Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unhandled exception after reading histogram (created with calcHist)

I am trying to get histogram from my color (3-channel) image in OpenCV but every time I do the calcHist histogram like this :

//int histSize[3];
//float hranges[2];
//const float* ranges[3];
//int channels[3];

ColorHistogram::ColorHistogram() 
{
    // Prepare arguments for a color histogram
    histSize[0]= histSize[1]= histSize[2]= 256;
    hranges[0]= 0.0; // BRG range
    hranges[1]= 255.0;
    ranges[0]= hranges; // all channels have the same range
    ranges[1]= hranges;
    ranges[2]= hranges;
    channels[0]= 0; // the three channels
    channels[1]= 1;
    channels[2]= 2;
}

cv::MatND ColorHistogram::getHistogram(const cv::Mat &image)
{
    cv::MatND hist;
    // Compute histogram
    cv::calcHist(&image,
        1, // histogram of 1 image only
        channels, // the channel used
        cv::Mat(), // no mask is used
        hist, // the resulting histogram
        3, // it is a 3D histogram
        histSize, // number of bins
        ranges // pixel value range
        );
    return hist;
}

enter image description here

When I try to fed the result to for instance cv::minMaxLoc I get an unhandled exception.

cv::Mat ColorHistogram::getHistogramImage(const cv::Mat &image){
    // 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);
//....
}

EDIT

I don't know if this is important but I get this error in console:

OpenCV Error: Assertion failed (img.dims <= 2) in unknown function, file C:\slave\WinInstallerMegaPack\src\opencv\modules\core\src\stat.cpp, line 788

and my image's dims = 2

like image 786
Patryk Avatar asked Nov 05 '22 08:11

Patryk


1 Answers

You can't call minMaxLoc with a 3D histogram (i.e., hist.dims == 3 is true) unfortunately. Below is the code for minMaxLoc:

void cv::minMaxLoc( InputArray _img, double* minVal, double* maxVal,
                Point* minLoc, Point* maxLoc, InputArray mask )
{
    Mat img = _img.getMat();
    CV_Assert(img.dims <= 2); // <-- This is the line that is asserting for you...

    minMaxIdx(_img, minVal, maxVal, (int*)minLoc, (int*)maxLoc, mask);
    if( minLoc )
        std::swap(minLoc->x, minLoc->y);
    if( maxLoc )
        std::swap(maxLoc->x, maxLoc->y);
}

You'll have to search for the min and max values in your 3D histogram manually. You may be able to use the NAryMatIterator to help ease the search. There is an example of how to use this with the documentation. Also, you can find my related answer here.

like image 132
mevatron Avatar answered Nov 10 '22 06:11

mevatron