2015-07-05 19 views
6

Ho provato ad ottenere la proiezione orizzontale usando la funzione countNonZero() come sotto.countNonZero function dà un errore di asserzione in 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); 
} 

Ma si è verificato un errore nella riga della funzione chiamata countonZero(). L'errore è il seguente.

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 

Qualcuno può indicare l'errore?

+4

binaryImage è una copia di src che è un'immagine a colori a 3 canali. prova cvtColor (src, binaryImage, CV_BGR2GRAY); – Micka

+2

c'è un altro errore: passare orizzontale.at (0, i) a horizontal.at (0, i) poiché è stato creato un tipo di dati a 8 bit. – Micka

+0

Ho apportato le modifiche e gli errori sono stati risolti. Grazie per quello. Ma ora vedo che il valore restituito dalla funzione countNonZero (roi) è sempre zero. Ho anche confermato che binaryImage non è un'immagine completamente nera. (ha pixel in bianco e nero ovunque) –

risposta

11

Asserzione src.channels() == 1 significa che l'immagine dovrebbe avere 1 canale, vale a dire che deve essere grigio, non colorato. Stai chiamando countNonZero su roi, che è una sottoimmagine di binaryImage, che è un clone di src, che è originariamente colorato.

Suppongo che volessi scrivere cvtColor(binaryImage, binaryImage, CV_BGR2GRAY);. In questo caso ha senso. Tuttavia, non ti vedo più usando lo src, quindi forse non hai bisogno di questa immagine intermedia. Nel caso in cui lo fai, non chiamare "binario", poiché "binario" in computer vision solitamente significa immagine in bianco e nero, solo due colori. La tua immagine è "grigia", poiché ha tutte le sfumature del bianco e nero.

Per quanto riguarda l'attività originale, Miki ha ragione, è necessario utilizzare cv::reduce per questo. Ti ha già dato un esempio su come usarlo.

+0

Grazie per la risposta. Diverso da quanto sopra le cose che ho dovuto cambiare, Mat roi = binaryImage (Rect (0, 0, 1, binaryImage.rows)); come questo, Mat roi = binaryImage (Rect (i, 0, 1, binaryImage.rows)); Stavo solo iterando la stessa colonna. –

+0

@SamithaChathuranga Hai ragione, certo. – Mikhail

0

BTW, è possibile calcolare la proiezione orizzontale utilizzando reduce fornendo come argomento CV_REDUCE_SUM.

Un esempio minimo:

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 

È possibile utilizzare questo con le vostre immagini come questa:

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

Puoi per favore elaborare la tua risposta? Cosa è ridotto? È una funzione?Se sì, come usarlo per lo scopo? –

+0

Siamo spiacenti. Ancora questo non ha alcun senso. Almeno tu non hai nemmeno usato l'immagine in bianco e nero per ottenere la sua proiezione orizzontale. –

+0

@SamithaChathuranga Ho aggiornato la mia risposta, spero che abbia più senso per te. – Miki