代碼關鍵點記錄:成功不遠了!O(∩_∩)O 哈哈~
1. Input : load_video_info.m 讀入視頻文件groundtruth_rect.txt(裏面是4個一組的點,x,y, width ,height ?),得到有用的參數:
target_sz = [ground_truth(1,4), ground_truth(1,3)]; 得到的是目標的尺寸(這裏好像是第一張的,也就是一樣大)
這個值會用來計算空間帶寬的值。通常一個m*n的目標,它的空間帶寬爲 sqrt(m*n)/16. 也就是後面的:
output_sigma
= sqrt(prod(target_sz)) * output_sigma_factor;
這個參數後面再看
sz = floor(target_sz * (1 + padding));
實際計算的時候將目標放大爲兩倍來計算。
得到sz以後有一部非常重要的操作:
[rs, cs] = ndgrid((1:sz(1)) - floor(sz(1)/2), (1:sz(2)) - floor(sz(2)/2));
y = exp(-0.5 / output_sigma^2 * (rs.^2 + cs.^2));
yf = fft2(y);
首先將範圍變成以target中心爲原點的分佈,然後表示出目標中心可能出現的概率分佈;接下來變換到頻域裏面去。
由此可以看出公式中的y不是我們平時使用的1或者是-1,而是一個可能出現的概率標籤。
pos = [ground_truth(1,2), ground_truth(1,1)] + floor(target_sz/2);
pos代表的是目標中心的位置。
cos_window = hann(sz(1)) * hann(sz(2))爲了消除邊緣的效應和強調中心,使用一個窗口。若是Opencv裏面沒有我們可以自己寫:
一個維度上的表示是這樣的: w(n)=0.5(1−cos2π n/N ) ,0≤n≤N。(當然好像也有一個函數叫做createHanningWindow,具體的也需要查一下。)
2.讀入圖片序列,進行操作
對於每一張進來的圖片,先轉化爲灰度圖。
然後代碼中相當冗長繁瑣讓人費解的一段代碼取出了 Target中的x 和Y的座標(當然有一些的邊界的處理),接下來將這個區域內的
灰度值歸一化到 -0.5 到 0.5(out = double(out) / 255 - 0.5;). 接下來通過hanning 窗口使得數據沒有邊緣效應(out= hann(sz(1)) *
hann(sz(2))* out)。
記得這個時候輸出的是經過歸一化,hanning窗 處理的目標的灰度值。
3. 求高斯核
主要就是參照公式(16):
求出高斯核。也就是代碼中的:k = exp(-1 / sigma^2 * max(0, (xx + yy - 2 * xy) / numel(x)));
同時還需要解釋的一個函數是: circshift,循壞位移函數。例如: circshift(a,[1,2])表示的是將a 行向下移動一行,再向右移動兩列。
而當這個數是負數就是向相反的方向!
例如:
a
=
1 2 3
4 5 6
7 8 9
0 0 0
>> circshift(a,[-1])
ans =
4 5 6
7 8 9
0 0 0
1 2 3
>> circshift(a,[1 2])
ans =
0 0 0
2 3 1
5 6 4
8 9 7
高斯核的求取過程中,用到了兩個區域的傅里葉變換,再在頻域內點積,而後又用到了循壞移位!這裏的意義是我現在還不能理解的。。
再一次的看到這裏我才明白這篇論文的優點是用了非常多的樣本來訓練分類器,而不是用一般的方法:從附近取幾個作爲正樣本,遠一點取幾個作爲負樣本,作者取了2倍size範圍內的這些樣本都用來訓練分類器。
接下來我還有一點的疑惑是:檢測的過程中不同位置的樣本體現在哪裏!!!
敬請期待!
iker Cross
2014. 12. 16