首先你要知道这是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 = 0x <imageHeightx ++)
for(y = 0y <imageWidthy++)
{
//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)//°ë¾¶ºÍ×îСÇøÓòÃæ»ý
} 至于怎么调试编译我看我是说不清楚了。。。。。。。。。。。。。。。。。。。。。。
推荐参考:
另外,团IDC网上有许多产品团购,便宜有口碑
先用特征值分解估计出信笑镇号个数,然后MUSIC算法中找出对应信号或信号噪声的特征向量,建立子空间。
S'*En*En'*S, 找最小值,谱搜索就好了。S是侍升培array manifold,En是噪声的特征向量。
函数照这个格式编就行 function output=MUSIC(array,Rxx,M)
array是线阵坐标矩阵,Rxx是老唯接收数据的二阶统计量,M是信号个数。
自己编吧,不难。。
每一幅图像都包含某种程度的噪声,噪声可以理解为由一种或者多种原因造成的灰 度值的随机变化,如由光子通量的随机性造成的噪声等,在大多数情况下,通过平滑技术(也常称为滤波技术)进行抑制或者去除, 其中具备保持边缘(Edge Preserving)作用的平滑技术得到了更多的关注。常用的平滑处理算法包括基于二维离散卷积的高斯平滑、均值平滑,基于统计学方法的中值平滑,具备保持边缘作用的平滑算法的双边滤波、导向滤波等。
I与K的二维离散卷积的计算步骤如下。
显然,高为H1、宽为W1的矩阵I与高为H2、宽为W2的卷积核K 的full卷积结果是一 个高为 H1+H2-1 、宽为 W1+W2-1 的矩阵,一般H2 ≤H1,W2 ≤W1。
从full卷积的计算过程可知, 如果Kflip靠近I 的边界, 那么就会有部分延伸到I之外而导致访问到未定义的值, 忽略边界,只是考虑I能完全覆盖Kflip内的值的情况, 该过程称为valid卷积。
当然, 只有当H2≤H1且W2≤W1时才会存在 valid卷积 。
为了使得到的卷积结果和原图像的高、宽相等,所以通常在计算过程中给Kflip指定 一个“锚点”, 然后将“锚点”循环移至图像矩阵的(r, c) 处, 其中0≤r<H1, 0≤c<W1,接下来对应位置的元素逐个相乘,最后对所有的积进行求和作为输出图像矩阵在 (r, c) 处的输出值。这个卷积过程称为same卷积,
大部分时候,为了更方便地指定卷积核的锚点,通常卷积核的宽、高为奇数,那么可以简单地令中心点为锚点的位置。same卷积是晌知full卷积的一部分,而如果valid卷积存在,那么valid卷积是same卷积的一部分。
对于full卷积和same卷积,矩阵I 边界处的值由于缺乏完整的邻接值,因此卷积运算 在这些区域需要特殊处理,方法是进行边界扩充,有如下几种常用方式。
利用上述不同的边界扩充方式得到的same卷积只是在距离矩阵上、下、左、右四个边界小于卷积核半径的区域内值会不同,所以只要在用卷积运算进行图像处理时,图像的重要信息不要落在距离边界小于卷积核半径的区域内就行。
如果一个卷积核至少由两个尺寸比它小的卷积核full卷积而成,并且在计算过程中在所有边界处均进行扩充零的 *** 作,且满足
其中kerneli的尺寸均比Kernel小,1≤i≤n,则称该卷积核是可分离的。
在图像处理中经常使用这样的卷积核,它可以分离为一坦谨敏维水平方向和一维垂直方向上的卷积核。
(1)full卷积性质
如果卷积核Kernel是可分离的, 且Kernel=kernel1★kernel2, 则有:
(2)same卷积性质
其中
其中,根据可分离卷积的性质,有
理解了上述高斯平滑的过程, 就可以明白OpenCV实现的高斯平滑函数:
从参数的设置可以看出, GaussianBlur 也是通让枝过分离的高斯卷积核实现的,也可以令水平方向和垂直方向上的标准差不相同,但是一般会取相同的标准差。 当平滑窗口比较小时, 对标准差的变化不是很敏感, 得到的高斯平滑效果差别不大; 相反,当平滑窗口 较大时,对标准差的变化很敏感, 得到的高斯平滑效果差别较大 。
利用卷积核 的分离性和卷积的结合律,虽然减少了运算量,但是随着卷积核窗口的增加,计算量仍会继续增大,可以利用图像的积分,实现时间复杂度为O(1)的快速均值平滑。
即任意一个位置的积分等于该位置左上角所有值的和。 利用矩阵的积分,可以计算出矩阵中任意矩形区域的和。
中值滤波最重要的能力是去除椒盐噪声。椒盐噪声是指在图像传输系统中由于解码误差等原因,导致图像中出现孤立的白点或者黑点。
一般来说,如果图像中出现较亮或者较暗的物体,若其大小小于中值平滑的窗口半径,那么它们基本上会被滤掉,而较大的目标则几乎会原封不动地保存下来。
中值平滑需要对邻域中的所有像素点按灰度值排序, 一般比卷积运算要慢。
在OpenCV中同样通过定义函数:
此外, 中值平滑只是排序统计平滑中的一种, 如果将取邻域的中值变为取邻域中的 最小值或者最大值, 显然会使图像变暗或者变亮。 这类方法就是后面要介绍的形态学 处理的基础。
高斯平滑、均值平滑在去除图像噪声时,会使图像的边缘信息变得模糊,接下来就 介绍在图像平滑处理过程中可以保持边缘的平滑算法: 双边滤波和导向滤波。
双边滤波是根据每个位置的邻域, 对该位置构建不同的权重模板。 详细过程如下:
其中0≤h<winH, 0≤w<winW, 且每个位置的空间距离权重模板是相同的。
其中0≤h<winH, 0≤w<winW, 显然每个位置的相似性权重模板是不一样的。
整个过程只在第二步计算相似性权重模板时和双边滤波不同, 但是对图像平滑的效果, 特别是对纹理图像来说, 却有很大的不同。
扩展
循环引导滤波 是一种 迭代 的方法, 本质上是一种多次迭代的联合双边滤波, 只是每次计算相似性权重 模板的依据不一样——利用本次计算的联合双边滤波结果作为下一次联合双边滤波计算 相似性权重模板的依据。
导向滤波在平滑图像的基础上,有良好的保边作用, 而且在细节增强等方面都有良好的表现,在执行时间上也比双边滤波快很多。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)