SLIC算法是simple linear iterative cluster的简称,该算法用来生成超像素(superpixel)。
目录
基本思想
实现SLIC算法
1.图像的预处理
2.初始化聚类中心
3.优化初始聚类中心
4. 计算像素点与聚类中心的距离
5.像素点分类
6.重新计算聚类中心
7.迭代4~6的过程
8.聚类优化
将图像从RGB颜色空间转换到CIE-Lab颜色空间,对应每个像素的(L,a,b)颜色值和(x,y)坐标组成一个5维向量V [L, a, b, x, y ],两个像素的相似性即可由它们的向量距离来度量,距离越大,相似性越小。
将图像从 RGB 颜色空间转换到 CIE-Lab 颜色空间,Lab颜色空间更符合人类对颜色的视觉感知。这个空间里的距离能反映人感觉到的颜色差别,相关计算更为准确。
Lab 颜色空间同样具有三个通道,分别是 l,a,b,其中 l 代表亮度,数值范围为 [0, 100],a 表示从绿色到红色的分量,数值范围为[-128, 127],b表示蓝色到黄色的分量,数值范围为[-128, 127]。
RGB 和 LAB 间没有直接的转换公式,需要将 RGB 转为 XYZ 颜色空间再转为 LAB,具体代码见下一篇中完整代码。
根据参数确定超像素的数目,也就是需要划分为多少个区域。假设图片有 N 个像素点,预计分割成 K 个超像素,每个超像素大小为 N/K。相邻中心距离为 S = Sqr(N/K),得到 k 个聚类的坐标。
注:推导相邻中心的距离:
N个像素点可以看作整个图形的面积为N,要分成K个小正方形。每个小正方形的面积就为 N/K。那么小正方形的边长为 Sqr(N/K)。所以相邻中心的距离也为 Sqr(N/k)。
在聚类中心的 3 * 3 邻域内选择梯度最小的像素点作为新的聚类中心。
把图像看成二维离散函数,梯度也就是这个函数的求导,当相邻像素值有变化就会存在梯度,而在边缘上的像素点的梯度最大。将聚类中心挪到梯度最小的地方可以避免其落到边缘轮廓上,影响聚类效果。
计算一个点 (i, j) 的像素梯度公式为:
在聚类中心距离为 S 的区域内,2S * 2S 的领域内计算像素点与每个聚类中心的距离。
这里的距离使用的是欧式距离,总距离 D
由 dc
颜色距离与 ds
空间距离两部分组成。公式如下:
如果直接将l
,a
,b
,x
,y
拼接成一个矢量计算距离,当超像素的大小变化时,x
,y
的值可以取到非常大 ,比如如果一张图1000*1000
,空间距离可以达到1000*Sqr(2)
,而颜色距离最大仅10*Sqr(2)
,导致最终计算得到的距离值中,空间距离ds
权重占比过大。
所以需要进行归一化,除以最大值即超像素点的初始宽度S
,将值映射到[0,1]。
而颜色空间距离也会给到一个固定的值m
来调节颜色距离与空间距离的影响权重,m
取值范围为[1,40]
。
距离公式即变成了
当m
越大,颜色空间除以m
后的值越小,即空间距离的权重越大,生成的像素会更为形状规则,当m
越小,颜色距离权重更大,超像素会在边缘更为紧凑,而形状大小较为不规则。
标记每个像素点的类别为距离其最小的聚类中心的类别。
计算属于同一个聚类的所有像素点的平均向量值,重新得到聚类中心 。
4~6
的过程直到旧聚类中心与新聚类中心的距离小于一定阈值或者达到一定迭代次数,一般来说,当迭代次数到达10
,算法能够达到收敛。
迭代到最后,可能会出现与聚类中心不属于同一连通域的孤立像素点,可以使用到连通算法将其分配到最近的聚类标签。