Accurate Scale Estimation for Robust Visual Tracking
我在前面一篇博客“相關濾波跟蹤(MOSSE)”中講了相關濾波跟蹤的原理,但是因爲那篇文章沒有提供代碼,所以就沒法深入的研究他,而且純理論看起來會很枯燥。後來Martin Danelljan 對MOSST做了改進,並增加了多尺度跟蹤,改進效果很顯著,在今年的VOT上,其測試效果是第一的。其文章名爲Accurate Scale Estimation for Robust Visual Tracking,其代碼爲DSST,因此後面就用DSST代表這種方法。我把文章代碼都上傳到這裏http://yunpan.cn/cHcj9c4q9VLfL 訪問密碼 af88 或者是這裏https://github.com/Lennycyz/DSST,大家可以下載。下面進入正文:
MOSSE(Visual Object Tracking using Adaptive Correlation Filters )在求解濾波器時,其輸入項是圖像本身(灰度圖),也就是圖像的灰度特徵。對於灰度特徵,其特徵較爲簡單,不能很好的描述目標的紋理、邊緣等形狀信息,因此DSST的作者將灰度特徵替換爲在跟蹤和識別領域較爲常用的HOG特徵。
DSST作者將跟蹤分爲兩個部分,位置變化(translation)和尺度變化(scale estimation)。在跟蹤的實現過程中,作者定義了兩個correlation filter,一個濾波器(translation filter)專門用於確定新的目標所處的位置,另一個濾波器(scale filter)專門用於尺度評估。
在translation filter方面,作者的方法與MOSSE的方法是一樣的,只不過其獲取最佳模板H的準則有了些許變化。根據translation filter可以獲取當前幀目標所處的位置,然後在當前目標位置獲取不同尺度的候選框,經過scale filter之後,確定新的目標尺度。
程序實現:
先來看看作者給出的僞代碼:
Algorithm 1 Proposed tracking approach :iteration at step t.
Input :
Image .
Precious target position and scale .
Translation model ,and scale model ,.
Output :
Estimated target position and scale .
Updated translation model ,and scale model ,.
Translation estimation :
1:Extract a translation sample from at and .
2:Compute the translation correlation using ,and in (6).
3:Set to the target position that maximizes .
Scale estimation :
4:Extract a translation sample from at and .
5:Compute the translation correlation using ,and in (6).
6:Set to the target position that maximizes .
Model update :
7:Extract samples and from at and .
8:Update the translation model ,using (5).
9:Update the scale model ,using (5).
初始化階段:
一、得到translation filter的輸入和輸出
% desired translation filter output (gaussian shaped), bandwidth proportional to target size
%prod(X)表示對X中的每個元素求積(product)
%ndgrid將兩個向量複製到rs(行rows) 和cs(cols)中
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)); %將矩正變爲單精度浮點型
已知初始目標框的爲
[rs, cs] = ndgrid((1:sz(1)) - floor(sz(1)/2), (1:sz(2)) - floor(sz(2)/2));
這裏的sz(1)=
>> sz=[4,6]
sz =
4 6
>> [rs, cs] = ndgrid((1:sz(1)) - floor(sz(1)/2), (1:sz(2)) - floor(sz(2)/2))
rs =
-1 -1 -1 -1 -1 -1
0 0 0 0 0 0
1 1 1 1 1 1
2 2 2 2 2 2
cs =
-2 -1 0 1 2 3
-2 -1 0 1 2 3
-2 -1 0 1 2 3
-2 -1 0 1 2 3
由上面的例程可看出,對於[rs,cs]=ndgrid(a,b)得到的結果是rs和cs都是m*n的矩陣,其中m等於a的維度,n等於b的維度。如果去rs和cs對應位置的點,構成一個組合,則能夠取邊所有可能的組合。
在MOSSE中講過,相關濾波器的求解公式:
上面獲取的這些patchs,再經過FFT之後,就是上式中的F,而G則是一個符合高斯分佈的形狀,並且峯值點F的中心。一般高斯分佈是如下形式:
一維高斯分佈函數:
一維高斯分佈函數:
作者程序中實現的方式爲:
y = exp(-0.5 * (((rs.^2 + cs.^2) / output_sigma^2)));
其中output_sigma=
yf = single(fft2(y))。
二、得到scale filter的輸入和輸出
與得到translation filter的方法相類似:
% desired scale filter output (gaussian shaped), bandwidth proportional to number of scales
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));
上面這段代碼中,nScale代表給定的尺度的個數,這裏nScale=33,scale_sigma_factor也是給定的參數,這裏scale_sigma_factor=1/4。
三、獲取hann window
這裏獲取hann window的目的是爲了降低FFT變換時,圖像邊緣對變換結果的影響。
作者代碼中用如下代碼獲取hann window:
cos_window = single(hann(sz(1)) * hann(sz(2))');
獲取一個sz(1)*sz(2)大小的cos_window框。
hann函數解釋:hann(L)
>> hann(5)
ans =
0
0.5000
1.0000
0.5000
0
>> hann(3)
ans =
0
1
0
>> hann(5)*hann(3)'
ans =
0 0 0
0 0.5000 0
0 1.0000 0
0 0.5000 0
0 0 0
跟蹤階段
一、更新目標框的位置
% extract the test sample feature map for the translation filter
%得到的是樣本的HOG特徵圖,並且用hann窗口減少圖像邊緣頻率對FFT變換的影響
xt = get_translation_sample(im, pos, sz, currentScaleFactor, cos_window);
% calculate the correlation response of the translation filter
xtf = fft2(xt);
% find the maximum translation response
%這裏是找到新到位置
response = real(ifft2(sum(hf_num .* xtf, 3) ./ (hf_den + lambda)));
[row, col] = find(response == max(response(:)), 1);
% update the position
pos = pos + round((-sz/2 + [row, col]) * currentScaleFactor);
positions(frame,:) = [pos target_sz];
作者首先將當前2倍大小的目標框(im_patch)resize成第一幀時2倍目標框大小sz。再提取im_patch的hog特徵圖。
一共提取了32個sz(1)*sz(2)大小的hog特徵,在用先前生成的cos_window與這32個特徵圖分別進行點乘操作,這樣做的目的是爲了減少圖像邊緣對FFT變換的影響。上面程序中xt就是經過cos_window操作後的hog特徵圖。其一共有28個hog特徵,,每個hog特徵都是sz(1)*sz(2)大小。
對xt進行FFT變換,得到變換後的結果xtf。
得到xtf後再用公式(對應論文中公式6):
二、更新目標框的尺度變化
% extract the test sample feature map for the scale filter
xs = get_scale_sample(im, pos, base_target_sz, currentScaleFactor * scaleFactors, scale_window, scale_model_sz);
% calculate the correlation response of the scale filter
xsf = fft(xs,[],2);
scale_response = real(ifft(sum(sf_num .* xsf, 1) ./ (sf_den + lambda)));
% find the maximum scale response
recovered_scale = find(scale_response == max(scale_response(:)), 1);
% update the scale
currentScaleFactor = currentScaleFactor * scaleFactors(recovered_scale);
if currentScaleFactor < min_scale_factor
currentScaleFactor = min_scale_factor;
elseif currentScaleFactor > max_scale_factor
currentScaleFactor = max_scale_factor;
end
target_sz = floor(base_target_sz * currentScaleFactor);
作者在跟蹤的過程中,將跟蹤分爲兩個部分,位置變化和尺度變化。作者採取兩個並行的相關性濾波器來分別對目標的位置變化和尺度變化進行評估。因此在代碼實踐上,這兩個濾波器的實現方式很相似。但是有幾點也不盡相同:
1、位移相關性濾波器(TF)在獲取hog特徵圖時,是以2倍目標框大小的圖像獲取的。並且這個候選框只有一個,即上一幀確定的目標框。
而尺度相關性濾波器(SF)在獲取hog特徵圖時,是以當前目標框的大小爲基準,以33中不同的尺度獲取候選框的hog特徵圖,即:
ss = (1:nScales) - ceil(nScales/2);
其理論依據是:
其中W和H分別代表目標框的寬度和高度,S代表尺度的個數。
2、SF的實踐過程中,FFT(快速傅里葉變換)和IFFT(快速傅里葉反變換)都是一維變換,而TF則是二維空間的變換。
三、更新TF和SF的參數
% extract the training sample feature map for the translation filter
xl=get_translation_sample(im, pos, sz, currentScaleFactor, cos_window);
% calculate the translation filter update
xlf = fft2(xl);
new_hf_num = bsxfun(@times, yf, conj(xlf));
new_hf_den = sum(xlf .* conj(xlf), 3);
% extract the training sample feature map for the scale filter
xs=get_scale_sample(im, pos, base_target_sz, currentScaleFactor * scaleFactors, scale_window, scale_model_sz);
% calculate the scale filter update
xsf = fft(xs,[],2);
new_sf_num = bsxfun(@times, ysf, conj(xsf));
new_sf_den = sum(xsf .* conj(xsf), 1);
if frame == 1
% first frame, train with a single image
hf_den = new_hf_den;
hf_num = new_hf_num;
sf_den = new_sf_den;
sf_num = new_sf_num;
else
% subsequent frames, update the model
hf_den = (1 - learning_rate) * hf_den + learning_rate * new_hf_den;
hf_num = (1 - learning_rate) * hf_num + learning_rate * new_hf_num;
sf_den = (1 - learning_rate) * sf_den + learning_rate * new_sf_den;
sf_num = (1 - learning_rate) * sf_num + learning_rate * new_sf_num;
end
參數跟新的過程與論文中公式(5)相吻合:
注:我後面會把這個MATLAB代碼改寫成C++的,完成後也會共享出來。