标题 | SLIC superpixel算法 |
做者 | YangZheng |
联系方式 | 263693992 |
SLIC算法是simple linear iterative cluster的简称,该算法用来生成超像素(superpixel)。html
算法大体思想是这样的,将图像从RGB颜色空间转换到CIE-Lab颜色空间,对应每一个像素的(L,a,b)颜色值和(x,y)坐标组成一个5维向量V[l, a, b, x, y],两个像素的类似性便可由它们的向量距离来度量,距离越大,类似性越小。 git
算法首先生成K个种子点,而后在每一个种子点的周围空间里搜索距离该种子点最近的若干像素,将他们归为与该种子点一类,直到全部像素点都归类完毕。而后计算这K个超像素里全部像素点的平均向量值,从新获得K个聚类中心,而后再以这K个中心去搜索其周围与其最为类似的若干像素,全部像素都归类完后从新获得K个超像素,更新聚类中心,再次迭代,如此反复直到收敛。怎么样,是否是感受很像K-means聚类算法。 github
该算法接受一个参数K,用于指定生成的超像素数目。设原图有N个像素,则分割后每块超像素大体有N/K个像素,每块超像素的边长大体为S=[N/K]^0.5,开始咱们每隔S个像素取一个聚类中心,而后以这个聚类中心的周围2S*2S为其搜索空间,与其最为类似的若干点即在此空间中搜寻。这里有一个问题,为了不所选的聚类中心是边缘和噪声这样的不合理点,算法作了改进, 在3*3的窗口中将聚类中心移动到梯度最小的区域,梯度定义为: 算法
这样就能够避免上面所说的状况。 spa
最后可能出现一些小的区域d被标记为归属某一块超像素但却与这块超像素没有链接,这就须要把这块小区域d从新归类为与这块小区域d链接的最大的超像素中去,以保证每块超像素的完整。 .net
初始化聚类中心,由于算法给定了距离,因此算法的初始中心为所划分区域的中心,即根据所给定的数量,划定所属类别的初始地区,以下图红框所示: 3d
如今咱们要将N为9的9*9的图像划分红为k为4的4个大小接近的超像素,作法就是首先以步距为 调试
的距离划分超像素,而后将中心位置的结点为超像素的中心结点。设置中心像素的时候论文还进行了进一步的处理,即在中心结点的3*3领域内选取梯度最小的点做为初始超像素的中心结点,也就是下图中分别取黄色区域中梯度最小的点做为中心结点,好处是能够避免将超像素定位在边缘上,而且减小用噪声像素接种超像素的机会。不过官网上给出的matlab代码和下面要分析的南开大学给出的源码并无进行这一步操做。我的以为进行这步操做效果会获得改善,不过改善效果有限,有没有这一步影响不大,一个像素的间距对像素颜色的影响有限。 htm
其中m表示空间和像素颜色的相对重要性的度量。当m大时,空间邻近性更重要,而且所获得的超像素更紧凑(即它们具备更低的面积与周长比)。当m小时,所获得的超像素更紧密地粘附到图像边界,可是具备较小的规则尺寸和形状。当使用CIELAB色彩空间时,m能够在[1,40]的范围内。 blog
第二个比较新颖的地方是计算距离的时候做者与传统的采用Kmeans进行分割的算法不一样,并非对整个空间的全部像素进行计算,而是限定了区域,区域大小为2S,即寻找时以初始聚类中心为寻找中心,肯定一个2S*2S的矩形,以下图所示:
图1:减小超像素搜索区域。SLIC的复杂性在图像O(N)中的像素数目中是线性的,而常规的k均值算法是O(kNI),其中I是迭代次数。这在分配步骤中提供了每一个聚类中心的搜索空间。(a)在常规k均值算法中,从每一个聚类中心到图像中的每一个像素计算距离。(b)SLIC仅计算从每一个聚类中心到2S×2S区域内的像素的距离。注意,指望的超像素大小仅为S×S,由较小的正方形表示。这种方法不只减小了距离计算,并且使得SLIC的复杂性与超像素的数量无关。
好处是显而易见的,限制搜索区域的大小显着地减小了距离计算的数量,这样能够极大的加快速度,能够将算法控制为线性复杂度。
接着即是对kMeans算法进行迭代,直到算法收敛或迭代次数大于某一个值,根据论文大部分图像在迭代次数为10之内,具体迭代思路以下:
采用连通份量算法进行进一步的处理,这一步是我一开始不太明白的地方,不太懂什么是孤立的结点。直到我调试代码才明白,即迭代完成后有可能产生以下图所示的形状,图中的黄色方框所框出的结点也就是所谓的孤立点,为了使分割效果更好,咱们一般不但愿存在这种结点,因而能够采用连通份量进行下一步地修正。
图中的绿框为类别2的搜索范围,因此有可能产生图中黄色框中的孤立结点
做者采用的连通份量的概念来解决这个问题,简单说来就是,根据4邻域连通或8邻域连通(代码采用的是4邻域的链接方式)的连通算法,则图中的黄色方框皆为一个联通份量,判断这个联通份量的面积,若是面积太小,则将联通份量的分类分给最近的类别,即左上角的两个2分为1,左下角分为3,右下角分为4(具体的实现能够参看代码)。
https://github.com/csjy309450/SLIC-Superpixels
参考资料: