Multi-Channel Back Projection Assertion (j < nimages)

泪湿孤枕 提交于 2020-01-03 03:15:27

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!