2017-07-11 190 views
2

我有一個字母和不同顏色的形狀的圖像。我需要對它們執行kmeans聚類,然後提供兩個不同的圖像,一個只重新生成形狀,另一個只重新生成Letter信號。 這是一個示例原始圖像和我需要實現的。 Original Image顏色分割使用Kmeans,Opencv蟒蛇

Shape color regenerated 並且類似地,另一個只用白色R.

我已經成功地進行k均值聚類算法,如何訪問標籤和集羣IDX再生預期的效果?有人可以請示例代碼說明。這是代碼。提前致謝。

import numpy as np 
import cv2 

img = cv2.imread("/home/manohar/Outputs/Targets/m-0.PNG",1) 
cv2.imshow("original",img) 

Z = img.reshape((-1,3)) 

# convert to np.float32 
Z = np.float32(Z) 

# Here we are applying k-means clustering so that the pixels around a colour are consistent and gave same BGR/HSV values 


# define criteria, number of clusters(K) and apply kmeans() 
criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 10, 1.0) 
# We are going to cluster with k = 2, because the image will have just two colours ,a white background and the colour of the patch 
K = 3 
attempts=10 
ret,label,center=cv2.kmeans(Z,K,None,criteria,attempts,cv2.KMEANS_PP_CENTERS) 

# Now convert back into uint8 
#now we have to access the labels to regenerate the clustered image 
center = np.uint8(center) 
res = center[label.flatten()] 
res2 = res.reshape((img.shape)) 
#res2 is the result of the frame which has undergone k-means clustering 


cv2.imshow("res2",res2) 
cv2.waitKey() 
cv2.destroyAllWindows() 

回答

1

好了,如果你想變成黑色是被你需要先了解哪些標籤對應於「白」類K-Means歸類爲「白色」的所有像素。您可以通過尋找實現這一目標,以什麼指標在center(其中包含導致ķ中心)做白色(255,255,255)屬於,像這樣:

white_index = 0 
for b,g,r in center: 
    #check if it is white 
    if b == g == r == 255: 
     #then this is the white category 
     break 
    white_index = white_index + 1 

請注意,由於k-means是unsupervized方法您的類別可能不一定是正好是白色(可能是類似於250,249,254)。所以在搜索索引時應該考慮這一點,那就是你應該尋找顏色更接近白色。你可以通過應用color distance公式來比較你的顏色。

在我的經驗

但是,我認爲,center已經以某種方式排序產生中心(更大的像素值往往先出現),我已經注意到了中心接近白色具有較低的指數(因此白色可能索引0)。但最好檢查一下。

現在您知道哪個索引對應於白色,您可以看到哪些像素被歸類爲label變量中的像素。對於這個有幾種方法,你可以做到這一點,肯定比其他一些更有效的,一種方法可能是:

#Copy image to modify it 
img_copy = img[:] 
#Reshape label to match the original image 
new_label = label.reshape(img.shape) 
#iterate over new_label, and if the category is white 
#paint pixel corresponding to row,col black 
row = 0 
for i in new_label: 
    column = 0 
    for category in i: 
     if category == white_index: 
      #paint that pixel black 
      img_copy[row,column] = [0, 0, 0] 
     column = column + 1 
    row = row + 1 

#now show edited image 
cv2.imshow("Object Removed",img_copy) 
cv2.waitKey() 
cv2.destroyAllWindows() 

編輯:上面的代碼獲得與檢測到的顏色去掉(塗黑)的圖像。爲了獲得它的補充,這是一個只有被檢測物體可見的圖像,你可以做幾件事情。一種方法可能是獲得img的副本,並塗黑是顏色(無category == white_index)的不像素,如:

#Obtain another copy of image to modify it 
extract = img[:] 
#Now do the opposite, iterate over new_label, and if the category is Not white 
#paint pixel corresponding to row,col black 
row = 0 
for i in new_label: 
    column = 0 
    for category in i: 
     if category != white_index: 
      #paint that pixel black 
      extract[row,column] = [0, 0, 0] 
     column = column + 1 
    row = row + 1 

#show or do whatever you want... 

獲得所提取的對象的另一種更復雜的方式僅是爲了獲得(通過閾值處理和使用cv2.findContours()),然後應用cv2.boundingRect(),以便您可以使用該對象(通過將img與給定的矩形對齊)獲取較小的剪輯。您可以查看該鏈接詳細解釋的地方。

+0

謝謝您的回覆先生,但這不是我想達到的。當我傳遞任何帶有形狀和字母的圖像時,我只想重新生成兩個新圖像,一個只有形狀,另一個只有字母顏色。我該如何做這個先生?在C++中,我們使用cluster_idx,我如何在python中執行此操作? – Manohar

+0

您的問題也被問及如何訪問中心和標籤。你能否澄清你的意思?如果我理解正確,你想要一個圖像與刪除檢測到的對象(就像在我的答案中已經解釋過的形狀變黑)*和*也只有提取的對象(字母)的圖像? – DarkCygnus

+0

根據您的意見編輯我的答案 – DarkCygnus