示例工程见:
http://files.cnblogs.com/laviewpbt/%e5%9b%be%e5%83%8f%e6%a8%a1%e7%b3%8a%e8%81%9a%e7%b1%bb.rar
一年前我写过模糊聚类算法(FCM)和硬聚类算法(HCM)的VB6.0实现及其应用 一文,之后,有不少同仁向我询问如何将这个算法应用在彩色图像的分割上,鉴于图像数据的特殊性,这里简单的谈谈在图像中聚类算法的需要注意一些细节。
C均值聚类算法较其他的聚类算法的主要优点是可以对大数据量进行计算(我也写过基于模糊等价关系的模糊聚类分析 ,这个方法只能分析很小的数据量),并且理论上已经证明该算法是收敛的。因此,对于图像的分割,特别是多于2类的彩色图像分割(2类的分割即二值化的过程,已经有着很多的方法,参见几种经典的二值化方法及其vb.net实现 ,但是这些方法很难扩展的多类分割中),有着广泛的应用。
我们知道,彩色图像的数据可以看成一M*N*3的数组,但是一方面三维数组的处理速度要低于一维或二维数组,另外从FCM通用性上讲,一般要分割的对象为样本组,而一个样本可以看成是n维空间中的一个点,因此,用二维数组来描述要分割的对象不仅意义明显而且有利于计算速度的提高。在MATLAB以及前面我写的那个FCM函数中第一维是样本,第二维是样本的具体数据,但是,图像数据在内存中的排列方式是BGRABRGABGRA.......(32位的),这样,通过API函数直接读取的数据一般为一(1 to 4,1 to M*N)数组,因此,要把前面写的那个FCM函数应用于图像分割,首先要改变下函数内部分循环的次序,这是其一。
彩色图像的数据量非常之大,要使得FCM或HCM函数具有实用价值,就必须把握好函数的每一个细节。下面我就在实际中我遇到的几个问题向大家描述下。
1、初始中心的选取
初始中心的选取其否合理直接影响着计算的速度和结果。不合理的初始点,可能导致结果收敛至一个不希望的极小点。这里提供几个选取初始中心点的方法以供参考。
2. 样本空间的选取
3. 距离的定义方式
不同的定义方式体现了不同的分割思想,以下是常用的集中距离定义方式。
详见:http://www.ownsoft.com/blog/blogview.asp?logID=48
4. 优化技巧
For i = -255 To 255
TempArray(i) = Abs(i)
Next
这样比直接在代码里用abs函数效率要高很多,即使用下述代码
Dist = TempArray(Data(1, i) - OldCenter(j, 1)) + TempArray(Data(2, i) - OldCenter(j, 2)) + TempArray(Data(3, i) - OldCenter(j, 3))
代替语句:
Dist = Abs(Data(1, i) - OldCenter(j, 1)) + Abs(Data(2, i) - OldCenter(j, 2)) + Abs(Data(3, i) - OldCenter(j, 3))
一个误区 :我曾在计算欧式距离的时候也定义了一个256个元素的数组记录n^2,然后用数组代替n*n计算,结果发现这样会导致计算速度的下降,所以在VB中这种简单的加减乘除还是很快的,只有在用像abs,Exp等函数时,如果方便在事前计算好查找表才会加快速度。
下面以部分分割效果来说明上述问题:
可以看出,采用随机中心,特别是对于FCM算法,要经过很长时间才能收敛。
对美女分类, 采用从缩略图获得中心、样本来源于RGB像素值。HCM用时0.25s,FCM用时1s。
其他条件不变,样本来源选择不重复的RGB像素值,HCM用时增加为437ms,FCM用时降低为657ms,这是因为针对这幅图像,HCM算法中分析不重复颜色值所需要的时间增量比循环时所节省时间要多,而FCM算法由于其循环的复杂度要高很多,当减小循环量时节省的时间特别明显。
一般情况下,一副彩色图像中不重复的颜色值和总的像素个数的比例可以达到1:5,当这个比值越明显的时候,采用不重复的RGB像素值时则速度提升越明显,特别是对于FCM算法,时间可以降为原来的1/3左右。