2015-07-05 3 views
6

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

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 

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

+4

binaryImage - это копия src, которая представляет собой трехканальное цветное изображение. попробуйте cvtColor (src, binaryImage, CV_BGR2GRAY); – Micka

+2

есть еще одна ошибка: switch horizontal.at (0, i) to horizontal.at (0, i), так как вы создали 8-битный тип данных. – Micka

+0

Я сделал изменения и ошибки решены. Спасибо за это. Но теперь я вижу, что значение, возвращаемое функцией countNonZero (roi), всегда равно нулю. Я также подтвердил, что binaryImage не является полностью черным изображением. (он имеет как черные, так и белые пиксели везде) –

ответ

11

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

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

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

+0

Спасибо за ответ. Помимо вышеперечисленных вещей, мне пришлось изменить, Mat roi = binaryImage (Rect (0, 0, 1, binaryImage.rows)); как это, Mat roi = binaryImage (Rect (i, 0, 1, binaryImage.rows)); Я просто повторял одну и ту же колонку. –

+0

@SamithaChathuranga Вы правы, конечно. – Mikhail

0

BTW, вы можете вычислить горизонтальную проекцию, используя 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

Можете ли вы усовершенствовать свой ответ? Что сокращается? Это функция?Если да, то как использовать его для этой цели? –

+0

Извините. Тем не менее это не имеет никакого смысла. По крайней мере, вы даже не использовали черно-белое изображение, чтобы получить его горизонтальную проекцию. –

+0

@SamithaChathuranga Я обновил свой ответ, надеюсь, что это имеет больше смысла для вас. – Miki

Смежные вопросы