Post by Creator » Wed May 04, 2011, 22:14
I suggest to split the code in few parts to make the task easier. Moreover, we can add the look-up tables for optimisation:
1. Variables Declaration and InitializationCode: Select all
void Normalization()
{
register int x, y;
register int i, j;
int mu, sigma; // Gaussian parameters unsigned int lut[256]; // Look-Up Table (LUT)
unsigned int nC[256], n; // Histogram of "this" image, number of pixels in image
double pC[256], cC[256]; // Image intencity value occurance probability, Cumalative Distribution Function of pC
double pN[256], cN[256]; // Normal intencity value occurance probability, Cumalative Distribution Function of pN
memset(nC, 0, 256*sizeof(unsigned int));
n = this->cols * this->rows;
mu = 256 / 2; sigma = mu / 3;
2. Calculating the Histogram:Code: Select all
std::vector<Mat> vChannels(this->channels());
split(*this, vChannels);
for (x = 0; x < this->cols; x++)
for (y = 0; y < this->rows; y++) {
int val = 0;
for (i = 0; i < this->channels(); i++) val += vChannels[i].at<unsigned char>(y, x);
val /= this->channels(); // Graff px style
nC[val]++;
}
3. Calculating the Probabilities:Code: Select all
for (i=0; i < 256; i++) {
pC[i] = static_cast<double>(nC[i]) / n;
// Calculating cumulative distribution
cC[i] = (i==0) ? pC[i] : cC[i-1] + pC[i];
}
// Creating the form of the normal histogram, and corresponding CDF
for(i = 0; i < 256; i++) {
pN[i] = exp(-pow((double) i - mu, 2) / (2*sigma*sigma)) / sqrt(2*Pi*sigma*sigma);
// Calculating cumulative distribution
cN[i] = (i==0) ? pN[i] : cN[i-1] + pN[i];
}
4.Creating look-up table (LUT):Code: Select all
for (i = 0; i < 256; i++) {
double Min = abs(cN[0] - cC[i]);
int MinJ = 0;
for (j = 1; j < 256; j++)
if (Min > abs(cN[j] - cC[i])) {
Min = abs(cN[j] - cC[i]);
MinJ = j;
}
lut[i] = MinJ;
}
5. Resulting Image Transforming:Code: Select all
for (x = 0; x < this->cols; x++)
for (y = 0; y < this->rows; y++)
for (i = 0; i < this->channels(); i++) {
unsigned char val = vChannels[i].at<unsigned char>(y, x);
vChannels[i].at<unsigned char>(y, x) = static_cast<unsigned char>(lut[val]);
}
merge(vChannels, *this);
vChannels.clear();
}
I suggest to split the code in few parts to make the task easier. Moreover, we can add the look-up tables for optimisation:
[b]1. Variables Declaration and Initialization[/b][code]
void Normalization()
{
register int x, y;
register int i, j;
int mu, sigma; // Gaussian parameters unsigned int lut[256]; // Look-Up Table (LUT)
unsigned int nC[256], n; // Histogram of "this" image, number of pixels in image
double pC[256], cC[256]; // Image intencity value occurance probability, Cumalative Distribution Function of pC
double pN[256], cN[256]; // Normal intencity value occurance probability, Cumalative Distribution Function of pN
memset(nC, 0, 256*sizeof(unsigned int));
n = this->cols * this->rows;
mu = 256 / 2; sigma = mu / 3;
[/code]
[b]2. Calculating the Histogram:[/b][code]
std::vector<Mat> vChannels(this->channels());
split(*this, vChannels);
for (x = 0; x < this->cols; x++)
for (y = 0; y < this->rows; y++) {
int val = 0;
for (i = 0; i < this->channels(); i++) val += vChannels[i].at<unsigned char>(y, x);
val /= this->channels(); // Graff px style
nC[val]++;
}
[/code]
[b]3. Calculating the Probabilities:[/b][code]
for (i=0; i < 256; i++) {
pC[i] = static_cast<double>(nC[i]) / n;
// Calculating cumulative distribution
cC[i] = (i==0) ? pC[i] : cC[i-1] + pC[i];
}
// Creating the form of the normal histogram, and corresponding CDF
for(i = 0; i < 256; i++) {
pN[i] = exp(-pow((double) i - mu, 2) / (2*sigma*sigma)) / sqrt(2*Pi*sigma*sigma);
// Calculating cumulative distribution
cN[i] = (i==0) ? pN[i] : cN[i-1] + pN[i];
}
[/code]
[b]4.Creating look-up table (LUT):[/b][code]
for (i = 0; i < 256; i++) {
double Min = abs(cN[0] - cC[i]);
int MinJ = 0;
for (j = 1; j < 256; j++)
if (Min > abs(cN[j] - cC[i])) {
Min = abs(cN[j] - cC[i]);
MinJ = j;
}
lut[i] = MinJ;
}
[/code]
[b]5. Resulting Image Transforming:[/b][code]
for (x = 0; x < this->cols; x++)
for (y = 0; y < this->rows; y++)
for (i = 0; i < this->channels(); i++) {
unsigned char val = vChannels[i].at<unsigned char>(y, x);
vChannels[i].at<unsigned char>(y, x) = static_cast<unsigned char>(lut[val]);
}
merge(vChannels, *this);
vChannels.clear();
}
[/code]