2012-06-29 79 views
2

我想在openCV(使用C)中的图像上实现kmeans集群。而不是聚集的图像导致一些颜色层,输出是非常奇怪的。我也尝试调试代码,但无法理解它可能出错的地方。opencv kmeans集群错误的输出

这里是输入和输出图像。

enter image description here

右边一个是输出与左一个是输入图像。

下面是代码:

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]; 
} 
} 

的get_clusters方法返回输入图像中的,这取决于是30在这种情况下的阈值的颜色的簇的数目。如果它的要求我也可以为你提供get_clusters的代码,但我认为它是正确的。

有人可以指出哪里出了问题。任何形式的帮助表示赞赏。 在此先感谢。

编辑:我的期望输出如下:

enter image description here

+0

你想达到什么目的?输出看起来与您的代码保持一致:cluster(x,y,r,g,b)。具有相似颜色的地理邻居进入同一个群集。除非你没有定义cl。 – Antoine

+0

实际上,cl是我从get_clusters方法获得的集群的各种颜色。 – bluechill

+0

除此之外,我想以这样的方式聚集图像,使得没有不同颜色的阴影。这样我就可以获得与特定对象相对应的单独颜色图层。 我正在编辑问题,以便所有人都清楚所需的输出。 – bluechill

回答

1

看你的“期望的输出”的形象,你的k均值的用法是错误的。像素坐标在聚类中不起作用。你只能把颜色三元组交给kmeans。

sample = cvCreateMat(image->height*image->width, 3, CV_32FC1); 

...

    for(j=0;j<image->width;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, 0, b); 
         cvSetReal2D(sample, k, 1, g); 
         cvSetReal2D(sample, k, 2, r); 
         k++; 
         } 

然后你还进一步具有索引错误的道路设置数据时。