图像特征提取与描述_角点特征04:LBP算法+HOG特征算子
1.LBP算法
LBP(Local Binary Pattern)指局部二值模式,是一種用來描述圖像局部特征的算子,LBP特征具有灰度不變性和旋轉不變性等顯著優點。它是由T. Ojala, M.Pietik?inen, 和 D. Harwood在1994年提出,由于LBP特征計算簡單、效果較好,因此LBP特征在計算機視覺的許多領域都得到了廣泛的應用。
1.1 LBP特征描述
原始的LBP算子定義為在$33$的窗口內,以窗口中心像素為閾值,將相鄰的8個像素的灰度值與其進行比較,若周圍像素值大于中心像素值,則該像素點的位置被標記為1,否則為0。這樣,$33$鄰域內的8個點經比較可產生8位二進制數(通常轉換為十進制數即LBP碼,共256種),即得到該窗口中心像素點的LBP值,并用這個值來反映該區域的紋理信息。如下圖所示:
?LBP值是從左上角像素,順時針旋轉得到的結果,如下圖所示:
用公式來進行定義如下所示:
其中,(x?c??,y?c??)表示3*3鄰域內的中心元素,它的像素值為i?c??,i?p??代表鄰域內其他像素的值。s(x)是符號函數,定義如下:
對于一幅大小為W*H的圖像,因為邊緣的像素無法計算8位的LBP值,所以將LBP值轉換為灰度圖像時,它的大小是(W?2)?(H?2)。
LBP算子利用了周圍點與該點的關系對該點進行量化。量化后可以更有效地消除光照對圖像的影響。只要光照的變化不足以改變兩個點像素值之間的大小關系,那么LBP算子的值不會發生變化,所以一定程度上,基于LBP的識別算法解決了光照變化的問題,但是當圖像光照變化不均勻時,各像素間的大小關系被破壞,對應的LBP模式也就發生了變化。
原始的LBP提出后,研究人員不斷對其提出了各種改進和優化。
1.2 圓形LBP算子
原始LBP特征使用的是固定鄰域內的灰度值,當圖像的尺度發生變化時,LBP特征的編碼將會發生變換,LBP特征將不能正確的反映像素點周圍的紋理信息,因此研究人員對其進行了改進。基本的 LBP 算子的最大缺陷在于它只覆蓋了一個固定半徑范圍內的小區域,只局限在3*3的鄰域內,對于較大圖像大尺度的結構不能很好的提取需要的紋理特征,因此研究者們對LBP算子進行了擴展。
新的LBP算子$LBP_{p}^{R}$計算不同半徑鄰域大小和不同像素點數的特征值,其中P表示周圍像素點個數,R表示鄰域半徑,同時把原來的方形鄰域擴展到了圓形,下圖給出了三種擴展后的LBP例子,其中,R可以是小數:
對于沒有落到整數位置的點,根據軌道內離其最近的兩個整數位置像素灰度值,利用雙線性插值的方法可以計算它的灰度值。
該算子的計算公式與原始的LBP描述算子計算方法相同,區別在鄰域的選擇上。
1.3 旋轉不變LBP特征
從 LBP 的定義可以看出,LBP算子不是旋轉不變的。圖像的旋轉就會得到不同的 LBP值。所以 Maenpaa等人又將 LBP算子進行了擴展,提出了具有旋轉不變性的 LBP 算子,即不斷旋轉圓形鄰域得到一系列初始定義的 LBP值,取其最小值作為該鄰域的 LBP 值。即:
其中,ROR(x,i)ROR(x,i)指沿順時針方向旋轉LBP算子i次。如下圖所示:
上圖給出了求取旋轉不變的 LBP 的過程示意圖,算子下方的數字表示該算子對應的 LBP值,圖中所示的 8 種 LBP模式,經過旋轉不變的處理,最終得到的具有旋轉不變性的 LBP值為 15。也就是說,圖中的 8種 LBP 模式對應的旋轉不變的 LBP模式都是 00001111。
1.4 Uniform Pattern LBP特征
Uniform Pattern,也被稱為等價模式或均勻模式,由于一個LBP特征有多種不同的二進制形式,對于半徑為R的圓形區域內含有P個采樣點的LBP算子將會產生$2^P$種模式。很顯然,隨著鄰域集內采樣點數的增加,二進制模式的種類是以指數形式增加的。例如:5×5鄰域內20個采樣點,有2^20=1,048,576種二進制模式。這么多的二進制模式不利于紋理的提取、分類、識別及存取。例如,將LBP算子用于紋理分類或人臉識別時,常采用LBP模式的統計直方圖來表達圖像的信息,而較多的模式種類將使得數據量過大,且直方圖過于稀疏。因此,需要對原始的LBP模式進行降維,使得數據量減少的情況下能最好的表示圖像的信息。
為了解決二進制模式過多的問題,提高統計性,Ojala提出了采用一種“等價模式”(Uniform Pattern)來對LBP算子的模式種類進行降維。Ojala等認為,在實際圖像中,絕大多數LBP模式最多只包含兩次從1到0或從0到1的跳變。因此,Ojala將“等價模式”定義為:當某個LBP所對應的循環二進制數從0到1或從1到0最多有兩次跳變時,該LBP所對應的二進制就稱為一個等價模式類。如00000000(0次跳變),00000111(只含一次從0到1的跳變),10001111(先由1跳到0,再由0跳到1,共兩次跳變)都是等價模式類。除等價模式類以外的模式都歸為另一類,稱為混合模式類,例如10010111(共四次跳變)。
下圖所示的LBP值屬于等價模式類:
下圖中包含四次跳變,屬于非等價模式。
通過這樣的改進,二進制模式的種類大大減少,而不會丟失任何信息。模式數量由原來的$2^P$種減少為 P ( P-1)+2種,其中P表示鄰域集內的采樣點數。對于3×3鄰域內8個采樣點來說,二進制模式由原始的256種減少為58種,即:它把值分為59類,58個uniform pattern為一類,其它的所有值為第59類。這樣直方圖從原來的256維變成59維。這使得特征向量的維數更少,并且可以減少高頻噪聲帶來的影響。
等價特征的具體實現:采樣點數目為8個,即LBP特征值有2^8種,共256個值,正好對應灰度圖像的0-255,因此原始的LBP特征圖像是一幅正常的灰度圖像,而等價模式LBP特征,根據0-1跳變次數,將這256個LBP特征值分為了59類,從跳變次數上劃分:跳變0次—2個,跳變1次—0個,跳變2次—56個,跳變3次—0個,跳變4次—140個,跳變5次—0個,跳變6次—56個,跳變7次—0個,跳變8次—2個。共9種跳變情況,將這256個值進行分配,跳變小于2次的為等價模式類,共58個,他們對應的值按照從小到大分別編碼為1—58,即它們在LBP特征圖像中的灰度值為1-58,而除了等價模式類之外的混合模式類被編碼為0,即它們在LBP特征中的灰度值為0,因此等價模式LBP特征圖像整體偏暗。
1.5 實現
在OpenCV中實現了LBP特征的計算,但沒有提供一個單獨的計算LBP特征的接口。所以我們使用skimage給大家演示該算法。
skimage即是Scikit-Image。基于python腳本語言開發的數字圖片處理包,scikit-image是基于scipy的一款圖像處理包,它將圖片作為numpy數組進行處理。安裝方法:
pip install scikit-imageskimage包的全稱是scikit-image SciKit (toolkit for SciPy) ,它對scipy.ndimage進行了擴展,提供了更多的圖片處理功能。它是由python語言編寫的,由scipy 社區開發和維護。skimage包由許多的子模塊組成,各個子模塊提供不同的功能。其中feature模塊進行特征檢測與提取。
使用的API是:
skimage.feature.local_binary_pattern(image, P, R, method=‘default’)參數:
-
image: 輸入的灰度圖像
-
P,R: 進行LBP算子計算時的半徑和像素點數
-
method: 算法類型:{‘default’, ‘ror’, ‘nri-uniform’, ‘var’}
default: "默認",原始的LBP特征ror: 圓形LBP算子
nri-uniform: 等價LBP算子
var:旋轉不變LBP算子
示例:
我們在下圖中提取LBP特征:
代碼如下所示:
import cv2 as cv from skimage.feature import local_binary_pattern import matplotlib.pyplot as plt # 1.讀取圖像 img = cv.imread("face.jpeg") face = cv.cvtColor(img,cv.COLOR_BGR2GRAY) # 2.特征提取 # 2.0 需要的參數 # LBP算法中范圍半徑的取值 radius = 1 # 領域像素點數 n_points = 8 * radius # 2.1 原始LBP特征 lbp = local_binary_pattern(face, 8, 1)# 2.2 圓形LBP特征 clbp = local_binary_pattern(face,n_points,radius,method="ror")# 2.3 旋轉不變LBP特征 varlbp = local_binary_pattern(face,n_points,radius,method="var")# 2.4 等價特征 uniformlbp = local_binary_pattern(face,n_points,radius,method="nri-uniform")fig,axes=plt.subplots(nrows=2,ncols=2,figsize=(10,8)) axes[0,0].imshow(lbp,'gray') axes[0,0].set_title("原始的LBP特征") axes[0,0].set_xticks([]) axes[0,0].set_yticks([]) axes[0,1].imshow(clbp,'gray') axes[0,1].set_title("圓形LBP特征") axes[0,1].set_xticks([]) axes[0,1].set_yticks([]) axes[1,0].imshow(varlbp,'gray') axes[1,0].set_title("旋轉不變LBP特征") axes[1,0].set_xticks([]) axes[1,0].set_yticks([]) axes[1,1].imshow(uniformlbp,"gray") axes[1,1].set_title("等價特征") axes[1,1].set_xticks([]) axes[1,1].set_yticks([]) plt.show()檢測結果如下所示:
2.HOG算法
HOG(Histogram of Oriented Gridients的簡寫)特征檢測算法,最早是由法國研究員Dalal等在CVPR-2005上提出來的,一種解決人體目標檢測的圖像描述子,是一種用于表征圖像局部梯度方向和梯度強度分布特性的描述符。其主要思想是:在邊緣具體位置未知的情況下,邊緣方向的分布也可以很好的表示行人目標的外形輪廓。
2.1 特征提取流程
HOG的主要思想是:在一副圖像中,局部目標的表象和形狀(appearance and shape)能夠被梯度或邊緣的方向密度分布(即梯度的統計信息,而梯度主要位于邊緣的地方)很好地描述。
HOG特征檢測算法的幾個步驟:顏色空間歸一化—>梯度計算—>梯度方向直方圖—>重疊塊直方圖歸一化—>HOG特征。如下圖所示:
整體流程簡單描述如下:
下面我們詳細介紹每一步驟的內容:
2.2 顏色空間歸一化
為了減少光照因素的影響,首先需要將整個圖像進行規范化(歸一化)。在圖像的紋理強度中,局部的表層曝光貢獻的比重較大,所以,這種壓縮處理能夠有效地降低圖像局部的陰影和光照變化。因為顏色信息作用不大,通常先轉化為灰度圖,然后在進行伽馬校正。
伽馬校正能夠有效的降低圖像的局部陰影和光照所帶來的的影響,從而降低算法對光照的敏感度,增強算法的魯棒性。
伽馬校正使用下式所得:
其中,I(x,y)是圖像在伽馬校正前像素點(x,y)處的灰度值,Y(x,y)為標準化的像素點(x,y)處的灰度值。伽馬校正如圖所示:
從上圖中可以看出:
下圖中左圖是原圖,中圖是γ=1/2.2的校正結果,右圖是γ=2.2的校正結果。
在HOG特征提取中,γ一般取0.5,此時,圖像的灰度值被拉伸,且灰度越低,拉伸的幅度越大,也就是說,對于光照較暗的圖像處理較好,能較大程度提升他們的亮度。
2.3 圖像梯度計算
邊緣是由圖像局部特征包括灰度、顏色和紋理的突變導致的。一幅圖像中相鄰的像素點之間變化比較少,區域變化比較平坦,則梯度幅值就會比較小,反之,則梯度幅值就會比較大。梯度在圖像中對應的就是其一階導數,所以圖像梯度計算利用一階微分求導處理,不僅能夠捕獲輪廓、人影以及一些紋理信息,還能進一步弱化光照的影響。Dalal研究了很多算子,如下表所示:
2.4 梯度直方圖計算
Dalal的研究結果表明,梯度方向為無符號且通道數為9時得到最好的檢測效果,此時一個梯度方向的一個通道為180/9=20°,代表的是角度0,20,40,60.....160。梯度方向矩陣中可以看到角度是0-180度,不是0-360度,這種被稱之為"無符號"梯度("unsigned" gradients)因為一個梯度和它的負數是用同一個數字表示的,也就是說一個梯度的方向以及它旋轉180度之后的方向被認為是一樣的,如下圖所示:
假設圖像被分為多個cell單元,如下所示:
每個cell單元中包含8*8個像素,如下所示:
我們將上一步得到的梯度方向投影到9個通道中,并將梯度幅值作為投影時的權值。
在進行梯度方向投影處理時采用加權的方式,確定某個通道的權值,如下所示:
還有一個細節是,如果角度大于在(160,180)之間時,角度0和180是相等的,所以,角度為165時將其按照幅值比例投影到0和160兩個通道中:(180-165)/(165-160)
遍歷整個cell中的所有像素點,便可以得到該cell單元的梯度方向直方圖:
2.5 重疊塊直方圖歸一化
由于圖像的局部曝光度以及前景與背景之間的對比度存在多樣化的情況,所以梯度值的變化范圍非常廣,引進歸一化的直方圖對于檢測結果的提高有著非常重要的作用。
在上一步中我們在每一個cell單元中創建了梯度方向直方圖,在這一步中我們將在block塊中進行梯度直方圖的歸一化,每一個block是由2*2=4個cell單元構成,如下圖所示:
在每個塊中梯度直方圖應該是4*9=36維的。
在解釋直方圖是如何進行歸一化之前,讓我們看看長度為3的向量是如何進行歸一化的:假設一個像素向量[128,64,32],向量的長度則為:sqrt{128^2 + 64^2 + 32^2} = 146.64 這也被稱為向量的L2范數。將向量的每一個元素除以146.64得到歸一化向量[0.87,0.43,0.22]。
我們將一個block塊中的梯度直方圖串聯成一個36*1維向量,并進行歸一化,就得到了該block塊內的特征,因為block塊之間是有重疊的,也就是說每個cell單元中的特征會多次出現在不同的block塊中。
2.6 收集HOG特征
上一步中我們得到一個block塊的歸一化后的梯度方向直方圖,現在我們只需遍歷檢測圖像中所有的塊便可以得到整個圖像的梯度方向直方圖,這就是我們要求解的HOG特征向量。
如上圖所示,block塊與block塊之間是可以重疊的,假設我們的檢測圖像大小為(64×128),其x方向的有(64?8×2)/8=7個block塊,其中64為檢測圖像的寬度,第一個8為cell寬度,2為一個block塊中的cell單元寬度,第二個8為block塊的滑動增量,同理,y方向有(128?8×2)/8+1=15個block塊,其中128為檢測圖像的高度,第一個8為cell高度,2為一個block塊中的cell單元高度,第二個8為block塊的滑動增量,因此一共有7×15=105 個block,每一個block中梯度直方圖的維數為36,那么檢測圖像為(64×128)的HOG特征向量的維數為105×36=3780。將其顯示在圖像上如下圖所示:
?
從上圖中,我們可以發現直方圖的主要方向捕捉了人的外形,尤其是軀干和腿的部位。我們得到歸一化的HOG特征之后,就可以使用分類器對行人進行檢測,比如使用支持向量機SVM進行人與背景的分類,如下圖所示:
2.7 HOG特征的優缺點
HOG特征具有以下優點:
- HOG表示的是邊緣的結構特征,因此可以描述局部的形狀信息
- 位置和方向的量化在一定程度上可以一直平移和旋轉帶來的影響
- 采取局部區域歸一化直方圖,可以部分抵消光照變換帶來的影響
它也有不少缺點:
- 描述子生成冗長,維數較高,導致速度慢,實時性差
- 很難處理遮擋問題
- 由于梯度的性質,對噪聲非常敏感
2.2 實現
OpenCV提供了計算HOG特征的API,實現HOG特征提取的流程是:
參數:
- winSize: 檢測窗口的大小
- blockSize: block塊的大小
- blockStride: block塊的滑動步長
- cellSize: cell單元的大小
- Nbins:統計梯度的方向的數目,一般取為9,即在一個cell單元中計算9個方向的梯度直方圖
返回:
-
hog: 實例化后的Hog特征檢測對象
-
搜索整個圖像,計算圖像的HOG特征,調用:
參數:
- img: 輸入圖像
- winStrise:檢測窗口的滑動步長
- padding:填充,在圖像的周圍填充點對邊界進行處理。
返回:
- hogDes: 整幅圖像的HOG特征描述符,當padding為默認的(0,0)時,特征向量的維數:[(img_size - window_size) / window_stride +1 )]*(每個檢測窗口中的特征維數)。
示例:
我們計算下圖的hog特征:
代碼如下所示:
import cv2 as cv import numpy as np import matplotlib.pyplot as plt# 1.讀取圖像 img = cv.imread('xingren.jpeg') gray= cv.cvtColor(img,cv.COLOR_BGR2GRAY)# 2.Hog特征提取 # 2.1 參數設置 winSize = (64,128) blockSize = (16,16) blockStride = (8,8) cellSize = (8,8) nbins = 9# 2.2 實例化hog對象 hog = cv.HOGDescriptor(winSize,blockSize,blockStride,cellSize,nbins)# 2.3 計算Hog特征描述符 hogDes = hog.compute(img,winStride=(8,8))# 2.4 輸出描述符的大小 print(hogDes.size)輸出結果為:57380,該圖的大小為(128*256)(128?256) ,窗口大小為(64*128)(64?128) ,block塊大小為(16,16),塊的移動步長為 (8,8),cell單元大小為(8,8)時,每一個窗口的特征維度為3780,窗口移動步長為(8,8)時,則圖像的特征的維度:
總結:
LBP算法:
原始LBP特征:在3*33?3的窗口內,以窗口中心像素為閾值,將相鄰的8個像素的灰度值與其進行比較,若周圍像素值大于中心像素值,則該像素點的位置被標記為1,否則為0。這樣,3*33?3鄰域內的8個點經比較可產生8位二進制數,即LBP值。
圓形LBP算子:計算不同半徑鄰域大小和不同像素點數的特征值
旋轉不變LBP算子:不斷旋轉圓形鄰域得到一系列初始定義的 LBP值,取其最小值作為該鄰域的 LBP 值
Uniform Pattern LBP特征:當某個LBP所對應的循環二進制數從0到1或從1到0最多有兩次跳變時,該LBP所對應的二進制就稱為一個等價模式類。。除等價模式類以外的模式都歸為另一類,稱為混合模式類。
API:
Skiimage.feature.Local_binary_pattern()
HOG算法
思想:在一副圖像中,局部目標的表象和形狀(appearance and shape)能夠利用梯度或邊緣的方向密度分布來描述。
HOG特征檢測算法的步驟:
顏色空間歸一化—>梯度計算—>梯度方向直方圖—>重疊塊直方圖歸一化—>HOG特征
簡單描述如下:
1)將輸入圖像灰度化,即將彩色圖轉換為灰度圖
2)顏色空間歸一化:采用Gamma校正法對輸入圖像進行顏色空間的標準化(歸一化),目的是調節圖像的對比度,降低圖像局部的陰影和光照變化所造成的影響,同時可以抑制噪音的干擾
3)梯度計算:計算圖像每個像素的梯度(包括大小和方向);主要是為了捕獲輪廓信息,同時進一步弱化光照的干擾
4)梯度方向直方圖:將圖像劃分成小cells(例如6*6像素/cell), 統計每個cell的梯度直方圖(不同梯度的個數),即可形成每個cell的描述符
5)重疊直方圖歸一化:將每幾個cell組成一個block(例如3*3個cell/block),一個block內所有cell的特征descriptor串聯起來便得到該block的HOG特征描述符。
6)HOG特征:將圖像image內的所有block的HOG特征描述符串聯起來就可以得到該image的HOG特征描述符,就得到最終的可供分類使用的特征向量了。
API:
1)實例化HOG對象:
hog = cv.HOGDescriptor()
2) 計算HOG特征描述符
hogdes = hog.Compute()
總結
以上是生活随笔為你收集整理的图像特征提取与描述_角点特征04:LBP算法+HOG特征算子的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 人脸识别案例:【实战】opencv人脸检
- 下一篇: nginx服务无法启动,启动时报错106