阅读前默认读者已经看过论文《Accurate Scale Estimation for Robust Visual Tracking》,并阅读过此博客。这篇文章写得很好,让我快速入门。本文将沿用其测试例程的方法。
位置滤波器
期望的高斯输出/余弦窗初始化
output_sigma = sqrt(prod(base_target_sz)) * output_sigma_factor;
[rs, cs] = ndgrid((1:sz(1)) - floor(sz(1)/2), (1:sz(2)) - floor(sz(2)/2));
y = exp(-0.5 * (((rs.^2 + cs.^2) / output_sigma^2)));
yf = single(fft2(y)); %fft是傅利叶变换
输出yf是在[sz(1) sz(2)]上的期望二维高斯输出,其中心在sz矩形框的中心。sz的面积是初始目标框大小的4倍。
cos_window = single(hann(sz(1)) * hann(sz(2))');
cos_window:sz(1)*sz(2) single /中心值最大为0.9997向四周递减(值为0)
上面的两者一旦计算,就固定不变(即使后续目标框会有微调)。
第一帧
提取位置滤波器的训练样本特征图
xl = get_translation_sample(im, pos, sz, currentScaleFactor, cos_window);
位置滤波器的设置/初始化
new_hf_num = bsxfun(@times, yf, conj(xlf));
% new_hf_num:sz(1)*sz(2)*28 complex single 初始化位置滤波器的分母
new_hf_den = sum(xlf .* conj(xlf), 3);
% new_hf_den:sz(1)*sz(2) single 初始化位置滤波器的分子
hf_den = new_hf_den;
hf_num = new_hf_num;
第二帧及后续帧
提取位置滤波器的测试样本特征图
xt = get_translation_sample(im, pos, sz, currentScaleFactor, cos_window);
1 当前帧的中心位置更新
response = real(ifft2(sum(hf_num .* xtf, 3) ./ (hf_den + lambda)));
[row, col] = find(response == max(response(:)), 1);
pos = pos + round((-sz/2 + [row, col]) * currentScaleFactor);
2 位置滤波器的更新
new_hf_num = bsxfun(@times, yf, conj(xtf));
% new_hf_num:sz(1)*sz(2)*28 complex single 位置滤波器的新分母
new_hf_den = sum(xtf .* conj(xtf), 3);
% new_hf_den:sz(1)*sz(2) single 位置滤波器的新分子
hf_den = (1 - learning_rate) * hf_den + learning_rate * new_hf_den;
hf_num = (1 - learning_rate) * hf_num + learning_rate * new_hf_num;
关于sum(hf_num .* xtf, 3)的理解
可实例测试如下:
>> A(:,:,1)=[1 2;3 4];
>> A(:,:,2)=[2 3;4 5];
>> B(:,:,1)=[3 4;5 6];
>> B(:,:,2)=[4 5;6 7];
>> sum(A .* B,3)
ans =
11 23
39 59
因为1*3+2*4=11 2*4+3*5=23 3*5+4*6=39 4*6+5*7=59
因此sum(A .* B,3)=A(i,j,1)*B(i,j,1)+A(i,j,2)*B(i,j,2)。这里可以看成A和B是2*2的图像像素算子,每个像素点有两维特征,每个像素点的得分为:该点的各维特征对应元素的乘积和。
关于get_translation_sample
先把当前2倍大小的目标框(im_patch)resize成第一帧时4倍目标框大小的sz。再提取im_patch的hog特征图。一共提取了sz(1)*sz(2)大小的hog特征(32维),但只取了前27维;再加上一维灰度特征,共28维。再用先前生成的cos_window与这28维的特征图分别进行点乘操作,这样做的目的是为了减少图像边缘对FFT变换的影响。上面程序中xt就是经过cos_window操作后的hog特征图。其输出xt维度为sz(1)*sz(2)*28。对xt进行FFT变换,得到变换后的结果xtf。
关于response
response = real(ifft2(sum(hf_num .* xtf, 3) ./ (hf_den + lambda)));
[row, col] = find(response == max(response(:)), 1);
response是每一个单位点的得分值。
得到的中心点的坐标不一定是像素点,而是和给定帧的单位相同。如[139 112 36 51]
关于bsxfun(@times, yf, conj(xlf))的理解
可实例测试如下:
>> x=[1 2 3;4 5 6]
x =
1 2 3
4 5 6
>> y=[1 2 3]
y =
1 2 3
>> num = bsxfun(@times, y, conj(x))
num =
1 4 9
4 10 18
相当于将y的每一列的数乘以x的每一列的数。
>> den = sum(x .* conj(x), 1)
den =
17 29 45
相当于将x的每一列元素的平方和输出。
尺度滤波器
期望的高斯输出初始化
scale_sigma = nScales/sqrt(33) * scale_sigma_factor;
ss = (1:nScales) - ceil(nScales/2);
ys = exp(-0.5 * (ss.^2) / scale_sigma^2);
ysf = single(fft(ys));
给定/期望一维高斯响应输出:大小为33维,高斯中心在维度的中点处。
scale_window = single(hann(nScales));
% scale_window:33*1 single 中心值最大为1向上下两端递减(值为0)
上面的两者一旦计算,就固定不变(即使后续目标框会有微调)。
第一帧
提取尺度滤波器的训练样本特征图
xs = get_scale_sample(im, pos, base_target_sz, currentScaleFactor * scaleFactors, scale_window, scale_model_sz);
尺度滤波器的设置/初始化
new_sf_num = bsxfun(@times, ysf, conj(xsf));
new_sf_den = sum(xsf .* conj(xsf), 1);
sf_den = new_sf_den;
sf_num = new_sf_num;
第二帧及后续帧
提取尺度滤波器的测试样本特征图(其实是一样的)
xs = get_scale_sample(im, pos, base_target_sz, currentScaleFactor * scaleFactors, scale_window, scale_model_sz);
1 尺度(因子)更新
scale_response = real(ifft(sum(sf_num .* xsf, 1) ./ (sf_den + lambda)));
recovered_scale = find(scale_response == max(scale_response(:)), 1);
currentScaleFactor = currentScaleFactor * scaleFactors(recovered_scale);
2 尺度滤波器的更新
new_sf_num = bsxfun(@times, ysf, conj(xsf));
new_sf_den = sum(xsf .* conj(xsf), 1);
sf_den = (1 - learning_rate) * sf_den + learning_rate * new_sf_den;
sf_num = (1 - learning_rate) * sf_num + learning_rate * new_sf_num;
关于get_scale_sample
不管当前的im_patch为多少,都会被resize成下面的大小。
im_patch_resized: 19*26 uint8
temp_hog = fhog(single(im_patch_resized), 4); % temp_hog:4*6*32 single
temp = temp_hog(:,:,1:31);
% temp: 4*6*31 single scale_window:33*1 single
% temp(:) * scale_window(s):4*6*31 single
4*6*31=744,这表示第一个尺度下的输出。一共有33个,故是744*33的输出。
关于维度问题
以位置滤波器为例
hf_num:sz(1)*sz(2)*28 %位置滤波器分子
hf_den:sz(1)*sz(2) %位置滤波器分母
意思是在程序实现时,位置滤波器的分子分母维度是不匹配的