I am trying to implement kmeans clustering on images in openCV (using C). Instead of the clustered image resulting in some color layers, the output is pretty weird. I have also tried to debug the code, but couldn’t understand where it may have gone wrong.
Here is the input and output images.

The right one is the output and the left one is the input image.
Here is the code:
image = cvLoadImage( "pic65.png", CV_LOAD_IMAGE_UNCHANGED);
sample = cvCreateMat( image->height*image->width, 5, CV_32FC1 );
clusters = cvCreateMat( image->height*image->width, 1, CV_32SC1 );
data = (uchar *)image->imageData;
for(i=0;i<image->height;i++)
{
for(j=0;j<image->width;j++)
{
cvSetReal2D( sample, k, 0, i);
cvSetReal2D( sample, k, 1, j);
b = data[i*image->widthStep + j*image->nChannels +0];
g = data[i*image->widthStep + j*image->nChannels +1];
r = data[i*image->widthStep + j*image->nChannels +2];
cvSetReal2D( sample, k, 2, b);
cvSetReal2D( sample, k, 3, g);
cvSetReal2D( sample, k, 4, r);
k++;
}
}
count = get_clusters();
cvKMeans2(sample,count,clusters,cvTermCriteria(CV_TERMCRIT_EPS+CV_TERMCRIT_ITER,100,0 ));
for (x = 0; x < image->height; x++)
{
for (y = 0; y < image->width; y++)
{
index = x * image->width + y;
cluster_index = cvGetReal2D(clusters,index,0);
data[x*image->widthStep + y*image->nChannels +0] = cl[cluster_index][0];
data[x*image->widthStep + y*image->nChannels +1] = cl[cluster_index][2];
data[x*image->widthStep + y*image->nChannels +2] = cl[cluster_index][2];
}
}
The get_clusters method returns the number of color clusters in the input image depending on a threshold value which is 30 in this case. If its required I can also provide you with the code of get_clusters, but I think its correct.
Can someone please point out where it has gone wrong. Any kind of help is appreciated.
Thanks in advance.
EDIT:My desired output is given below:

Judging on your “desired output” image, your usage of kmeans is wrong. The pixel coordinates should play no role in the clustering. You should only hand the color triplets to kmeans.
…
Then you also have an indexing bug further down the road when setting data.