K-means算法在图像处理中的应用

使用背景

从广义上说,聚类就是将数据集中在某些方面相似的数据成员放在一起。聚类的的目的也是把数据分类,但是事先是不知道如何去分的,完全是算法自己来判断各条 数据之间的相似性,相似的就放在一起。在图像处理中,可以使用K-means算法对图片进行压缩,使图片具有k个像素点值。

K-means聚类算法流程

  • 第一步,确定K值,即将数据集聚集成K个类簇或小组;
  • 第二步,从数据集中随机选择K个数据点作为质心(Centroid)或数据中心;
  • 第三步,分别计算每个点到每个质心之间的距离,并将每个点划分到离最近质心的小组;
  • 第四步,当每个质心都聚集了一些点后,重新定义算法选出新的质心。(对于每个簇,计 算其均值,即得到新的k个质心点);
  • 第五步,迭代执行第三步到第四步,直到迭代终止条件满足为止(分类结果不再变化)。

K-means()原型介绍

在OpenCV中,Kmeans()函数原型如下所示:

  • retval, bestLabels, centers = kmeans(data, K, bestLabels, criteria, attempts, flags[, centers]);
  • data表示聚类数据,最好是np.flloat32类型的N维点集;
  • K表示聚类类簇数;
  • bestLabels表示输出的整数数组,用于存储每个样本的聚类标签索引;
  • criteria表示算法终止条件,即最大迭代次数或所需精度。在某些迭代中,一旦每个簇中心的移动小于criteria.epsilon,算法就会停止;
  • attempts表示重复试验kmeans算法的次数,算法返回产生最佳紧凑性的标签;
  • flags表示初始中心的选择,两种方法是cv2.KMEANS_PP_CENTERS ;和cv2.KMEANS_RANDOM_CENTERS;
  • centers表示集群中心的输出矩阵,每个集群中心为一行数据。

算法实现

import cv2
import numpy as np
import matplotlib.pyplot as plt

img = cv2.imread(r'C:\Users\ZFG\PycharmProjects\Lenet_test\lenna.png', 0)
print (img.shape)
rows, cols = img.shape[:]
data = img.reshape((rows * cols, 1))
data = np.float32(data)
#定义中心
criteria = (cv2.TERM_CRITERIA_EPS +
            cv2.TERM_CRITERIA_MAX_ITER, 10, 1.0)
#设置标签
flags = cv2.KMEANS_RANDOM_CENTERS
#K-Means聚类 聚集成5类
compactness, labels, centers = cv2.kmeans(data, 5, None, criteria, 10, flags)
#生成最终图像
dst = labels.reshape((img.shape[0], img.shape[1]))
#用来正常显示中文标签
plt.rcParams['font.sans-serif']=['SimHei']
#显示图像
titles = [u'原始图像', u'聚类图像']
images = [img, dst]
for i in range(2):
   plt.subplot(1,2,i+1), plt.imshow(images[i], 'gray')
   plt.title(titles[i])
   plt.xticks([]),plt.yticks([])
plt.show()

我把lena的灰度图分成了具有五类像素点的值(即k=5),最后展示下效果吧。下图为lena灰度图使用k-menas聚类算法后结果的展示:

  • 哈哈吓人吧,自己调试的时候可以根据实际情况调整其k值的大小。最后总结下,虽然k-means算法的实现需要一些程序,但是在opencv中可以调用直接封装好的Kmeans()函数,可以说特别方便了。

猜你喜欢

转载自blog.csdn.net/weixin_50233398/article/details/120004129
今日推荐