目标跟踪--Learning Dynamic Siamese Network for Visual Object Tracking 代码阅读

目标跟踪–Learning Dynamic Siamese Network for Visual Object Tracking 代码阅读

该论文是2017年ICCV的会议论文,作者使用动态孪生网络进行目标跟踪,论文名《Learning Dynamic Siamese Network for Visual Object Tracking》。有关论文理论的详细介绍可以参考:https://blog.csdn.net/aiqiu_gogogo/article/details/79429071 博客内容。本篇主要记录对其代码阅读。

作者认为SiameseFC跟踪效果不好是因为缺少了在线更新过程,因此将目标变化和背景抑制认为是一种线性变化,变化系数求解采用KCF中提到的变换到傅立叶域内进行处理求解。个人认为只要有了KCF和SiameseFC的相关基础,本文还是较好理解的。


代码阅读
代码是matlab编写而成的,采用的深度学习框架是MatconvNet。入口韩式是demo_tracking.m文件。核心文件是run_DSiam.m文件。从代码可以看出作者是根据SiameseFC基础上修改而来,主要在里面增加了求解Target appearance variation V和Background suppression W过程。
网络初始化
demo_tracking.m文件主要完成相关路径设置等,完成相关配置后到run_DSiam.m文件进行网络初始化和跟踪过程。
在run_DSiam.m文件中第一个重要点是52行

[state,opts] = fcnet_init(img, state, netname, nettype);

fcnet_init函数完成网络孪生网络的初始化和相关参数设置等工作。孪生网络总用于目标跟踪的网络结构如图1所示。
在这里插入图片描述

图1 跟踪网络结构图

跟踪阶段
跟踪阶段是run_DSiam.m中的57-91行,核心是fcn_update函数。下面主要分析fcn_update函数作用。
fcn_update函数首先加载相关参数和网络模型。然后代码

x_crops = make_scale_pyramid(img, pos, scaledInstance, instanceSize, avgChans,opts);

代码提取了三种尺度下的以目标为中心的图像patch块。然后使用孪生网络中用于跟踪的网络(网络结构如图1所示)进行一次前向传播,得到新目标位置等。到此完成跟踪当前帧,只需要不断迭代这一步骤即可。
下面主要记录一下论文中的创新点是如何体现在代码中的。在执行跟踪的前向传播阶段时,利用的是图1网络结构,其中18、19行作者自己创建了名为CirConv的层,该层主要配合接下来要讲的update_vupdate_w计算论文中公式(即本文核心内容)
在这里插入图片描述在这里插入图片描述在这里插入图片描述
因为V和W求的是t-1帧的变化系数,所以从跟踪开始,在第三帧才进行计算第二帧的变化系数。因此在完成第二帧跟踪后,首先将exemplar的特征保存在变量corrfeat中,第二帧(t-1)帧的特征保存在tcorrfeat中,然后执行代码

net_conv = update_v(net_conv, corrfeat, tcorrfeat, opts)

其中参数net_conv网络结构如图1所示,corrfeat是图1网络提取到的feature map,tcorrfeat是exemplar的feature map。update_v函数核心如下所示。

function net = update_v(net,feats_1,feats_t,p)

[alphaf,featf] = update_change(feats_1{1}(:,:,:,1),feats_t{1},p.v_lambda);

net.params(net.getParamIndex('cir11_alphaf')).value = alphaf;
net.params(net.getParamIndex('cir11_featf')).value = featf;
net.layers(net.getLayerIndex('circonv1_1')).block.enable = true;

上述代码可以看出,update_v重点是update_change函数。其代码为

function [change_alpahf,change_featf] = update_change(corrfeat,new_corrfeat,lambda,issum)
if nargin<4
   issum =false; 
end

% leanring filter from corrfeat to new_corrfeat
cos_window = hann(size(corrfeat,1)) * hann(size(corrfeat,2))';
tcorrfeat = bsxfun(@times, corrfeat, cos_window);

corrfeatf = fft2(tcorrfeat);
numcorr = numel(corrfeatf(:,:,1));
if ~issum
    kcorrfeatf = (corrfeatf .* conj(corrfeatf))./numcorr;
else
    kcorrfeatf = sum(corrfeatf .* conj(corrfeatf),3)./numel(corrfeatf);
end
tnew_corrfeat = bsxfun(@times, new_corrfeat, cos_window);
tnew_corrfeatf = fft2(tnew_corrfeat);
alphaf = tnew_corrfeatf./ (kcorrfeatf+ lambda);   

change_alpahf = alphaf;
change_featf = corrfeatf;
end

分析这段代码可以看出先对exemplar做fft变换并保存在变量corrfeatf中,然后将 F ∗ ( F 1 l ) ⨀ F ( F 1 l ) \mathcal{F^*(F^l_1)}\bigodot\mathcal{F(F^l_1)} F(F1l)F(F1l)结果存放在变量kcorrfeatf中,变量alpha中存放 F ( F t − 1 l ) F ∗ ( F 1 l ) ⨀ F ( F 1 l ) + λ v \frac{\mathcal{F(F^l_{t-1})}}{\mathcal{F^*(F^l_1)}\bigodot\mathcal{F(F^l_1)} + \lambda_v} F(F1l)F(F1l)+λvF(Ft1l)。这样执行完update_change函数后返回update_v中将alpha保存在cir11_alphaf(图1中18行的一个参数),corrfeatf存放入cir11_featf(图1中18行的一个参数)。
在跟踪第三帧,使用图1的网络结构进行前向传播,其中circonv1_1核心代码如下所示

for fi = 1:numsamp
	feat = ofeat(:,:,:,fi);
	trans_alphaf = params{1};
        trans_featf = params{2};
	trans_lr = params{3};            
       % add transformation to feat
        cos_window = hann(size(feat,1)) * hann(size(feat,2))';
        feat = bsxfun(@times, feat, cos_window);
        featf = fft2(feat);
        numcorr = numel(featf(:,:,1));
        if ~obj.calsum
        	kfeatf = (featf .* conj(trans_featf))./numcorr;
               t_feat = real(ifft2(trans_alphaf.* kfeatf));
               assert(ndims(feat) == ndims(t_feat), 'feat and t_feat have different number of dimensions');
               toutputs(:,:,:,fi)= (1-trans_lr).*ofeat(:,:,:,fi)+trans_lr.*t_feat;
        else
                kfeatf = sum(featf .* conj(trans_featf),3)./numel(featf);
                t_feat = real(ifft2(trans_alphaf.* kfeatf));
                toutputs(:,:,:,fi) = (1-trans_lr).*inputs{2}(:,:,:,fi)+trans_lr.*t_feat;
        end
end

代码

kfeatf = (featf .* conj(trans_featf))./numcorr;
t_feat = real(ifft2(trans_alphaf.* kfeatf));

完成论文中公式(2)与刚刚update_v中为未计算完的部分。此时关于V的更新已经结束,接下来准备更新W,W更新与V更新调用同一函数,过程完全一致。
到此,论文中主要代码就到此结束,其他内容多是相关配置项设置等,与理解论文核心内容关系不大。

评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值