Многоканальное утверждение обратной проекции (j & lt; nimages)

Попытка сделать обратное проецирование гистограммы на трехканальном изображении приводит к следующей ошибке:

Ошибка OpenCV: утверждение не выполнено (j < nimages) в histPrepareImages, файл ../modules/imgproc/src/histogram.cpp, строка 148

Код, который не работает:

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

Запуск почти идентичного кода на одноканальном изображении работает. Согласно документации, многоканальные изображения также поддерживаются. Почему этот код не работает?

1

Решение

Краткий ответ: cv::calcBackProject() не поддерживает работу на месте, хотя это не упоминается в документации.

объяснение

Копание в источник OpenCV приводит к следующему фрагменту:

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...
}

Строка, которая вызывает проблему:

_backProject.create( images[0].size(), images[0].depth() );

который, если источник и назначение совпадают, перераспределяет данные входного изображения. images[0].depth() оценивает CV_8U, который численно эквивалентен спецификатору типа CV_8UC1, Таким образом, данные создаются как одноканальное изображение.

Это проблема, потому что histPrepareImages по-прежнему ожидает, что входное изображение имеет 3 канала, и утверждение выбрасывается.

Решение

К счастью, обходной путь прост. Выходной параметр должен отличаться от входного, например:

cv::Mat result;
cv::calcBackProject(&output, 1, channels, hist, result, ranges);
3

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]