基于MeanShift的Camshift算法原理详解(整理)
第一篇MeanShift原理和实现
1 MeanShift原理
如下图所示:矩形窗口中的红色点代表特征数据点,矩形中的圆圈代表选取窗口。meanshift算法的目的是找到含有最多特征的窗口区域,即使圆心与概率密度函数的局部极值点重合,亦即使圆心与特征数据点最密集的地方中心尽量重合到一块。算法实现是通过向特征数据点密度函数上升梯度方向逐步迭代偏移至上升梯度值近似为零(到达最密集的地方)。
即在不改变选取局部窗口的情况下,通过给窗口一个向着特征数据点更密集的方向一个偏移向量,然后将偏移后的选取窗口作为当前选取窗口,根据选取窗口数据特征点密集情况给出一个一个向着特征数据点更密集的方向一个偏移向量……迭代偏移过程中,直到偏移向量的模值近似为零即可。
我们来分析一下上述过程:当选取窗口(圆形)由远靠近最密集点,再远离最密集点的过程中,圆形窗口中特征数据点的数量变化:理想情况下应是选取窗口包含的特征数据点越来越多,再到越来越少。(这个过程对应meanshift算法的基本形式,没有添加核函数时)
2 为什么要用概率密度函数的上升梯度呢?
概率密度函数可以表示大小不变的选取窗口中特征数据点的密度,我们要找的是概率密度最大的选取窗口,这样,我们只要使下一个选取窗口的概率密度函数值减去当前选取窗口的概率密度函数值大于0,就可以越来越靠近取窗口的概率密度函数的最大值,当下一个选取窗口与当前选取窗口非常接近时,就可以用概率密度梯度表示两窗口概率密度函数对应值的差,也就是说只要使选取窗口向概率密度函数梯度上升的方向偏移就可以在上升梯度值近似为零时取得概率密度函数的近似最大值。所以使用概率,是因为特征数据点本身是概率事件或说是标定与标准特征匹配程度的特征数据。
上面的分析的前提是默认选取窗口中的各个特征数据点的权值是相等的,但实际中各个特征数据点对最终判定是否为目标的影响是不一样的,这可以通过加权值函数(即meanshift扩展方法中的核函数)来实现。
3 添加的权值函数应满足什么条件呢?
对某一选取窗口的概率密度函数值=各个特征数据点的总和相当量除以窗口面积的相当量。
当选取窗口为全局窗口时,目标一定出现,即此范围内权值函数的各个值的总和归一化后一定为1。
为了便于比较和求概率密度函数的梯度,加权函数亦即核函数在自变量取值范围内的积分为1.
所以核函数应满足的条件:自变量范围内积分,值为1。
4 meanshift方法的适用范围及其优缺点
meanshift方法适合概率密度函数有极值且在某一局部区域内唯一,即选择的特征数据点能够较为明显的判定目标,亦即显著特征点。显然此方法,meanshift的基本形式不适合等概率特征点(即特征点是均匀分布)的情况。
1) meanshift算法,受初始值的影响很大,和经验相关。
2) 算法收敛的速度和程度很大程度上与选取的窗口有关,选取恰当的窗口非常重要。
3) 窗口选取的是否恰当很大程度上取决于目标(特征数据点的分布状况),这就是说此方法在处理一类目标时,还是很有效的,最起码跟踪同一目标,在窗口经过恰当的线性变换后,跟踪效果应该还是不错的。即概率密度函数的极值在自变量区域压缩或扩大的过程中,极值仍存在,仍可跟踪到目标。
4) meanshift算法若用于图割,则适用于:
已经建立标准的特征数据点集,且通过恰当的概率密度函数和核函数可以唯一的确定目标时,可以将目标从批量图片中分割,挑选出来,但是取出的结果显示为选取窗口中所有的内容,也就是说可能会有目标物之外的图像或缺失部分目标物。若选取窗口为目标物的轮廓,那将非常不错,也就意味着窗口模板要更新或目标轮廓是不变的(实际中不变几乎是不可能的),更新以为误差与误差的积累,也就是说进行批量分割时,效果是有限的。
5 meanshift 编程实现(opencv)
具体编程实现的时候meanshift算法思想其实很简单——利用概率密度的梯度爬升来寻找局部最优。它要做的就是输入一个在图像的范围,然后一直迭代(朝着重心迭代)直到满足你的要求为止。
例如在opencv中,实现过程:输入一张图像(imgProb),再输入一个开始迭代的方框(windowIn)和一个迭代条件(criteria),输出的是迭代完成的位置(comp )。
这是函数原型:
int cvMeanShift( const void* imgProb,CvRect windowIn,
CvTermCriteria criteria, CvConnectedComp* comp )
但是当它用于跟踪时,这张输入的图像就必须是反向投影图了。反向投影图实际上是一张概率密度图。经过反向投影时的输入是一个目标图像的直方图(也可以认为是目标图像),还一个输入是当前图像就是你要跟踪的全图,输出大小与全图一样大,它上像素点表征着一种概率,就是全图上这个点是目标图像一部分的概率。如果这个点越亮,就说明这个点属于物体的概率越大。
1)半自动跟踪思路:
输入视频,用画笔圈出要跟踪的目标,然后对物体跟踪。(用过opencv的都知道,这其实是camshiftdemo的工作过程)
第一步:选中物体,记录你输入的方框和物体。
第二步:求出视频中有关物体的反向投影图。
第三步:根据反向投影图和输入的方框进行meanshift迭代,由于它是向重心移动,即向反向投影图中概率大的地方移动,所以始终会移动到目标上。
第四步:然后下一帧图像时用上一帧输出的方框来迭代即可。
2)全自动跟踪思路:
输入视频,对运动物体进行跟踪。