2012-06-29 42 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++; 
         } 

然後你還進一步具有索引錯誤的道路設置數據時。