2011-08-10 11 views
7

próbuję uruchomić kmeans na 3 kanał koloru obrazu, ale za każdym razem staram się uruchomić funkcję Wydaje upaść z powodu następującego błędu:OpenCV biegania kmeans algorytm na obrazie

OpenCV Error: Assertion failed (data.dims <= 2 && type == CV_32F && K > 0) in unknown function, file ..\..\..\OpenCV-2.3.0\modules\core\src\matrix.cpp, line 2271 

I ve zawiera poniższy kod z kilkoma komentarzami, aby pomóc określić, co jest przekazywane. Każda pomoc jest bardzo doceniana.

// Load in an image 
// Depth: 8, Channels: 3 
IplImage* iplImage = cvLoadImage("C:/TestImages/rainbox_box.jpg"); 

// Create a matrix to the image 
cv::Mat mImage = cv::Mat(iplImage); 

// Create a single channel image to create our labels needed 
IplImage* iplLabels = cvCreateImage(cvGetSize(iplImage), iplImage->depth, 1); 

// Convert the image to grayscale 
cvCvtColor(iplImage, iplLabels, CV_RGB2GRAY); 

// Create the matrix for the labels 
cv::Mat mLabels = cv::Mat(iplLabels); 

// Create the labels 
int rows = mLabels.total(); 
int cols = 1; 
cv::Mat list(rows, cols, mLabels .type()); 
uchar* src; 
uchar* dest = list.ptr(0); 
for(int i=0; i<mLabels.size().height; i++) 
{ 
    src = mLabels.ptr(i); 
    memcpy(dest, src, mLabels.step); 
    dest += mLabels.step; 
} 
list.convertTo(list, CV_32F); 

// Run the algorithm 
cv::Mat labellist(list.size(), CV_8UC1); 
cv::Mat centers(6, 1, mImage.type()); 
cv::TermCriteria termcrit(CV_TERMCRIT_EPS+CV_TERMCRIT_ITER, 10, 1.0); 
kmeans(mImage, 6, labellist, termcrit, 3, cv::KMEANS_PP_CENTERS, centers); 

Odpowiedz

11

Błąd mówi wszystko: Assertion failed (data.dims <= 2 && type == CV_32F && K > 0)

Są to bardzo proste zasady, aby zrozumieć, funkcja będzie działać tylko wtedy, gdy:

  • mImage.depth() jest CV_32F

  • jeśli mImage.dims jest <= 2

  • i jeśli K > 0. W takim przypadku definiujesz K jako .

Z tego, co stwierdzono w tej kwestii, wydaje się, że:

IplImage* iplImage = cvLoadImage("C:/TestImages/rainbox_box.jpg");` 

się ładuje obraz jako IPL_DEPTH_8U domyślnie i nie IPL_DEPTH_32F. Oznacza to, że mImage jest również IPL_DEPTH_8U, dlatego Twój kod nie działa.

+0

Czy to oznacza, że ​​muszę go załadować jako obraz w skali szarości? – Seb

+0

Nie, nie ma. 'iplImage-> depth' oraz' iplImage-> nChannels' to dwie różne rzeczy. Musisz przekonwertować iplImage na jego odpowiednik IPL_DEPTH_32F. To wszystko. Sprawdź tę odpowiedź, jak to zrobić: http://stackoverflow.com/questions/6349493/opencv-iplimage-data-to-float – karlphillip

+0

Po prostu wypróbowałem funkcję konwertowania i zawiesiło się na mnie. "IplImage * ipl32Image = cvCreateImage (cvGetSize (iplImage), IPL_DEPTH_32F, 1); cvConvert (iplImage, ipl32Image);" z błędem "Błąd OpenCV: Asercja nie powiodła się (src.size == dst.size && src.channels() == dst.ch annels()) w nieznanej funkcji, plik .. \ .. \ .. \ OpenCV-2.3 .0 \ modules \ core \ src \ convert.cpp, wiersz 1177 ". Wygląda na to, że będę musiał albo podzielić kanały, albo będę musiał załadować obraz w skali szarości. – Seb

Powiązane problemy