问题
Attempting to do histogram back-projection on a three-channel image results in the following error:
OpenCV Error: Assertion failed (j < nimages) in histPrepareImages, file ../modules/imgproc/src/histogram.cpp, line 148
The code which fails:
cv::Mat _refImage; //contains reference image of type CV_8UC3
cv::Mat output; //contains image data of type CV_8UC3
int histSize[] = {16, 16, 16};
int channels[] = {0, 1, 2};
const float hRange[] = {0.f, 256.f};
const float* ranges[] = {hRange, hRange, hRange};
int nChannels = 3;
cv::Mat hist;
cv::calcHist(&_refImage, 1, channels, cv::noArray(), hist, nChannels, histSize, ranges);
cv::calcBackProject(&output, 1, channels, hist, output, ranges); //This line causes assertion failure
Running nearly identical code on a single-channeled image works. According to the documentation, multi-channel images are also supported. Why won't this code work?
回答1:
The short answer is that cv::calcBackProject()
does not support in-place operation, although this is not mentioned in the documentation.
Explanation
Digging into the OpenCV source yields the following snippet:
void calcBackProject( const Mat* images, int nimages, const int* channels,
InputArray _hist, OutputArray _backProject,
const float** ranges, double scale, bool uniform )
{
//Some code...
_backProject.create( images[0].size(), images[0].depth() );
Mat backProject = _backProject.getMat();
assert(backProject.type() == CV_8UC1);
histPrepareImages( images, nimages, channels, backProject, dims, hist.size, ranges,
uniform, ptrs, deltas, imsize, uniranges );
//More code...
}
The line which causes the problem is:
_backProject.create( images[0].size(), images[0].depth() );
which, if the source and destination are the same, reallocates the input image data. images[0].depth()
evaluates to CV_8U
, which is numerically equivalent to the type specifier CV_8UC1
. Thus, the data is created as a single-channel image.
This is a problem because histPrepareImages
still expects the input image to have 3 channels, and the assertion is thrown.
Solution
Fortunately, the workaround is simple. The output parameter must be different from the input, like so:
cv::Mat result;
cv::calcBackProject(&output, 1, channels, hist, result, ranges);
来源:https://stackoverflow.com/questions/16840968/multi-channel-back-projection-assertion-j-nimages