I am developping on Qt creator, with opencv.
I have to developp a program that does the histogram equalization of an image. My images are 16bits grayscale images so I cannot use the opencv function "equalizeHist" because it only works with 8bit grayscale images.
The code I wrote to do it is the following :
void equalizeHist_16U(Mat* img)
{
long hist[65535] = {0};
double ratio;
int i, j;
assert(img->channels() == 1);
assert(img->type() == CV_16U);
ratio = 65535.0 / (img->cols*img->rows);
//Cumulative histogram calculation
compute_hist_16U(img, hist, true);
for(i=0 ; i<img->cols ; i++)
{
for(j=0 ; j<img->rows ; j++)
{
img->at<unsigned short>(j,i) = ratio*hist[img->at<unsigned short>(j,i)];
}
}
}
long compute_hist_16U (Mat* img, long* hist, bool cumul)
{
unsigned short i, j, k;
long* b;
long max = 0;
//is the image 16bits grayscale ?
assert(img->channels() == 1);
assert(CV_16U == img->type());
//histogram calculation
for(i=0 ; i<img->cols ; i++)
{
for(j=0 ; j<img->rows ; j++)
{
hist[img->at<unsigned short>(j,i)]++;
if(hist[img->at<unsigned short>(j,i)] > max)
max = hist[img->at<unsigned short>(j,i)];
}
}
//Cumulative histogram calculation (if cumul=true)
if(cumul)
{
for(b=hist ; b<hist+65535 ; b++)
{
*(b+1) += *b;
}
}
return (cumul ? hist[65535] : max);
}
It does what I expected, now I want to do the histogram equialization of my image but only on a specified part of the image. I added x1,x2,y1,y2 parameters to my function and changed the bounds of my "for" like this (the lines of code i changed have arrows):
---->void equalizeHist_16U(Mat* img, int x1, int x2, int y1, int y2)
{
long hist[65535] = {0};
double ratio;
int i, j;
assert(img->channels() == 1);
assert(img->type() == CV_16U);
ratio = 65535.0 / (img->cols*img->rows);
//Cumulative histogram calculation
compute_hist_16U(img, hist, true);
---->for(i=x1 ; i<=x2 ; i++)
{
---->for(j=y1 ; j<=y2 ; j++)
{
img->at<unsigned short>(j,i) = ratio*hist[img->at<unsigned short>(j,i)];
}
}
}
---->long compute_hist_16U (Mat* img, long* hist, bool cumul, int x1, int x2, int y1, int y2)
{
unsigned short i, j, k;
long* b;
long max = 0;
//is the image 16bits grayscale ?
assert(img->channels() == 1);
assert(CV_16U == img->type());
//histogram calculation
---->for(i=x1 ; i<=x2 ; i++)
{
---->for(j=y1 ; j<=y2 ; j++)
{
hist[img->at<unsigned short>(j,i)]++;
if(hist[img->at<unsigned short>(j,i)] > max)
max = hist[img->at<unsigned short>(j,i)];
}
}
//Cumulative histogram calculation (if cumul=true)
if(cumul)
{
for(b=hist ; b<hist+65535 ; b++)
{
*(b+1) += *b;
}
}
return (cumul ? hist[65535] : max);
}
But it does not work as expected, my image is not equalized, I do not have extrem values (clear white and dark black) on my image. If I try
equalizeHist_16U(&img, 0, 50, 0, 50)
The image i get is very very bright And if I try
equalizeHist(&img, 300, 319, 220, 239)
The image I get is very very dark
I think I have made a mistake in the loops bounds but I can't find where ! Maybe you have an idea ?
Thank you in advance