k均值聚类算法的基本原理是根据数据的密集程度寻找相对密集数据的质心,再根据质心完成数据分类。
1.图解k均值聚类算法
下面的代码在大小为240×320的图像中选择3组数据点,为了便于说明k均值聚类算法,在选择数据点时设置了坐标的随机取值范围。将所有点作为分类数据,调用cv2.kmeans()函数并应用k均值聚类算法进行分类;在图像中用不同颜色显示分类数据和质心。
import cv2
import numpy as np
from matplotlib import pyplot as plt
创建聚类数据,3种类别,每种类别20个点
data = np.vstack((np.random.randint(10,90,(20,2)),
np.random.randint(80,170, (20, 2)),
np.random.randint(160,250, (20, 2))))
data=data.astype(np.float32)
定义算法终止条件
criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 20, 1.0)
使用K均值聚类算法执行分类操作,K=3,返回结果中label保存标志,center保存质心
ret,label,center=cv2.kmeans(data,3,None,criteria,10,cv2.KMEANS_RANDOM_CENTERS)
根据运算结果返回的标志,将数据分为3组,便于绘制图像
data1 = data[label.ravel() == 0]
data2 = data[label.ravel() == 1]
data3 = data[label.ravel() == 2]
plt.scatter(data1[:,0], data1[:,1], c='r')#绘制第1类数据点,红色
plt.scatter(data2[:,0], data2[:,1], c='g')#绘制第2类数据点,绿色
plt.scatter(data3[:,0], data3[:,1], c='b')#绘制第3类数据点,蓝色
plt.scatter(center[:,0], center[:,1],100,['#CC3399'],'s')#绘制质心,颜色为#CC3399
plt.show() #显示结果
2.使用k均值聚类算法量化图像颜色
使用k均值聚类算法量化图像颜色,即将质心作为图像新的像素,从而减少图像中的颜色值。
import cv2
import numpy as np
img = cv2.imread('bee.jpg') #打开图像
cv2.imshow('Original',img) #显示原图
img2 = img.reshape((-1,3)).astype(np.float32) #转换为n*3的浮点类型数组
定义算法终止条件
criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 10, 1.0)
K = 4
ret,label,center=cv2.kmeans(img2,K,None,criteria,10,cv2.KMEANS_RANDOM_CENTERS)
center = np.uint8(center) #将质心转换为整型
img3 = center[label.ravel()] #转换为一维数组
img3 = img3.reshape((img.shape)) #恢复为原图像数组形状
cv2.imshow('K=4',img3)
cv2.waitKey(0)