dimanche 28 février 2021

How does cv::calcHist(params) work under the hood?

I am trying to create a custom function to calculate histogram of individual channels of an image in C++ . I know cv::calcHist(params) does this already and i am trying to compare the correctness of my custom function by comparing the output of cv::calcHist(param). And i see i am getting a different output then the one i get using the cv::calcHist(params)

Below is my function:

int generateHistograms(const cv::Mat& img, int* blueChnl, int* redChnl , int* greenChnl)
{
    MatConstIterator_<Vec3b> it, end;
    for( it = img.begin<Vec3b>(), end = img.end<Vec3b>(); it != end; ++it)
    {
      (*(blueChnl+(*it)[0]))++;
      (*(redChnl+(*it)[0]))++;
      (*(greenChnl+(*it)[0]))++;
    }

}

I ran this function on the image given at the cv::calcHist(param) tutorial page.I also ran the cv::calcHist(param) given in the tutorial. Below is a snippet:

vector<Mat> bgr_planes;
split( src, bgr_planes );
int histSize = 256;
float range[] = { 0, 256 }; //the upper boundary is exclusive
const float* histRange = { range };
bool uniform = true, accumulate = false;
Mat b_hist, g_hist, r_hist;
calcHist( &bgr_planes[0], 1, 0, Mat(), b_hist, 1, &histSize, &histRange, uniform, accumulate );
calcHist( &bgr_planes[1], 1, 0, Mat(), g_hist, 1, &histSize, &histRange, uniform, accumulate );
calcHist( &bgr_planes[2], 1, 0, Mat(), r_hist, 1, &histSize, &histRange, uniform, accumulate );

and got the following histogram outputs from cv::caclHist() and my function respectively. On inspection of the frequency of individual pixels, i see that the frequency for a pixel value was 0 at a lot of places in b_hist but not in blueChnl and almost everywhere the values were different. Also the frequency for the pixel values calculated using my function was as large as 1500 but b_hist has had all the frequency <256.

What am i doing wrong here ?

Un normalized image using cv::calcHist()

enter image description here

Aucun commentaire:

Enregistrer un commentaire