k均值(kmeans)聚类是一种最为简单的聚类方法,直接根据数据点之间的距离(欧氏距离,几何距离等等)来划分数据是属于哪一类的,当所有数据点所属的类别不在变化的时候,聚类也就完成了。详细原理可索引下面一个博客:
关于kmeans再谈几点认识:
关于opencv下的kmean算法,函数为cv2.kmeans()
函数的格式为:kmeans(data, K, bestLabels, criteria, attempts, flags)
(1)data: 分类数据,最好是np.float32的数据,每个特征放一列。之所以是np.float32原因是这种数据类型运算速度快,同样的数据下如果是uint型数据将会慢死你。
(2) K: 分类数,opencv2的kmeans分类是需要已知分类数的。
(3) bestLabels:预设的分类标签:没有的话 None
(4) criteria:迭代停止的模式选择,这是一个含有三个元素的元组型数。格式为(type,max_iter,epsilon)
其中,type又有两种选择:
—–cv2.TERM_CRITERIA_EPS :精确度(误差)满足epsilon停止。
—- cv2.TERM_CRITERIA_MAX_ITER:迭代次数超过max_iter停止。
—-cv2.TERM_CRITERIA_EPS+cv2.TERM_CRITERIA_MAX_ITER,两者合体,任意一个满足结束。
(5)attempts:重复试验kmeans算法次数,将会返回最好的一次结果
(6)flags:初始类中心选择,两种方法
cv2.KMEANS_PP_CENTERS ; cv2.KMEANS_RANDOM_CENTERS
下面使用这个函数对灰度图像进行分类。首先需要明白的一点是输入数据变换到一维。因为我们是对整个图像进行聚类,所以他们的灰度值都属于一个特征(维度)内的,而图像属于二维的,所以不能直接当data输入进去,需要将图像转化为一个长条或者长链的一维数据。我们说data结束数据,每一个特征放一列,灰度图像聚类的灰度值就是一个特征。若果说是彩色图像聚类,那么这个时候需要分别把RGB三个通道转化为一维才行。最后把分类结果以图像的形式显示出来的时候,需要把长条或者长链的标签再变回来才行。详细代码如下:
import cv2
import numpy as np
import matplotlib.pyplot as plt
img = cv2.imread(‘woman.jpg‘,0)#image read be ‘gray‘
plt.subplot(121),plt.imshow(img,‘gray‘),plt.title(‘original‘)
plt.xticks([]),plt.yticks([])
#change img(2D) to 1D
img1 = img.reshape((img.shape[0]*img.shape[1],1))
img1 = np.float32(img1)
#define criteria = (type,max_iter,epsilon)
criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER,10,1.0)
#set flags: hou to choose the initial center
#---cv2.KMEANS_PP_CENTERS ; cv2.KMEANS_RANDOM_CENTERS
flags = cv2.KMEANS_RANDOM_CENTERS
# apply kmenas
compactness,labels,centers = cv2.kmeans(img1,4,None,criteria,10,flags)
img2 = labels.reshape((img.shape[0],img.shape[1]))
plt.subplot(122),plt.imshow(img2,‘gray‘),plt.title(‘kmeans‘)
plt.xticks([]),plt.yticks([])
这就是设置分成4类的结果。
版权声明:本文为博主原创文章,未经博主允许不得转载。
Python下opencv使用笔记(十二)(k均值算法之图像分割)
原文地址:http://blog.csdn.net/on2way/article/details/47038861