2015-07-05 16 views
6

Próbowałem uzyskać rzut poziomy za pomocą funkcji countNonZero(), jak poniżej.Funkcja countNonZero daje błąd potwierdzenia w 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); 
} 

Ale wystąpił błąd w linii wywołującej funkcję countonZero(). Błąd jest następujący.

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 

Czy ktoś może wskazać błąd?

+4

binaryImage to kopia src, która jest 3-kanałowym kolorowym obrazem. spróbuj cvtColor (src, binaryImage, CV_BGR2GRAY); – Micka

+2

jest inny błąd: przełącz poziomo.at (0, i) na horizontal.at (0, i), ponieważ utworzono 8-bitowy typ danych. – Micka

+0

Zrobiłem zmiany i błędy zostały rozwiązane. Dziękuję za to. Ale teraz widzę, że wartość zwracana przez funkcję countNonZero (roi) zawsze wynosi zero. Potwierdziłem również, że binaryImage nie jest całkowicie czarnym obrazem. (ma wszędzie białe i czarne piksele) –

Odpowiedz

11

Assertion src.channels() == 1 oznacza, że ​​obraz powinien mieć 1 kanał, to znaczy, że musi być szara, nie kolorowy. Wywołujesz countNonZero na roi, który jest subimage of binaryImage, który jest klonem src, który jest pierwotnie kolorowy.

Przypuszczam, że chcesz napisać cvtColor(binaryImage, binaryImage, CV_BGR2GRAY);. W tym przypadku ma to sens. Jednak nie widzę, żebyś ponownie używał src gdziekolwiek, więc może nie potrzebujesz tego pośredniego obrazu. Jeśli tak, nie wywołuj "binary", ponieważ "binarny" w wizji komputerowej oznacza zwykle obraz czarno-biały, tylko dwa kolory. Twój obraz jest "szary", ponieważ ma wszystkie odcienie czerni i bieli.

Jeśli chodzi o twoje pierwotne zadanie, Miki ma rację, powinieneś użyć do tego cv::reduce. Dał ci już przykład, jak z niego korzystać.

+0

Dzięki za odpowiedź. Inne niż powyższe rzeczy musiałem zmienić, Mat roi = binaryImage (Rect (0, 0, 1, binaryImage.rows)); jak to, Mat roi = binaryImage (Rect (i, 0, 1, binaryImage.rows)); Właśnie powtarzałem tę samą kolumnę. –

+0

@SamithaChathuranga Masz rację, jasne. – Mikhail

0

Przy pomocy BTW można obliczyć rzut poziomy za pomocą reduce podając jako argument CV_REDUCE_SUM.

Minimalny przykład:

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 

Możesz użyć tego z obrazów takich jak to:

// 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

Czy możesz dopracować swoją odpowiedź? Co to jest zmniejszenie? Czy to jest funkcja?Jeśli tak, jak z niego korzystać w tym celu? –

+0

Przepraszamy. Nadal nie ma to żadnego sensu. Przynajmniej nie użyłeś nawet czarno-białego obrazu, aby uzyskać jego poziomy rzut. –

+0

@SamithaChathuranga Uaktualniłem swoją odpowiedź, mam nadzieję, że będzie to dla ciebie bardziej sensowne. – Miki