Ask Your Question

Revision history [back]

click to hide/show revision 1
initial version

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;    
int n = 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++) {
    Mat mask(labels==i);
    result.setTo(centers.at<Vec3f>(i), mask); // set cluster color
}

image description image description

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;    
int n = 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(centers.at<Vec3f>(i), result.setTo(color, mask); // set cluster color
}

image description image description

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