StuckInPhDNoMore
StuckInPhDNoMore

Reputation: 2679

Drawing the histogram using line function

So I have been continuing my opencv learning and am struggling with the histogram function. I clearly understand the calchist function and my code works till there, its drawing that I do not understand.

I realize that I will be using the line function to make a line between two points, but the point coordinates given really confuse me.

I am following the online tutorial for it found here: http://docs.opencv.org/doc/tutorials/imgproc/histograms/histogram_calculation/histogram_calculation.html and I am also following the OpenCV cookbook version 2.

The line calculation according to the online tutorial is at step 7, as:

 for( int i = 1; i < histSize; i++ )
  {
      line( histImage, Point( bin_w*(i-1), hist_h - cvRound(b_hist.at<float>(i-1)) ) ,
                       Point( bin_w*(i), hist_h - cvRound(b_hist.at<float>(i)) ),
                       Scalar( 255, 0, 0), 2, 8, 0  );
      line( histImage, Point( bin_w*(i-1), hist_h - cvRound(g_hist.at<float>(i-1)) ) ,
                       Point( bin_w*(i), hist_h - cvRound(g_hist.at<float>(i)) ),
                       Scalar( 0, 255, 0), 2, 8, 0  );
      line( histImage, Point( bin_w*(i-1), hist_h - cvRound(r_hist.at<float>(i-1)) ) ,
                       Point( bin_w*(i), hist_h - cvRound(r_hist.at<float>(i)) ),
                       Scalar( 0, 0, 255), 2, 8, 0  );
  }

I honestly had trouble understanding that, and also the values for hist_h and hist_w, as to why 512 and 400 were chosen?

So I consulted my book for this and found the same problem tackled as:

// Compute histogram first
cv::MatND hist= getHistogram(image);
// Get min and max bin values
double maxVal=0;
double minVal=0;
cv::minMaxLoc(hist, &minVal, &maxVal, 0, 0);
// Image on which to display histogram
cv::Mat histImg(histSize[0], histSize[0], 
CV_8U,cv::Scalar(255));
// set highest point at 90% of nbins
int hpt = static_cast<int>(0.9*histSize[0]);
// Draw a vertical line for each bin 
for( int h = 0; h < histSize[0]; h++ ) {
float binVal = hist.at<float>(h);
int intensity = static_cast<int>(binVal*hpt/maxVal);
// This function draws a line between 2 points 
cv::line(histImg,cv::Point(h,histSize[0]),
cv::Point(h,histSize[0]-intensity),
cv::Scalar::all(0));
}
return histImg;
}

here the coordinate of the second point cv::Point(h,histSize[0]-intensity) is what I dont understand. As in why minus intensity from it?

This might be a really stupid question but Im sorry I just do not understand the coordinates given here.. ive googled enough examples and have not found any help in clearing this up.

So what Im asking here is can anyone please explain to me the coordinate system given in either of the methods. I would really really appreciate it.

Thank you

P.S. I would also like to note here that histsize = 256

Upvotes: 1

Views: 1281

Answers (1)

ypnos
ypnos

Reputation: 52357

Talking about the second code example.

In OpenCV, the coordinate system starts at the top-left. So entry 0,0 of the matrix is at the top-left, 0,(cols-1) at the top-right, (rows-1),0 at the bottom-left and (rows-1),(cols-1) at the bottom-right.

Humans expect a histogram to start from the bottom of the image. To achieve that you negate the coordinates and start at (rows-1) instead of 0. In your example, rows == histsize[0].

Your code has a bug:

The coordinate …,histsize[0] is not valid! The matrix rows run from 0 to histsize[0] - 1!

Upvotes: 1

Related Questions