OpenCV K-means 聚类
-
参考1
https://www.cnblogs.com/jerrylead/archive/2011/04/06/2006910.html -
原图
-
调用OpenCV K-means 聚类的结果图
-
note 从效果来看, 参考1 中提到的坐标在这里应该是像素值, 实际是更新像素值动态的将原图中像素分为两类
-
效果
-
Python 代码
import cv2
import numpy as np
import matplotlib.pyplot as plt
if __name__ == "__main__":
img = cv2.imread('test.png')
img = cv2.resize(img, dsize=(100, 100))
#图图像的每个通道分别进行K-means
data = img.reshape((-1, 3))
data = np.float32(data)
#标识无监督学习的终止条件( 3,10,1)
criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 10, 1.0)
#开始时候随机选两点进行作为质心
flags = cv2.KMEANS_RANDOM_CENTERS
# 迭代10次,
# compactness是参考1中提到的J的值即畸变,
# labels2是每个数据的分类 要么0 要么1 ,labels2.flatten().shape= (1000,)
# centers2 即质心,标识两个类的中心值,shape= (2,3)
compactness, labels2, centers2 = cv2.kmeans(data, 2, None, criteria, 10, flags)
# 2 类 图像转换回 uint8 二维类型
centers2 = np.uint8(centers2)
res2 = centers2[labels2.flatten()]
#dst2 即结果
dst2 = res2.reshape(img.shape)
plt.subplot(1,2,1)
plt.imshow(img)
plt.subplot(1,2,2)
plt.imshow(dst2)
plt.show()
### >>> centers2
###array([[231, 220, 202],
### [109, 98, 109]], dtype=uint8)
###>>> labels2.flatten().shape
###(10000,)
- 代码中用到的原图 test.png ,直接另存为即可