最近,做图像分割,了解到了SLIC,即简单线性迭代聚类。其实是将K-means的思想应用到了超像素的生成中。
http://ivrl.epfl.ch/supplementary_material/RK_SLICSuperpixels/index.html
介绍SLIC算法的论文,以及源码。
算法流程
首先,根据一定的步长,均匀散布种子点;为了不让种子点散落在分割的边界,所以求解其在3×3邻域内的最小梯度,然后重置种子点;同时,将每个像素点标记为-1,距离为无穷大;
之后,采用的是K-means的思想。对于每一个中,在2S×2S的区域内进行搜索,计算该点到该区域内每个像素点的距离,如果距离小于下一个种子点到它的距离,则更新该类的距离值和该点的标记值;
之后,不断循环迭代,直到误差很小,或者不再改变,则退出循环,由于会产生一些孤立的超像素,所以,文中还有后处理的部分,增强超像素的连接性。
由于本人的分割算法还在尝试的阶段,如果使用C++进行编程,则调试起来比较麻烦,所以,我将其C++代码,改写成python,而且使用了openCV,这样使用起来更为方便,快捷。
代码中显示算法流程的部分:
def DoSuperpixelSegmentation_ForGivenSuperpixelSize(self):
self.STEP = int(float(self.superpixelsize)**(0.5) + 0.5)
if(1):
self.DoRGBtoLABConversion()
else:
for i in range(self.sz):
self.m_lvec[0][i] = self.ubuff[0][i] >> 16 & 0xff
self.m_avec[0][i] = self.ubuff[0][i] >> 8 & 0xff
self.m_bvec[0][i] = self.ubuff[0][i] & 0xff
perturbseeds = True
if(perturbseeds):
edgemag = self.DetectLabEdges()
self.GetLABXYSeeds_ForGivenStepSize(perturbseeds, edgemag)
self.PerformSuperpixelSLIC(edgemag)
self.numlabels = self.kseedsl.shape[1]
self.EnforceLabelConnectivity() ## 后处理,连接增强
for i in range(self.sz):
self.klabel[0][i] = self.nlabel[0][i] ## 将旧的标号替换
完整代码,可在:
http://download.csdn.net/my
下载
运行结果: