深入剖析mean shift 图像分割 原理及代码

首先你要知道这是PAMI 2003的一篇文章,非常经典的哦,Mean Shift: A Robust Approach Toward Feature Space Analysis。当然原文有17页,都是一些复杂的公式。。。。。

Mean shift主要用在图像平滑和图像分割(那个跟踪我现在还不清楚),先介绍一下平滑的原理:

输入是一个5维的空间,2维的(x,y)地理坐标,3维的(L,u,v)的颜色空间坐标,当然你原理也可以改写成rgb色彩空间或者是纹理特征空间。

先介绍一下核函数,有uniform的,也有高斯的核函数,不管是哪个的,其基本思想如下:简单的平滑算法用一个模板平均一下,对所有的像素,利用周围的像素平均一下就完事了,

这个mean shift的是基于概率密度分布来的,而且是一种无参的取样。有参的取样就是假设所有的样本服从一个有参数的概率分布函数,比如说泊松分布,正态分布等等,高中生都知道概率公式里面是有参数的,在说一下特征空间是一个5维的空间,距离用欧几里德空间就可以了,至少代码里就是这样实现的,而本文的无参取样是这样的:在特征空间里有3维的窗口(想象一下2维空间的窗口),对于一个特征空间的点,,对应一个5维的向量,可以计算该点的一个密度函数,如果是有参的直接带入该点的坐标就可以求出概率密度了,基于窗函数的思想就是考虑它邻近窗口里的点对它的贡献, 它假设密度会往密集一点的地方转移,算出移动之后的一个5维坐标,该坐标并会稳定,迭代了几次之后,稳定的地方是modes。这样每一个像素点都对应一个这么一个modes,用该点的后3维的值就是平滑的结果了,当然在算每个点的时候,有些地方可能重复计算了,有兴趣的化你可以参考一下源代码,确实是可以优化的。总结一下mean shift的平滑原理就是在特征空间中向密度更高的地方shift(转移)。

其次是怎么利用mean shift分割图像

先对图像进行平滑,

第2步利用平滑结果建立区域邻接矩阵或者区域邻接链表,就是在特征空间比较近的二间在2维的图像平面也比较接近的像素算成一个区域,这样就对应一个区域的邻接链表,记录每个像素点的label值。当然代码中有一个传递凸胞的计算,合并2个表面张力很接近的相邻区域,这个我还没想怎么明白,希望比较清楚的朋友讲一讲。最后还有一个合并面积较小的区域的操作,一个区域不是对应一个modes值嘛,在待合并的较小的那个区域中,寻找所有的邻接区域,找到距离最小的那个区域,合并到那个区域就ok了。

void msImageProcessor::Filter(int sigmaS, float sigmaR, SpeedUpLevel speedUpLevel)这个是平滑操作,sigmaS是2维的平面窗口的窗函数,sigmaR是颜色空间的窗函数,最后一个参数表示是否加速算法。

void msImageProcessor::FuseRegions(float sigmaS, int minRegion)这个就是合并较小区域的一个函数。

void msImageProcessor::Segment(int sigmaS, float sigmaR, int minRegion, SpeedUpLevel speedUpLevel)这个是分割函数,里面包括了平滑功能。再详细的我也不说了。。。。。

最后是怎么调用问题:void CImageProcessing::mydebug(){int x,y; int width_ = imageWidth;int height_ = imageHeight;unsigned char *tmp = new unsigned char[width_ * height_ * 3];unsigned char *dst = tmp;for (x = 0;x < imageHeight; x ++) for(y = 0;y < imageWidth; y++) { //Color tmp = (*imageData_RGB)(y, x); //uchar * data = &CV_IMAGE_ELEM(ip,uchar,x,y*3) ; // *(dst++) = data[2] ; // *(dst++) = data[1] ; // *(dst++) = data[0] ; *(dst++) = (*imageData_RGB)(y, x).channel[0]; *(dst++) = (*imageData_RGB)(y, x).channel[1]; *(dst++) = (*imageData_RGB)(y, x).channel[2]; } cbgImage_->SetImageFromRGB( tmp, width_, height_, true); delete []tmp; msImageProcessor *iProc = new msImageProcessor(); iProc->DefineImage(cbgImage_->im_, COLOR, height_, width_); iProc->SetSpeedThreshold(0.1); iProc->Segment(5,8,10,NO_SPEEDUP);// iProc->Filter(5,8,NO_SPEEDUP);// iProc->FuseRegions(mWinSize,mAreaSize);//°×ò} 至于怎么调试编译我看我是说不清楚了。。。。。。。。。。。。。。。。。。。。。。

发光并非太阳的专利,我也可以发光 。

深入剖析mean shift 图像分割 原理及代码

相关文章:

你感兴趣的文章:

标签云: