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
}
2 | No.2 Revision |
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
}
3 | No.3 Revision |
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
}