8

I am trying to run kmeans on a 3 channel color image, but every time I try to run the function it seems to crash with the following error:

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 included the code below with some comments to help specify what is being passed in. Any help is greatly appreciated.

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

1 Answer 1

11

The error says all: Assertion failed (data.dims <= 2 && type == CV_32F && K > 0)

These are very simple rules to understand, the function will work only if:

  • mImage.depth() is CV_32F

  • if mImage.dims is <= 2

  • and if K > 0. In this case, you define K as 6.

From what you stated on the question, it seems that:

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

is loading the image as IPL_DEPTH_8U by default and not IPL_DEPTH_32F. This means that mImage is also IPL_DEPTH_8U, which is why your code is not working.

Sign up to request clarification or add additional context in comments.

5 Comments

So does this mean that I have to load it in as a grayscale image?
No, it doesn't. iplImage->depth and iplImage->nChannels are two different things. You need to convert iplImage to it's IPL_DEPTH_32F equivalent. That's all. Check this answer on how to do that: stackoverflow.com/questions/6349493/…
I just tried the convert function and it crashes on me. "IplImage* ipl32Image = cvCreateImage(cvGetSize(iplImage), IPL_DEPTH_32F, 1); cvConvert(iplImage, ipl32Image);" with the error "OpenCV Error: Assertion failed (src.size == dst.size && src.channels() == dst.ch annels()) in unknown function, file ..\..\..\OpenCV-2.3.0\modules\core\src\convert.cpp, line 1177". It seems that I'll have to either split up the channels or I'll have to load in a grayscale image
It's crashing because you assume that the number of channels of iplImage is 1. Fix it to cvCreateImage(cvGetSize(iplImage), IPL_DEPTH_32F, iplImage->nChannels);
Beautiful! I misinterpreted the "mImage.dims" thinking that it only wanted that to be a 1 or a 2. Thank you so very much. :D

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.