Ask Your Question
1

Block Overlapped Histogram Equalization

asked 2013-08-03 11:52:56 -0600

william gravatar image

updated 2013-08-03 23:06:24 -0600

I want to do a block overlapped histogram equalization with a 3x3 kernel with fast algorithm. For example, given a 9x9 image (with rows from 0 to 8 ; and columns from 0 to 8). The location for each pixel will be given as: (rows, columns) i.e (height, width). First the pixel at location (1,1) will be computed using a 3x3 kernel to obtain the first kernel histogram. Then move to the second pixel at location (1,2), here I would like to delete pixel at location (0,0), (1,0), (2,0) and add pixel at location (0,3), (1,3), (2,3) to the previous kernel histogram while maintaining pixels at locations (0,1), (1,1) (2,1) and (0,2) (1,2) (2,2). The window will slides from left to right until the second last column at (1,7). In the OutputImage, I can only compute the kernel histogram with column=1 (i.e x==cr_w/2) while other kernel histograms cannot be computed. Is there something wrong at “histogram[image.at<uchar>(y+k,x-r-1)]--;” and “histogram[image.at<uchar>(y+k,x+r)]++;” in the code I wrote below? Please advise.

After finish sliding the first row at (1,7), I wand to continue with the second row at location (2,7) by deleting pixels at first row and adding pixels at fourth row. Then I would like to slide from right to left. How do I need to modify my code so that it can run till the last pixel at (7,7)?

image description

image description

Code:

    int nl = image.rows; // image height
int nc = image.cols; // image width
unsigned int TransferFunction[256];
cv::Mat OutputImage(nc, nl, CV_8U,cv::Scalar(255));

int cr_w;
int cr_h;
cout<<"\nPlease enter contextual region width = ";
cin>> cr_w;
cout<<"\nPlease enter contextual region height = ";
cin>> cr_h;

   for (int y=cr_h/2; y<nl-cr_h/2; y++)
{
    for (int x=cr_w/2; x<nc-cr_w/2; x++) 
    {
        // update histogram;
        for(int i=0; i<256; i++)
            histogram[i] = 0;

        int top = y-cr_h/2;
        int bottom = y+cr_h/2;

        int left = x-cr_w/2;
        int right = x+cr_w/2;

        int r = cr_h/2; //window radius

                if (x == cr_w/2)
        {
        for (int j=top; j<=bottom; j++)
            for (int i=left; i<=right; i++)
            {
                histogram[image.at<uchar>(j,i)]++;  
            }
        }

        else 
        {
                for(int k=-cr_h/2; k<=ch_w/2; k++)
                {
                histogram[image.at<uchar>(y+k,x-r-1)]--;
                histogram[image.at<uchar>(y+k,x+r)]++;
                }
        }

  HE(histogram, 0, 255, TransferFunction);    //histogram equalization function

  OutputImage.at<uchar>(y,x) = TransferFunction[int(image.at<uchar>(y,x))];

    }
}
edit retag flag offensive close merge delete

1 answer

Sort by » oldest newest most voted
0

answered 2013-08-03 19:28:25 -0600

I'm not sure of what you want to do, but if you want to compute an histogram per line (or group of lines), I suggest using the ROI and calcHist function:

cv::Mat img = imread( "myimage", 0 ); // Read in grayscale
int rows = img.rows;
int cols = img.cols;
const int step = 3; // Size of your window (3x3,...)
for( int r = 1 ; r < rows ; ++r )
{
    cv::Mat roi = img(cv::Rect(r,0,step,cols));
    cv::calcHist( &img, 1, channels, cv::Mat(), hist, 1, histSize, ranges );
    // Do what you whant with your histogram (equilization, save, ...)
}

I haven't specify all the parameters of calcHist, read the doc for all information you may needed (and the sample below the function is very useful!).

edit flag offensive delete link more

Comments

I had just insert a picture above for reference. Initially I will compute the local histogram equalization of the first 3 x 3 kernel (center and indicated by 1 in the picture). Then I will move from left to right to the second pixel and compute the second local histogram equalization (center and indicated by 2 in the picture). To do a fast algorithm, I just want to delete the first column and add the fourth column to the previous histogram as indicated by ( - ) and ( + ) in the above picture. At the 8 th column, after finish computing local histogram equalization on the first row, I want to move to the second row and 8th column, then sliding from right to left.

william gravatar imagewilliam ( 2013-08-03 22:13:37 -0600 )edit

However the code i wrote has some errors, the Output Image only compute local histogram equalization at the second column (pixels below 1). The border pixels has white intensity and the other pixels are all black as shown above in Output Image. Why my code cannot run "histogram[image.at<uchar>(y+k,x-r-1)]--;" and "histogram[image.at<uchar>(y+k,x+r)]++;"? Please advise. Thank you.

william gravatar imagewilliam ( 2013-08-03 22:59:29 -0600 )edit

Question Tools

Stats

Asked: 2013-08-03 11:52:56 -0600

Seen: 840 times

Last updated: Aug 03 '13