1.主程序入口
- 下面的程序就是超像素生成的函数入口:
slic.DoSuperpixelSegmentation_ForGivenNumberOfSuperpixels(img, width, height, labels, numlabels, m_spcount, m_compactness);
这里有几个特别的参数需要说明:
- slic:SLIC slic; 是一个SLIC类
- labels:int* labels = new int[sz];一张标签图,和图像大小一致,用于标记每个像素的标签值;sz=width*height,即一张图像的像素总数。
- numlabels:int numlabels(0);是图像最终分成的类数,即最终生成的超像素个数,在这里被初始化为0。
- m_spcount: 是客户从界面输入的值,即初始化的种子个数,但是SLIC算法中不一定每个种子最终都能得一个超像素,由于某些因素可能被其他超像素合并。若种子数不符合规定,则通过(总像素值SZ)/(每个超像素默认大小200)获得种子数:if (m_spcount < 20 || m_spcount > sz/4) m_spcount = sz/200;
- m_compactness:if(m_compactness < 1.0 || m_compactness > 80.0) m_compactness = 20.0;这个值也是有用户设定的,是颜色特征和XY坐标特征之间的紧密度比例,20这个值效果往往不错。
- 该函数的定义:
void SLIC::DoSuperpixelSegmentation_ForGivenNumberOfSuperpixels(
unsigned int * ubuff,//img
const int width,
const int height,
int*& klabels,//labels
int& numlabels, //
const int & K, //初始化的种子数
m_spcount
const double & compactness) //
m_compactness空间参数转换的权重值
{
const int superpixelsize = 0.5+double(width*height)/ double(K);
DoSuperpixelSegmentation_ForGivenSuperpixelSize(ubuff,width,height,klabels,numlabels,superpixelsize,compactness);
}
- superpixelsize:超像素的大小,即每个超像素中包含的像素值
- DoSuperpixelSegmentation_ForGivenSuperpixelSize函数中完成了超像素生成的功能
- const int STEP = sqrt(double(superpixelsize))+0.5;这个变量很关键,是种子点的跨度。
在
DoSuperpixelSegmentation_ForGivenSuperpixelSize函数中主要包含以下函数:
- DoRGBtoLABConversion(ubuff, m_lvec, m_avec, m_bvec);
- GetLABXYSeeds_ForGivenStepSize(kseedsl, kseedsa, kseedsb, kseedsx, kseedsy, STEP, perturbseeds, edgemag);
- PerformSuperpixelSLIC(kseedsl, kseedsa, kseedsb, kseedsx, kseedsy, klabels, STEP, edgemag,compactness);
- EnforceLabelConnectivity(klabels, m_width, m_height, nlabels, numlabels, double(sz)/double(STEP*STEP));
3.关键程序解析:这里只讲
PerformSuperpixelSLIC与
EnforceLabelConnectivity
- PerformSuperpixelSLIC:
局部顾名思义,就是只对种子点附近的像素进行聚类,这里种子是按照STEP=S的跨度分布的,稍微扩大一点聚类范围,选为边长为2S矩形。
(2)
特征值计算
上面即像素到种子点的“距离”计算,距离中包括了LABXY5个特征值。方法就是,在局部区域内对每个像素点求其到中心的距离,若小于以前存放的距离,则将距离更新,且更新该像素点的类别标签。
(3)
种子点特征值更新
上部分程序,将超像素中的特征值加在一起。
上部分程序将各特征值的平均值作为中心点的特征值。
整个KMeans聚类迭代次数为10,即上面的内容重复10次,每次的像素点所属的类都有可能变化。
- EnforceLabelConnectivity