Ask Your Question
0

assertion failed error in kmeans

asked 2017-01-14 00:12:16 -0500

shreya gravatar image

updated 2017-01-14 02:06:57 -0500

berak gravatar image

i am trying to write a code to posterize an image using kmeans in open 3.0 (c++) the code is as follows :

int main()
{
  Mat src = imread("1.jpg", 1 );
  Mat samples(src.rows * src.cols, 3, CV_32F);
  //Mat samples(3,src.rows*src.cols,CV_32F);
  for( int y = 0; y < src.rows; y++ )
    for( int x = 0; x < src.cols; x++ )
      for( int z = 0; z < 3; z++)
        samples.at<float>(y + x*src.rows, z) = src.at<Vec3b>(y,x)[z];


  int clusterCount = 3;
  Mat labels;
  int attempts = 5;
  Mat centers;
  //kmeans(samples, clusterCount, labels, TermCriteria(CV_TERMCRIT_ITER|CV_TERMCRIT_EPS, 10000, 0.0001), attempts, KMEANS_PP_CENTERS, centers );

kmeans(samples,clusterCount, labels,TermCriteria( TermCriteria::EPS+TermCriteria::COUNT, 10, 1.0),3, KMEANS_RANDOM_CENTERS, centers);
  Mat new_image(src.rows * src.cols, 3, CV_32S);
  for( int y = 0; y < src.rows; y++ )
    for( int x = 0; x < src.cols; x++ )
    { 
      int cluster_idx = labels.at<int>(y + x*src.rows,0);
      new_image.at<Vec3b>(y,x)[0] = centers.at<int>(cluster_idx, 0);
      new_image.at<Vec3b>(y,x)[1] = centers.at<int>(cluster_idx, 1);
      new_image.at<Vec3b>(y,x)[2] = centers.at<int>(cluster_idx, 2);
    }
  imshow( "clustered image", new_image );
  waitKey();
}

i am getting an assertion failed error : OpenCV Error: Assertion failed (N >= K) in cv::kmeans, file C:\buildslave64\win64_amdocl\master_PackSlave-win64-vc11-shared\opencv\modules\core\src\kmeans.cpp, line 231 how should i resolve this ?

edit retag flag offensive close merge delete

2 answers

Sort by ยป oldest newest most voted
1

answered 2017-01-14 03:13:23 -0500

berak gravatar image

updated 2017-01-14 04:06:52 -0500

let's start with this: Assertion failed (N >= K) yea, you need more samples, than clusters with kmeans, so your image is obviously empty, it was never read, and you never checked.

then, all those stupid and horribly wrong for loops, as @LBerger already pointed out, almost everything in your 2nd part is wrong ! go back to the board, and write a 100 times: I MUST NOT USE PER PIXEL LOOPS !, really...

please rather try like this:

Mat img = imread("1.jpg");
if (img.empty()) {  // only FOOLS never check !
    return -1;
}
img.convertTo(img, CV_32F);  // to float
Mat samples = img.reshape(1,img.total()); // a vertical strip, 3 floats wide.

Mat labels, centers;    
kmeans(samples,3, labels,TermCriteria( TermCriteria::EPS+TermCriteria::COUNT, 10, 1.0),3, KMEANS_RANDOM_CENTERS, centers);

centers = centers.reshape(3,0); //K rows of Vec3f
labels = labels.reshape(1,img.rows);  // same shape as original img

Mat result(img.size(), CV_8UC3);
for (int i=0; i<centers.rows; i++) {
    Scalar color = centers.at<Vec3f>(i);
    Mat mask(labels==i);
    result.setTo(color, mask); // set cluster color
}

image description image description

edit flag offensive delete link more

Comments

2

thanks a lot sir and i just started using open cv 2 months back so i am new to the library and how it works the only way i learn is through internet i didnt write this code i found this code online only and was trying to understand and run it to learn how kmeans can be used to posterize an image

shreya gravatar imageshreya ( 2017-01-14 05:27:31 -0500 )edit
1

answered 2017-01-14 02:33:18 -0500

LBerger gravatar image

updated 2017-01-14 02:34:28 -0500

these lines are wrong

  new_image.at<Vec3b>(y,x)[0] = centers.at<int>(cluster_idx, 0);
  new_image.at<Vec3b>(y,x)[1] = centers.at<int>(cluster_idx, 1);
  new_image.at<Vec3b>(y,x)[2] = centers.at<int>(cluster_idx, 2);

size image is

Mat new_image(src.rows * src.cols, 3, CV_32S);

and loop limit are

  for( int y = 0; y < src.rows; y++ )
    for( int x = 0; x < src.cols; x++ )

read this post about kmeans

edit flag offensive delete link more

Comments

shreya gravatar imageshreya ( 2017-02-23 07:44:52 -0500 )edit
Login/Signup to Answer

Question Tools

1 follower

Stats

Asked: 2017-01-14 00:12:16 -0500

Seen: 1,292 times

Last updated: Jan 14 '17