粒子滤波法是指通过寻找一组在状态空间传播的随机样本对概率密度函数进行近似,以样本均值代替积分运算,从而获得状态最小方差分布的过程。
对于粒子滤波跟踪方法,这里有一篇很浅显易懂的博客,我分享给大家他的工作也是参考Rob Hess的程序做的,感谢老外的开源精神,我看了他的程序,我也提出了我的几点改进,作者本身的设想是想做多目标的运动跟踪,但函数接口写的还是有些混乱,以至于最后不能实现(估计是我才疏识浅,没能领会作者的精神),而且用到了gsl数学库,这个库我是不熟悉的,开了一下程序,主要也就只用了里面的随机数的功能,这功能在新版本的OpenCV里已经集成啦,作者用的数据结构还是老版本的结构,好多函数还是作者自己写的,我这里用新版本的数据结构重新写了一遍这个算法,简化跟踪目标为一个。下面介绍一下我的设计流程
首先还是将视频转换到HSV颜色空间,我发现很多图像处理的办法都是在该空间下完成的,Rob Hess对HSV颜色空间的特征提取还是很有意思的,他知道色度和饱和度提供的信息和亮度提供的信息分开考虑,做出了他自己的特征直方图。我这里用了新版本的calcHist做的特征直方图,偷了个懒,效果感觉还可以。
初始化阶段就是对鼠标选中的目标区域的特征直方图提取,进入搜索阶段,通俗的讲,就是在待搜索区域里放入大量的粒子particle,放入粒子的规则有很多,这里使用的是让粒子的分布为高斯分布,计算每个粒子所在区域的特征直方图,与目标区域特征进行比较,特征接近的粒子的权重大一些,反之权重小一些。通过调整各粒子的权重大小和样本位置来近似实际的概率分布,以样本期望作为系统估计值。然后进行重采样,重新分布粒子的位置。(对于重采样的目的,是为了解决序列重要性采样(SIS)存在的退化现象,即几步迭代之后,许多粒子的权重变得很小,大量的计算浪费在小权值的粒子上。解决退化问题的一般办法就是重采样原理,基本思想就是对后验概率密度再采样,保留复制权重大的粒子,剔除权重小的粒子。程序里感觉只是据粒子的权重的后验概率分布进行一次重新采样,感觉并不是yangyangcv说的那个类似ransac的意思,因为我对代码分析并没有循环放粒子的过程,欢迎大家拍砖)
具体的算法流程为
我的实际编程步骤大概可以分为如下几步:
// step 1: 提取目标区域特征
// step 2: 初始化particle(粒子的个数很影响跟踪的速度)
// step 3: 求particle的transition(这一步的参数会很影响粒子的变化区域,需要对不同的跟踪对象进行调整参数)
// step 4: 求particle区域的特征直方图(特征选取的不合适也很影响结果)
// step 5: 特征的比对,更新particle权重(特征比较的方法也是影响结果的因素)
// step 6: 归一化粒子权重
// step 7: resample根据粒子的权重的后验概率分布重新采样
// step 8: 计算粒子的期望,作为跟踪结果
再写一下我试验后的心得,我用的是最基本的粒子滤波算法,考虑因素较少,受参数影响很大,而且参数众多,不方便自动调整。对不同的视频跟踪效果差别很大,而且会出现目标丢失的情况。这都是可以改进的。