1. 程式人生 > >影象特徵提取之(三) --- HOG特徵

影象特徵提取之(三) --- HOG特徵

1.hog特徵提取流程


這裡寫圖片描述

2.伽瑪校正
在計算機系統中,由於顯示卡或者顯示器的原因會出現實際輸出的影象在亮度上有偏差,而Gamma曲線矯正就是通過一定的方法來矯正影象的這種偏差的方法。一般情況下,當用於Gamma矯正的值大於1時,影象的高光部分被壓縮而暗調部分被擴充套件,當Gamma矯正的值小於1時,影象的高光部分被擴充套件而暗調部分被壓縮。目的是調節影象的對比度,降低影象區域性的陰影和光照變化所造成的影響,同時可以抑制噪音的干擾。


這裡寫圖片描述

公式如下:
這裡寫圖片描述

表示對影象I取指數值gamma

3.計算梯度
梯度包括梯度的幅值和方向。
點(x,y)處的水平梯度為:
這裡寫圖片描述
點(x,y)處的垂直梯度為:
這裡寫圖片描述


點(x,y)處梯度的幅值為:
這裡寫圖片描述
點(x,y)處梯度的方向為:
這裡寫圖片描述

4.構建cell梯度直方圖
將0~360分為18分,每份為20度,由於tanx的週期為180度,所以0~20與180~200度屬於同一類,以此類推,一共可以得到9類方向。


這裡寫圖片描述

將影象劃分為若干個cell(cell之間無重疊),例如64*64的image,cell的大小為8*8,則一共可以得到64個cell,對cell中的每個畫素求取梯度方向,統計對應梯度方向類別的加權數量,
其中,某畫素梯度方向對應的權值為該畫素的梯度幅值,由此得到cell的梯度方向直方圖。

5. 把單元格組合成大的塊(block),塊內歸一化梯度直方圖


可以形象的理解為塊是滑動的,block滑動的步長應等於cell的邊長。bolck之間一定有重疊,重疊的好處是每一個單元格的特徵會以不同的結果多次出現在最後的特徵向量中。


這裡寫圖片描述

塊內歸一化:來自http://blog.csdn.net/zhazhiqiang/article/details/21047207
採用了四中不同的方法對區間進行歸一化,並對結果進行了比較。引入v表示一個還沒有被歸一 化的向量,它包含了給定區間(block)的所有直方圖資訊。| | vk | |表示v的k階範數,這裡的k去1、2。用e表示一個很小的常數。這時,歸一化因子可以表示如下:
L2-norm:
這裡寫圖片描述
L1-norm:
這裡寫圖片描述


L1-sqrt:
這裡寫圖片描述
L2-Hys:它可以通過先進行L2-norm,對結果進行截短(clipping)(即值被限制為v - 0.2v之間),然後再重新歸一化得到。

6.最終結果
如上文中所提到的例子,一張64*64的image,cell的大小為8*8,則可以得到64個shell,
選取block的大小為16*16,滑動的步長為8,則一共有7*7=49個block,每個block含有4個shell,每個特徵向量的長度為9,將上述的特徵向量串聯起來,則最終每張得到的每個特徵向量的長度為,9*4*49 = 1764.

7. opencv中呼叫HOGDescriptor 提取hog特徵

HOGDescriptor *hog = HOGDescriptor(cvSize(IMG_WIDTH ,IMG_HEIGHT),cvSize(16,16),cvSize(8,8),cvSize(8,8), 9);
引數1:檢測串列埠(例程中檢測整幅圖片)
引數2:塊大小
引數3:塊的滑動步長
引數4:cell大小
引數5:梯度方向數
    vector<float>descriptors;
    hog->compute(trainImg, descriptors, Size(8,8), Size(0,0));
    Mat result = Mat::zeros(1,descriptors.size(), CV_32FC1);
    result = Mat(descriptors).t()