OpenCV-Python OpenCV中的K-Means聚類

目標

  • 瞭解如何在OpenCV中使用cv.kmeans()函數進行數據聚類

理解參數

輸入參數

  1. sample:它應該是np.float32數據類型,並且每個功能都應該放在單個列中。
  2. nclusters(K):結束條件所需的簇數
  3. criteria:這是迭代終止條件。滿足此條件後,算法迭代將停止。實際上,它應該是3個參數的元組。它們是(type,max_iter,epsilon): a. 終止條件的類型。它具有3個標誌,如下所示: cv.TERM_CRITERIA_EPS-如果達到指定的精度epsilon,則停止算法迭代。 cv.TERM_CRITERIA_MAX_ITER-在指定的迭代次數max_iter之後停止算法。 cv.TERM_CRITERIA_EPS + cv.TERM_CRITERIA_MAX_ITER-當滿足上述任何條件時,停止迭代。 b. max_iter-一個整數,指定最大迭代次數。 c. epsilon-要求的精度
  4. attempts:該標誌用於指定使用不同的初始標籤執行算法的次數。該算法返回產生最佳緊密度的標籤。該緊湊性作為輸出返回。
  5. flags:此標誌用於指定初始中心的獲取方式。通常,為此使用兩個標誌:cv.KMEANS_PP_CENTERScv.KMEANS_RANDOM_CENTERS

輸出參數

  1. 緊湊度:它是每個點到其相應中心的平方距離的總和。
  2. 標籤:這是標籤數組(與上一篇文章中的“代碼”相同),其中每個元素標記為“0”,“ 1” .....
  3. 中心:這是群集中心的陣列。 現在,我們將通過三個示例瞭解如何應用K-Means算法。

1. 單特徵數據

考慮一下,你有一組僅具有一個特徵(即一維)的數據。例如,我們可以解決我們的T恤問題,你只用身高來決定T恤的尺寸。因此,我們首先創建數據並將其繪製在Matplotlib中

<code>import numpy as np
import cv2 as cv
from matplotlib import pyplot as plt
x = np.random.randint(25,100,25)
y = np.random.randint(175,255,25)

z = np.hstack((x,y))
z = z.reshape((50,1))
z = np.float32(z)
plt.hist(z,256,[0,256]),plt.show()/<code>

因此,我們有了“ z”,它是一個大小為50的數組,值的範圍是0到255。我將“z”重塑為列向量。 如果存在多個功能,它將更加有用。然後我製作了np.float32類型的數據。 我們得到以下圖像:

OpenCV-Python OpenCV中的K-Means聚類 | 五十八

現在我們應用KMeans函數。在此之前,我們需要指定標準。我的標準是,每當運行10次算法迭代或達到epsilon = 1.0的精度時,就停止算法並返回答案。

<code># 定義終止標準 = ( type, max_iter = 10 , epsilon = 1.0 )
criteria = (cv.TERM_CRITERIA_EPS + cv.TERM_CRITERIA_MAX_ITER, 10, 1.0)
# 設置標誌
flags = cv.KMEANS_RANDOM_CENTERS
# 應用K均值
compactness,labels,centers = cv.kmeans(z,2,None,criteria,10,flags)/<code>

這為我們提供了緊湊性,標籤和中心。在這種情況下,我得到的中心分別為60和207。標籤的大小將與測試數據的大小相同,其中每個數據的質心都將標記為“ 0”,“ 1”,“ 2”等。現在,我們根據標籤將數據分為不同的群集。

<code>A = z[labels==0]
B = z[labels==1]/<code>

現在我們以紅色繪製A,以藍色繪製B,以黃色繪製其質心。

<code># 現在繪製用紅色'A',用藍色繪製'B',用黃色繪製中心
plt.hist(A,256,[0,256],color = 'r')
plt.hist(B,256,[0,256],color = 'b')
plt.hist(centers,32,[0,256],color = 'y')
plt.show()/<code>

得到了以下結果:

OpenCV-Python OpenCV中的K-Means聚類 | 五十八

2. 多特徵數據

在前面的示例中,我們僅考慮了T恤問題的身高。在這裡,我們將同時考慮身高和體重,即兩個特徵。 請記住,在以前的情況下,我們將數據製作為單個列向量。每個特徵排列在一列中,而每一行對應於一個輸入測試樣本。 例如,在這種情況下,我們設置了一個大小為50x2的測試數據,即50人的身高和體重。第一列對應於全部50個人的身高,第二列對應於他們的體重。第一行包含兩個元素,其中第一個是第一人稱的身高,​​第二個是他的體重。類似地,剩餘的行對應於其他人的身高和體重。查看下面的圖片:

OpenCV-Python OpenCV中的K-Means聚類 | 五十八

現在,我直接轉到代碼:

<code>import numpy as np
import cv2 as cv
from matplotlib import pyplot as plt
X = np.random.randint(25,50,(25,2))
Y = np.random.randint(60,85,(25,2))
Z = np.vstack((X,Y))
# 將數據轉換未 np.float32
Z = np.float32(Z)
# 定義停止標準,應用K均值
criteria = (cv.TERM_CRITERIA_EPS + cv.TERM_CRITERIA_MAX_ITER, 10, 1.0)
ret,label,center=cv.kmeans(Z,2,None,criteria,10,cv.KMEANS_RANDOM_CENTERS)
# 現在分離數據, Note the flatten()
A = Z[label.ravel()==0]
B = Z[label.ravel()==1]
# 繪製數據
plt.scatter(A[:,0],A[:,1])
plt.scatter(B[:,0],B[:,1],c = 'r')
plt.scatter(center[:,0],center[:,1],s = 80,c = 'y', marker = 's')
plt.xlabel('Height'),plt.ylabel('Weight')
plt.show()/<code>

我們得到如下結果:

OpenCV-Python OpenCV中的K-Means聚類 | 五十八

3.顏色量化

顏色量化是減少圖像中顏色數量的過程。這樣做的原因之一是減少內存。有時,某些設備可能會受到限制,因此只能產生有限數量的顏色。同樣在那些情況下,執行顏色量化。在這裡,我們使用k均值聚類進行顏色量化。

這裡沒有新內容要解釋。有3個特徵,例如R,G,B。因此,我們需要將圖像重塑為Mx3大小的數組(M是圖像中的像素數)。在聚類之後,我們將質心值(也是R,G,B)應用於所有像素,以使生成的圖像具有指定數量的顏色。再一次,我們需要將其重塑為原始圖像的形狀。下面是代碼:

<code>import numpy as np
import cv2 as cv
img = cv.imread('home.jpg')
Z = img.reshape((-1,3))
# 將數據轉化為np.float32
Z = np.float32(Z)
# 定義終止標準 聚類數並應用k均值
criteria = (cv.TERM_CRITERIA_EPS + cv.TERM_CRITERIA_MAX_ITER, 10, 1.0)
K = 8
ret,label,center=cv.kmeans(Z,K,None,criteria,10,cv.KMEANS_RANDOM_CENTERS)
# 現在將數據轉化為uint8, 並繪製原圖像
center = np.uint8(center)
res = center[label.flatten()]
res2 = res.reshape((img.shape))
cv.imshow('res2',res2)
cv.waitKey(0)
cv.destroyAllWindows()/<code>

我們可以看的K=8的結果

OpenCV-Python OpenCV中的K-Means聚類 | 五十八


分享到:


相關文章: