Функция countNonZero выдает ошибку утверждения в openCV

Я попытался получить горизонтальную проекцию, используя функцию countNonZero (), как показано ниже.

Mat src = imread(INPUT_FILE, CV_LOAD_IMAGE_COLOR);
Mat binaryImage = src.clone();
cvtColor(src, src, CV_BGR2GRAY);

Mat horizontal = Mat::zeros(1,binaryImage.cols, CV_8UC1);

for (int i = 0; i<binaryImage.cols; i++)
{
Mat roi = binaryImage(Rect(0, 0, 1, binaryImage.rows));

horizontal.at<int>(0,i) = countNonZero(roi);
cout << "Col no:" << i << " >>" << horizontal.at<int>(0, i);
}

Но в строке вызова функции countonZero () произошла ошибка. Ошибка заключается в следующем.

    OpenCV Error: Assertion failed (src.channels() == 1 && func != 0) in cv::countNo
nZero, file C:\builds\2_4_PackSlave-win32-vc12-shared\opencv\modules\core\src\st
at.cpp, line 549

Может кто-нибудь указать на ошибку?

6

Решение

Утверждение src.channels() == 1 означает, что изображение должно иметь 1 канал, т.е. оно должно быть серым, а не цветным. Ты звонишь countNonZero на roi, который является прообразом binaryImage, который является клоном src, который изначально окрашен.

Я полагаю, вы хотели написать cvtColor(binaryImage, binaryImage, CV_BGR2GRAY);, В этом случае это имеет смысл. Тем не менее, я не вижу, что вы используете src опять в любом месте, так что, возможно, вам не нужно это промежуточное изображение. В этом случае не называйте «двоичный», так как «двоичный» в компьютерном зрении обычно означает черно-белое изображение, только два цвета. Ваше изображение «серое», поскольку оно имеет все оттенки черного и белого.

Что касается вашего первоначального задания, Мики прав, вы должны использовать cv::reduce для этого. Он уже дал вам пример того, как его использовать.

14

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

Кстати, вы можете вычислить горизонтальную проекцию, используя reduce в качестве аргумента CV_REDUCE_SUM,

Минимальный пример:

Mat1b mat(4, 4, uchar(0));
mat(0,0) = uchar(1);
mat(0,1) = uchar(1);
mat(1,1) = uchar(1);

// mat is:
//
// 1100
// 0100
// 0000
// 0000

// Horizontal projection, result would be a column matrix
Mat1i reducedHor;
cv::reduce(mat, reducedHor, 1, CV_REDUCE_SUM);

// reducedHor is:
//
// 2
// 1
// 0
// 0

// Vertical projection, result would be a row matrix
Mat1i reducedVer;
cv::reduce(mat, reducedVer, 0, CV_REDUCE_SUM);

// reducedVer is:
//
// 1200// Summary
//
// 1100 > 2
// 0100 > 1
// 0000 > 0
// 0000 > 0
//
// vvvv
// 1200

Вы можете использовать это с вашими изображениями, как это:

// RGB image
Mat3b img = imread("path_to_image");

// Gray image, contains values in [0,255]
Mat1b gray;
cvtColor(img, gray, CV_BGR2GRAY);

// Binary image, contains only 0,1 values
// The sum of pixel values will equal the count of non-zero pixels
Mat1b binary;
threshold(gray, binary, 1, 1, THRESH_BINARY);

// Horizontal projection
Mat1i reducedHor;
cv::reduce(binary, reducedHor, 1, CV_REDUCE_SUM);

// Vertical projection
Mat1i reducedVer;
cv::reduce(binary, reducedVer, 0, CV_REDUCE_SUM);
0

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