HOG特征


原文請移步知乎:https://zhuanlan.zhihu.com/p/40960756

 

python實現:

實現
基於python的scikit-image庫提供了HOG特征提取的接口:

from skimage import feature as ft
features = ft.hog(image, # input image
orientations=ori, # number of bins
pixels_per_cell=ppc, # pixel per cell
cells_per_block=cpb, # cells per blcok
block_norm = 'L1', # block norm : str {‘L1’, ‘L1-sqrt’, ‘L2’, ‘L2-Hys’}
transform_sqrt = True, # power law compression (also known as gamma correction)
feature_vector=True, # flatten the final vectors
visualise=False) # return HOG map

 


參數說明:
image: input image, 輸入圖像

orientation: 指定bin的個數. scikit-image 實現的只有無符號方向.
(根據反正切函數的到的角度范圍是在-180°~ 180°之間, 無符號是指把 -180°~0°這個范圍統一加上180°轉換到0°~180°范圍內. 有符號是指將-180°~180°轉換到0°~360°范圍內.)
也就是說把所有的方向都轉換為0°~180°內, 然后按照指定的orientation數量划分bins. 比如你選定的orientation= 9, 則bin一共有9個, 每20°一個:
[0°~20°, 20°~40°, 40°~60° 60°~80° 80°~100°, 100°~120°, 120°~140°, 140°~160°, 160°~180°]

pixels_per_cell : 每個cell的像素數, 是一個tuple類型數據,例如(20,20)

cell_per_block : 每個BLOCK內有多少個cell, tuple類型, 例如(2,2), 意思是將block均勻划分為2x2的塊

block_norm: block 內部采用的norm類型.

transform_sqrt: 是否進行 power law compression, 也就是gamma correction. 是一種圖像預處理操作, 可以將較暗的區域變亮, 減少陰影和光照變化對圖片的影響.

feature_vector: 將輸出轉換為一維向量.

visualise: 是否輸出HOG image, (應該是梯度圖)

scikit-image 版的HOG 沒有進行cell級別的gaussian 平滑, 原文對cell進行了gamma= 8pix的高斯平滑操作.

 

二. HOG實例講解(以下所有的系統參數都是按照上述論文實驗得出的最佳結果確定的)

  1. 圖像預處理

包括伽馬校正和灰度化。這是可選的步驟,因為實驗證明做不做影響不大。伽馬校正是減少光度對實驗的影響。灰度化是將彩色圖片變成灰度圖。其實彩色圖片也可以直接處理。不過是分別對三通道的顏色值進行梯度計算,最后選擇梯度最大的那個。為簡單起見,假設輸入為灰度圖,同時大小是64*128(這個大小是上面論文的大小,也可以自己確定不同的大小,但是實驗效果就不能得到保證)。

 

2.計算每一個像素點的梯度值,得到梯度圖(規模和原圖大小一樣)

對於像素點A,要計算水平梯度和豎直梯度,如上圖,水平梯度 g_x =30-20=10,豎直梯度 g_y =64-32=32.

那么總的梯度強度值g和梯度方向 \theta 將按照以下公式計算:

g=\sqrt{g_x^2+g_y^2}

\theta=arctan{\frac{g_x}{g_y}}

梯度方向將會取絕對值,因此梯度方向的范圍是0-180度。取絕對值的原因是這樣效果更好。

 

3.計算梯度直方圖

 

按照第二步的計算,每一個像素點都會有兩個值:梯度強度/梯度方向。

現在就計算梯度直方圖,這是一個關鍵步驟也是HOG能夠work的原因。

梯度直方圖是在一個8*8的cell里面計算的。那么在8*8的cell里面就會有8*8*2=128個值,2是包括了梯度強度和梯度方向。通過統計形成梯度直方圖,128個值將會變成9個值,大大降低了計算量,同時又對光照等環境變化更加地robust。

首先,我將0-180度分成9個bins,分別是0,20,40...160。然后統計每一個像素點所在的bin。請看下圖:

左上圖是8*8的梯度方向值,右上圖是8*8的梯度強度值,下圖是9個bins。

先看兩個藍色圈圈。因為藍圈的方向是80度,大小是2,所以該點就投給80這個bin;

再看兩個紅色圈圈。因為紅色圈圈的方向是10,大小是4,因為10距離0點為10,距離20點為也為10,那么有一半的大小是投給0這個bin,還有一半的大小(即是2)投給20這個bin。

那么統計完64個點的投票數以后,每個bin就會得到一個數值,可以得到一個直方圖,在計算機里面就是一個大小為9的數組。

從上圖可以看到,更多的點的梯度方向是傾向於0度和160度,也就是說這些點的梯度方向是向上或者向下,表明圖像這個位置存在比較明顯的橫向邊緣。因此HOG是對邊角敏感的,由於這樣的統計方法,也是對部分像素值變化不敏感的,所以能夠適應不同的環境。

 

4. 對16*16大小的block歸一化

歸一化的目的是降低光照的影響。

歸一化的方法是向量的每一個值除以向量的模長。

比如對於一個(128,64,32)的三維向量來說,模長是 \sqrt{128^2+64^2+32^2}=146.64

那么歸一化后的向量變成了(0.87,0.43,0.22)

那么16*16大小的block是怎么來的?

請看下圖:

綠色方塊是8*8大小的cell,藍色方塊就是由4個cell組成的block。作者提出要對block進行normalize。那么由於一個cell就會有大小為9的vector,四個cell就有36大小的vector。對block進行normalize就是對這大小為36的vector進行歸一化。

而每一個block將按照上圖籃框移動的方式進行迭代截取。

 

5.得到HOG特征向量

每一個16*16大小的block將會得到36大小的vector。那么對於一個64*128大小的圖像,按照上圖的方式提取block,將會有7個水平位置和15個豎直位可以取得,所以一共有7*15=105個block,所以我們整合所有block的vector,形成一個大的一維vector的大小將會是36*105=3780。

得到HOG特征向量,就可以用來可視化和分類了。對於這么大的HOG特征,SVM就排上用場了。

文章就寫到這里,謝謝閱讀。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM