SCM代码的学习与优化

1.初始化阶段

 1). 关于仿射变换的函数都位于文件夹Affine Sample Function;

      试验序列存放在文件夹Datasets中,参数设置trackparam,与ALSA类似,只是关于仿射参数的计算处理,SCM是在主程序demo.m中进行。

      模板尺寸设置为32*32,不同的序列粒子数不同, 应该是在准确度的基础上为了提高运行效率对粒子数进行了调整。(ALSA的粒子数为600,但运行对比之后,速度仍然比SCM更快)

 2). SDC初始化设置:50个正样本A_pos,200个负样本A_neg

由affineTrainG.m实现:正样本根据trackparam预设的第一帧的仿射参数,在目标周围几像素半径内采样,再用标准双线性内插滤波器下采样以选择图像。

                                           负样本来自目标周围的环形区域,并不全是背景,还带有一部分目标,作者认为可以使算法获得更高的准确率。

SCM代码的学习与优化_第1张图片

 3). SGM初始化设置:直方图字典

这一部分的model同ALSA一样用重叠的滑动窗口进行patch化,利用了结构化局部信息。

patch尺寸为6*6,步长为2,因此每个粒子/模板可以得到13x13个patch。(32-6)/2=13,M=(13+1)*(13+1)=196

affineTrainL.m涉及到了for循环将32*32的模板/粒子进行patch化,修改后,利用ALSA算法中的img2patch.m函数,可能会提高速度。


2..正式跟踪

【原理】SDC+SGM

for循环:从1:num(总帧数)

读取图像,若是彩色图像则转换成灰度图像。(历来各种tracker几乎都是用的灰度信息,凌海滨老师提到过目前已有利用彩色信息的趋势,是为一个创新点。)


>>>>SDC<<<<

1). 粒子滤波采样affineSample.m

如前所说,不同序列的粒子数设定并不总是一样,根据序列的复杂度来调整。

在affineSample函数中,原作又用了一个for循环将三维矩阵转换成二维,在此借鉴ALSA的处理方式,直接reshape函数搞定。在对比中,刚开始还疑惑怎么修改前和修改后得到的结果每次都不一样……一时没转过弯,原因是粒子滤波,有概率因素的嘛!

粒子滤波返回三个变量:wimgs(三维矩阵形式的粒子)、Y(粒子向量化/二维矩阵形式的粒子)、param(n个粒子的仿射参数)

n个粒子+50个正样本+200个负样本归一化处理之后,进入了特征选择模块。

2). 特征选择selectFeature.m

selectFeature.m这个函数相当于找到一个映射基,上一步采样到的粒子与该映射基相乘,就可以剔除一些冗余的信息。至于具体是怎么找到这个映射基的呢?这里也很巧妙的用到了稀疏理论,作者认为:正样本对应+1,负样本对应-1,这个对应关系可以通过一个稀疏的映射基s来传达。记正负样本为矩阵A,±1label为向量P,映射基s,即A*s=p。

利用稀疏理论求解s,实际上就是对feature进行选择,去除对p没有贡献的信息。(作者code里的p代表公式中的s,凌乱ing……)


具体解法:mexLasso求解稀疏向量s(1024*1),找出s中的非零元,假设有s_L个,按照规则:第n个非零元对应第n列,且在第n列中的位置由该非零元在s中的标号确定,(用1代替),扩展为1024*s_L维的S映射矩阵。

求出映射矩阵S之后,便将1)采样得到的n个粒子、50个正样本、200个负样本都投影到该映射空间。至此,特征维数便从1024降为了s_L维(通常为100~200维左右)。

3). 置信度量

这一部分的思想与传统的sparse tracker[L1-tracker、ALSA等]无异:目标可以由正样本稀疏表示,背景可以由负样本span。


值得注意的是,这里的“字典”A'同时包含了正负样本,那么势必会产生疑问:由此解出来的稀疏向量alpha同时含有正样本与负样本的系数,如何去表征它的识别能力呢?

作者的方法是求解重构误差:如果输入x是正的,那么对应正样本的系数应该是稀疏的,而负样本不是;负样本同理。因此可以通过分别计算两类重构误差,见下式。


如果粒子是正样本,前者很小,后者很大。而置信度量便可依据指数的特性拉大二者的差距以更好的挑选粒子。



>>>SGM<<<

原理:计算模板用字典稀疏表示的系数,每一帧的M个粒子的稀疏系数;根据文中提出的遮挡处理方法(依据重构误差+阈值来判断),剔除各个粒子中发生遮挡的块;最后就是模板系数和候选粒子稀疏之间进行相似性度量,得到Lc。

PS. 这部分的代码,作者用的是for循环对单帧的n_sample个粒子逐个进行处理。出于优化的角度考虑,我改成了批量处理单帧的所有粒子。


公式也是针对单个patch(yi)的,可以把M个patch按列放置矩阵Y中,可以一次解出所有的稀疏,得到文中的ρ。


遮挡处理很好理解,利用各个patch稀疏的重构误差,判断哪些patches发生遮挡,再把对应的patch剔除(系数为0)。


SGM的相似性度量利用的是直方图相交函数:对应找到第j个patch与模板的系数相比较的min,再求和。


>>>collaborative model<<<

联合策略特别简单,SDC与SGM的度量相乘,找到值最大的粒子即为当前帧的目标。


3. 模板更新

每5帧更新一次:SDC模型中的负样本,SGM的模板直方图(实质是稀疏系数)

输入:param(更新前最后一帧的跟踪结果的仿射参数)、alpha_p(更新前最后一帧跟踪结果对应的稀疏系数)、alpha_q(第一帧的稀疏系数)

【个人认为】code里的输入有错,文章中强调在update策略中不引入遮挡patches,下面的公式也体现了,融合的都是经过遮挡处理的直方图ψ。所以此处输入也应该是

遮挡weighted之后的直方图。

SDC:在当前帧的结果附近,根据初始化阶段的affineTrainG.m函数里对negative samples进行采集(在目标周围,带一点目标的部分和背景)。返回至参数X_neg.

SGM:字典D保持不变,防止引入错误的跟踪结果和遮挡信息;只更新模板直方图。根据预设的遮挡阈值,判断是否要更新模板。见下式:


μ后面的是第一帧的模板稀疏系数,(1-μ)加权的是更新前最后一帧的跟踪结果的稀疏系数。

写到最后我终于要吐槽原作,你的代码和文章的命名真是迷之凌乱啊_(:з」∠)_

原code中的O_n是每个粒子的196个patches中发生遮挡的比例,阈值O_0设置为0.8,意思是当超过80%的块被遮挡时就不更新当前循环中的模板(即不引入遮挡信息以避免漂移),否则就按μ加权融合一些当前跟踪结果的信息进去。


写在最后:经过几天的优化调试,我把code中的for循环等进行了向量化矩阵化处理,目前测试的几个序列,速度提高了10~20%左右。


你可能感兴趣的:(SCM代码的学习与优化)