MD大神的fDSST是DSST的加速改进版,文章发表在TPAMI17上先给文章地址:
http://www.cvl.isy.liu.se/en/research/objrec/visualtracking/scalvistrack/DSST_TPAMI.pdf
fDSST代码matlab在作者主页有提供:http://www.cvl.isy.liu.se/en/research/objrec/visualtracking/scalvistrack/index.html
fDSST的加速主要体现在PCA将尺度特征维度缩减 。
代码分析:
run_tracker.m部分代码没有区别主要完成了视频数据加载初始化参数等,fDSST.m代码中体现了与DSST的区别。
下面是初始化的尺度部分,主要建立了17个尺度变化因子和33个内插尺度变化因子,并且建立了尺度回归目标ys和尺度cos窗,其它则是一些细节的考虑
可以看到这些与二维图像的初始化没有本质的差别,就是换成一维的操作,将二维图像向量化则变成了一维。
if nScales > 0 scale_sigma = nScalesInterp * scale_sigma_factor; scale_exp = (-floor((nScales-1)/2):ceil((nScales-1)/2)) * nScalesInterp/nScales; scale_exp_shift = circshift(scale_exp, [0 -floor((nScales-1)/2)]); interp_scale_exp = -floor((nScalesInterp-1)/2):ceil((nScalesInterp-1)/2); interp_scale_exp_shift = circshift(interp_scale_exp, [0 -floor((nScalesInterp-1)/2)]); scaleSizeFactors = scale_step .^ scale_exp; interpScaleFactors = scale_step .^ interp_scale_exp_shift; ys = exp(-0.5 * (scale_exp_shift.^2) /scale_sigma^2); ysf = single(fft(ys)); scale_window = single(hann(size(ysf,2)))'; %make sure the scale model is not to large, to save computation time if scale_model_factor^2 * prod(init_target_sz) > scale_model_max_area scale_model_factor = sqrt(scale_model_max_area/prod(init_target_sz)); end %set the scale model size scale_model_sz = floor(init_target_sz * scale_model_factor); im = imread(s_frames{1}); %force reasonable scale changes min_scale_factor = scale_step ^ ceil(log(max(5 ./ sz)) / log(scale_step)); max_scale_factor = scale_step ^ floor(log(min([size(im,1) size(im,2)] ./ base_target_sz)) / log(scale_step)); max_scale_dim = strcmp(params.s_num_compressed_dim,'MAX'); if max_scale_dim s_num_compressed_dim = length(scaleSizeFactors); else s_num_compressed_dim = params.s_num_compressed_dim; end end
在后面的循环中主要思路就是提取特征,训练得到模型参数,提取下一帧图像patch的特征,利用训练好的模型计算响应,得到下一帧的位置和尺度,如此循环;
尺度的计算可以认为与位置的计算是分开的,尺度信息就是一个值:当前帧尺度因子,乘上固定的初始size则是当前帧的size;
我们先看尺度训练代码部分,在后半部
if nScales > 0 %create a new feature projection matrix [xs_pca, xs_npca] = get_scale_subwindow(im, pos, base_target_sz, currentScaleFactor*scaleSizeFactors, scale_model_sz); %上面一句提取了17个不同尺度的patch再统一resize到scale_model_sz大小,然后再分别提取这些patch的hog特征,将hog特征拉成一维的 %最后输出的xs_pca是17个一维的hog向量,用于后面的降维,后面的那个变量没用,是空的 if frame == 1 s_num = xs_pca; else s_num = (1 - interp_factor) * s_num + interp_factor * xs_pca; end; %上面两句用于特征的更新,目的使模型对于跟踪目标的鲁棒性变强 bigY = s_num; bigY_den = xs_pca; if max_scale_dim [scale_basis, ~] = qr(bigY, 0); [scale_basis_den, ~] = qr(bigY_den, 0); else [U,~,~] = svd(bigY,'econ'); scale_basis = U(:,1:s_num_compressed_dim); end scale_basis = scale_basis'; %上面使用奇异值分解得到pca变换矩阵,源代码中将维度最大化压缩从744维到17维 %create the filter update coefficients sf_proj = fft(feature_projection_scale([],s_num,scale_basis,scale_window),[],2); sf_num = bsxfun(@times,ysf,conj(sf_proj)); %通过降维得到的模型矩阵只有17*17大小,获得了极大加速 xs = feature_projection_scale(xs_npca,xs_pca,scale_basis_den',scale_window); xsf = fft(xs,[],2); new_sf_den = sum(xsf .* conj(xsf),1); if frame == 1 sf_den = new_sf_den; else sf_den = (1 - interp_factor) * sf_den + interp_factor * new_sf_den; end; %更新模型,和特征更新的原因相同 end
再来看看检测部分的尺度代码
if nScales > 0 %create a new feature projection matrix [xs_pca, xs_npca] = get_scale_subwindow(im,pos,base_target_sz,currentScaleFactor*scaleSizeFactors,scale_model_sz); xs = feature_projection_scale(xs_npca,xs_pca,scale_basis,scale_window); xsf = fft(xs,[],2); %提取待检测patch的不同尺度的特征并且降维,pca矩阵用的也是训练部分的那个矩阵 scale_responsef = sum(sf_num .* xsf, 1) ./ (sf_den + lambda); %计算响应,这是个17维的向量 interp_scale_response = ifft( resizeDFT(scale_responsef, nScalesInterp), 'symmetric'); %内插分出了33维的相应的向量 recovered_scale_index = find(interp_scale_response == max(interp_scale_response(:)), 1); %找到响应值最大的所对应的那个尺度因子 %set the scale currentScaleFactor = currentScaleFactor * interpScaleFactors(recovered_scale_index);