我是学院讲师贾志刚。值此学院“4.20IT充电节”(4月19~20日)之际,与大家分享我的《OpenCV中KMeans算法应用》体验。正文来了~~~一、KMeans算法介绍KMeans算法由MacQueen于1967年提出,是最简单、最常用的数据分类方法之一。作为一种常见的数据分析技术,它在机器学习、数据挖掘、模式识别、图像分析等领域都有应用。从分类的角度来看,KMeans属于硬分类,即需要手动指定分类个数,而MeanSift分类方法可以根据收敛情况自动确定分类个数。在学习方法上,KMeans是一种无监督学习方法,即在整个学习过程中不需要人为干预,自动完成对整个数据集的分类的学习方法。对于给定的数据集DS(DataSet)和输入的类别编号K,KMeans的整个工作原理可以描述如下:1.根据输入的类别编号K定义K个类别,并为每个类别选择一个中心点2.对于DS中的每个数据点,做如下操作:-计算它与K个中心点的距离-将数据点分配到K个中心点中距离最近的中心点所属的类别3.对于每个K个类别计算数据点的平均值,得到新的K个中心点4.第一步比较新的K个中心点和已有的K个中心点的差值——当两者的差值不变或更小时超过指定的阈值,结束分类——当两者相差或不满足条件时,将新计算出的中心点值作为K分类的新中心点,继续执行步骤2~4。直到满足条件退出。从数学的角度来看,KMeans就是找到K个类别,并最小化它们的中心点与每个类别中每个数据的差的平方和,而实现这个过程就是要经过上面的2~4个步骤不断迭代执行,直到收敛。公式表达如下:以上就是KMeans算法的基本思想。如果要实现或应用这个算法,有三点值得关注:1.初始K个类别中每个类别的中心点选择。大部分算法实现都支持随机选择和手动指定两种方式,OpenCV中的KMeans实现也支持这两种方式。2、多维数据支持。很多时候,我们要分类的特征对象的描述数据不是一个数据特征,而是一个特征向量来表示。在OpenCV中,多维数据的KMeans分类支持是通过Mat对象构建实现的。3.收敛条件——一般情况下,当达到指定的迭代次数或两个RSS值的差值小于给定的阈值时,分类过程结束,输出最终的分类结果。下图就是一个例子。黑点代表数据点,十字代表中心点的位置。当初始输入分类数K=2时,KMeans每一步执行结果:2.OpenCV中KMeans相关函数说明KMeans是OpenCVAPI函数的核心模块。各参数详细解释如下:-data表示输入数据集,可以是一维或多维数据,类型为Mat类型,例如:Matpoints(count,2,CV_32F)表示即数据集是二维的,浮点数数据集。-K表示类别数,最常见的是K=2,用于二分类。-bestLabels表示每个数据点经过计算后最终的分类索引,是一个INT类型的Mat对象。-criteria表示算法终止的条件。当达到最大循环次数或指定精度阈值时,算法停止继续分类迭代计算。-attempts表示为了获得最好的分类效果,算法需要不同的初始分类尝试-flags表示使用哪种初始中心点选择方式KMEANS_RANDOM_CENTERS表示随机选择中心点KM??EANS_PP_CENTERS选择KMEANS_USE_INITIAL_LABELS基于集中算法的第一个分类中心这些点使用输入的中心点-centers代表输出的每个分类的中心点数据。3.应用案例——使用KMeans实现图像分割KMeans在图像处理中的经典应用场景是根据用户输入的类别数量实现自动图像区域分割。本例基于OpenCV的KMeans函数实现图像自动分割。对于彩色图像,每个像素都有RGB的三个分量。整个图像可以看作是一个3维数据集。只需将这个3维数据集作为输入参数传递给KMeans函数即可。算法执行后,根据分类标记的索引设置不同的颜色即可。所以演示程序的实现步骤如下:1.将输入图像转换为数据集2.使用KMeans算法对数据进行分类3.根据每个数据点的分类索引,重新填充图像的颜色和显示分割后的图像。运行效果如下:完整代码实现如下:#include
