calcHist returns invalid Mat (n-dimensional histogram, n>=3)

asked 2014-01-20 13:31:39 -0600

Torsten gravatar image

updated 2014-01-20 14:04:25 -0600

Hi there,

I want to calculate a n-dimensional histogram of an image (sample code below n=3), but calcHist returns an invalid Mat resulting in an error in normalize:

Mat hist_tmp;
//Mat1b mask (is a parameter of the function and not equal to Mat())

const int K = 8;
const int nChannels = 3;
const int channels[nChannels] = {0, 1, 2};
const int histSize[nChannels] = {K, K, K};
const float range[2] = {0, 255};
const float* ranges[nChannels] = {range, range, range};
calcHist( &_img, 1, channels, mask, hist_tmp, nChannels, histSize, ranges, true, false);

cout << "type "<< _img.type() << "|" << hist_tmp.type() << "\n";
cout << "rows "<< _img.rows << "|" << hist_tmp.rows << "\n";
cout << "columns "<< _img.cols << "|" << hist_tmp.cols << "\n";
cout << "channels "<< _img.channels() << "|" << hist_tmp.channels() << "\n";

normalize(hist_tmp, hist_tmp, 0, 255, NORM_MINMAX);

I get this error message:

type 16|5

rows 480|-1

columns 640|-1

channels 3|1

OpenCV Error: Assertion failed (img.dims <= 2) in minMaxLoc, file /build/opencv/src/opencv-2.4.8/modules/core/src/stat.cpp, line 1136 terminate called after throwing an instance of 'cv::Exception' what():

/build/opencv/src/opencv-2.4.8/modules/core/src/stat.cpp:1136: error: (-215) img.dims <= 2 in function minMaxLoc

I know there are examples for generating a 3D-histogram (like here) but I can't see what I'm doing different/wrong!

Thanks! Torsten

edit retag flag offensive close merge delete

Comments

1

so, the 1st thing minMaxLoc is doing:

CV_Assert(_img.dims() <= 2);

voila, it can't handle 3 dim arrays.

minMaxLoc again is only called from normalize(), because you specified NORM_MINMAX.

the whole thing runs fine with NORM_INF, NORM_L1, NORM_L2.

berak gravatar imageberak ( 2014-01-20 14:03:03 -0600 )edit

ok, thanks - I will have a look at this - but rows/cols = -1 is a little bit strange?

Torsten gravatar imageTorsten ( 2014-01-20 14:06:40 -0600 )edit

yea, call it strange, maybe. for dim > 2 the sizes are in hist_tmp.size.p . (p[0]==p[1]==p[2] == 8)

berak gravatar imageberak ( 2014-01-20 14:11:39 -0600 )edit

how can an one channel image have dims > 2? (hist_temp has dims = 3)

Torsten gravatar imageTorsten ( 2014-01-20 14:23:42 -0600 )edit

yea, hist_temp.channels() returns 1. that's definitely misleading ( if not a bug )

berak gravatar imageberak ( 2014-01-20 14:31:55 -0600 )edit

I tried to convert hist_temp with split to a set of one channels images (which should have dims = 2), but as hist_temp.channels() is already one that didn't help. I can't even print hist_tmp because of dims = 3 (cout << hist_tmp). Any idea how I can debug this further?

Torsten gravatar imageTorsten ( 2014-01-20 14:38:25 -0600 )edit

oh dear, i got no idea now ;(

i guess, multi-dim support is only sparsely implemented in opencv. expect more probs like this further on.

berak gravatar imageberak ( 2014-01-20 14:43:32 -0600 )edit

ok, I know that it's an Mat containing only uchar blanks: uchar *p = hist_tmp.datastart; while(p < hist_tmp.dataend) { cout << "'" << *p << "'\n"; p += 8; }

I wonder why I am the only person having this problem - 3D histograms seem to work (for other people); btw I use OpenCV 2.4.8 ArchLinux x86_64

Torsten gravatar imageTorsten ( 2014-01-20 15:06:15 -0600 )edit

Any resolution on this, I am facing the same problem with 3.4.5

ramg8x gravatar imageramg8x ( 2019-02-20 08:09:09 -0600 )edit

this post is too old feel free to post a new question

LBerger gravatar imageLBerger ( 2019-02-20 08:19:15 -0600 )edit