LBP基本原理與特徵分析

轉自:http://blog.csdn.net/songzitea/article/details/17686135

背景介紹

局部二值模式(Local binary patterns,LBP)是機器視覺領域中用於描述圖像局部紋理特徵的算子,具有旋轉不變性和灰度不變性等顯著的優點。它是由T. Ojala, M.Pietikäinen, 和 D. Harwood [1][2]在1994年提出,LBP在紋理分類問題上是一個非常強大的特徵;如果LBP與HOG結合,則可以在一些集合上十分有效的提升檢測效果。LBP是一個簡單但非常有效的紋理運算符。它將各個像素與其附近的像素進行比較,並把結果保存爲二進制數。由於其辨別力強大和計算簡單,局部二值模式紋理算子已經在不同的場景下得到應用。LBP最重要的屬性是對諸如光照變化等造成的灰度變化的魯棒性。它的另外一個重要特性是它的計算簡單,這使得它可以對圖像進行實時分析。本節介紹相關LPB算法特徵提取知識。

基本理論

局部二值模式是廣泛用於圖像分類的一種圖像特徵,它的特點是,在圖像發生光照變化時,提取的特徵仍然能夠不發生大的改變。提取LBP的過程首先是將原始圖像轉換爲LBP圖,然後統計LBP圖的LBP直方圖,並以這個向量形式的直方圖來表示原始的圖像。LBP的基本思想是定義於像素的8鄰域中,以中心像素的灰度值爲閾值,將周圍8個像素的值與其比較,如果周圍的像素值小於中心像素的灰度值,該像素位置就被標記爲0,否則標記爲1.每個像素得到一個二進制組合,就像00010011.每個像素有8個相鄰的像素點,即有2^8種可能性組合.如下圖所示。


因此,LBP操作可以被定義爲

其中35是中心像素,亮度是36;而37則是相鄰像素的亮度。s是一個符號函數:


這種描述方法使得你可以很好的捕捉到圖像中的細節。實際上,研究者們可以用它在紋理分類上得到最先進的水平。正如剛纔描述的方法被提出後,固定的近鄰區域對於尺度變化的編碼失效。所以,使用一個變量的擴展方法,在文獻[5]中有描述。主意是使用可變半徑的圓對近鄰像素進行編碼,這樣可以捕捉到如下的近鄰:


對一個給定的點40   ,他的近鄰點 41 可以由如下計算:


其中,R是圓的半徑,而P是樣本點的個數。這個操作是對原始LBP算子的擴展,所以有時被稱爲擴展LBP(又稱爲圓形LBP)。如果一個在圓上的點不在圖像座標上,我們使用他的內插點。計算機科學有一堆聰明的插值方法,而OpenCV使用雙線性插值。


LBP的提升版本

原始的LBP提出後,研究人員不斷對其提出了各種改進和優化。

圓形LBP算子

基本的LBP算子的最大缺陷在於它只覆蓋了一個固定半徑範圍內的小區域,這顯然不能滿足不同尺寸和頻率紋理的需要。爲了適應不同尺度的紋理特徵,並達到灰度和旋轉不變性的要求,Ojala等對 LBP 算子進行了改進,將 3×3鄰域擴展到任意鄰域,並用圓形鄰域代替了正方形鄰域,改進後的 LBP 算子允許在半徑爲 R 的圓形鄰域內有任意多個像素點。從而得到了諸如半徑爲R的圓形區域內含有P個採樣點的LBP算子;


LBP均勻模式LBP (uniform LBP)

基本地LBP算子可以產生不同的二進制模式,對於半徑爲R的圓形區域內含有P個採樣點的LBP算子將會產生P2種模式。很顯然,隨着鄰域集內採樣點數的增加,二進制模式的種類是急劇增加的。均勻模式就是一個二進制序列從0到1或是從1到0的變過不超過2次(這個二進制序列首尾相連)。比如:10100000的變化次數爲3次所以不是一個uniform pattern。所有的8位二進制數中共有58個uniform pattern.爲什麼要提出這麼個uniform LBP呢,例如: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(共四次跳變)。通過這樣的改進,二進制模式的種類大大減少,而不會丟失任何信息。模式數量由原來的2P種減少爲 P ( P-1)+2種,其中P表示鄰域集內的採樣點數。對於3×3鄰域內8個採樣點來說,二進制模式由原始的256種減少爲58種,即:它把值分爲59類,58個uniform pattern爲一類,其它的所有值爲第59類。這樣直方圖從原來的256維變成59維。這使得特徵向量的維數更少,並且可以減少高頻噪聲帶來的影響。

旋轉不變模式LBP

旋轉不變模式LBP能夠在圖片發生一定的傾斜時也能得到相同的結果。它的定義可以看下(注:此圖來自於網絡):

 


我們看到中心點的鄰居不再是它上下左右的8個點(補充一句,不一定非要是3*3的鄰域,這個自己定,但是鄰域大了意味着直方圖向量維度的增加),而是以它爲圓心的一個圈,規定了這個圓的半徑和點的個數,就可以求出各個點的座標,但是點的座標不一定是整數,如果是整數那麼這個點的像素值就是對應點的值,如果不是整數,就用差值的方式得到。從 LBP 的定義可以看出,LBP 算子是灰度不變的,但卻不是旋轉不變的。圖像的旋轉就會得到不同的 LBP值。Maenpaa等人又將 LBP算子進行了擴展,提出了具有旋轉不變性的 LBP 算子,即不斷旋轉圓形鄰域得到一系列初始定義的 LBP值,取其最小值作爲該鄰域的 LBP 值。

如上圖所示(注:此圖來自於網絡)給出了求取旋轉不變的 LBP 的過程示意圖,圖中算子下方的數字表示該算子對應的 LBP值,圖中所示的 8 種 LBP模式,經過旋轉不變的處理,最終得到的具有旋轉不變性的 LBP值爲 15。也就是說,圖中的 8種 LBP 模式對應的旋轉不變的 LBP模式都是 00001111。

上述介紹了幾種不同版本的LBP,對LBP特徵向量進行提取的步驟,如下所示:

  1. 將檢測窗口劃分爲16×16的小區域(cell);
  2. 對於每個cell中的一個像素,將相鄰的8個像素的灰度值與其進行比較,若周圍像素值大於中心像素值,則該像素點的位置被標記爲1,否則爲0。這樣,3*3鄰域內的8個點經比較可產生8位二進制數,即得到該窗口中心像素點的LBP值;
  3. 然後計算每個cell的直方圖,即每個數字(假定是十進制數LBP值)出現的頻率;然後對該直方圖進行歸一化處理。
  4. 最後將得到的每個cell的統計直方圖進行連接成爲一個特徵向量,也就是整幅圖的LBP紋理特徵向量;

然後便可利用SVM或者其他機器學習算法進行分類了。

參考代碼

本節,提供基本LBP和均勻模式LBP實現代碼地函數。在此給出測試的源圖像。如圖所示:

基本LBP代碼

  1. void LBP(IplImage* src, IplImage* dst){    
  2.     int width=src->width;    
  3.     int height=src->height;    
  4.     for(int j=1;j
  5.         for(int i=1;i
  6.             uchar neighborhood[8]={0};    
  7.             neighborhood[7] = CV_IMAGE_ELEM( src, uchar, i-1, j-1);    
  8.             neighborhood[6] = CV_IMAGE_ELEM( src, uchar, i-1, j);    
  9.             neighborhood[5] = CV_IMAGE_ELEM( src, uchar, i-1, j+1);    
  10.             neighborhood[4] = CV_IMAGE_ELEM( src, uchar, i, j-1);    
  11.             neighborhood[3] = CV_IMAGE_ELEM( src, uchar, i, j+1);    
  12.             neighborhood[2] = CV_IMAGE_ELEM( src, uchar, i+1, j-1);    
  13.             neighborhood[1] = CV_IMAGE_ELEM( src, uchar, i+1, j);    
  14.             neighborhood[0] = CV_IMAGE_ELEM( src, uchar, i+1, j+1);    
  15.             uchar center = CV_IMAGE_ELEM( src, uchar, i, j);    
  16.             uchar temp=0;    
  17.     
  18.             for(int k=0;k<8;k++){    
  19.                 temp+=(neighborhood[k]>center)*(1<<k);    
  20.             }    
  21.             CV_IMAGE_ELEM( dst, uchar, i, j)=temp;    
  22.         }    
  23.     }    
  24. }   

輸出結果爲:

 

UniformPatternLBP代碼

 

  1. void UniformPatternLBP(IplImage* src, IplImage* dst) {    
  2.     int width=src->width;    
  3.     int height=src->height;    
  4.     uchar table[256];     
  5.     memset(table,0,256);    
  6.     uchar temp=1;    
  7.     for(int i=0;i<256;++i)  {    
  8.         if(getHopCount(i)<=2) {    
  9.             table[i]=temp;    
  10.             temp++;    
  11.         }    
  12.         // printf("%d\n",table[i]);    
  13.     }   
  14.     for(int j=1;j
  15.         for(int i=1;i
  16.             uchar neighborhood[8]={0};    
  17.             neighborhood[7] = CV_IMAGE_ELEM( src, uchar, i-1, j-1);    
  18.             neighborhood[6] = CV_IMAGE_ELEM( src, uchar, i-1, j);    
  19.             neighborhood[5] = CV_IMAGE_ELEM( src, uchar, i-1, j+1);    
  20.             neighborhood[4] = CV_IMAGE_ELEM( src, uchar, i,   j+1);    
  21.             neighborhood[3] = CV_IMAGE_ELEM( src, uchar, i+1, j+1);    
  22.             neighborhood[2] = CV_IMAGE_ELEM( src, uchar, i+1, j);    
  23.             neighborhood[1] = CV_IMAGE_ELEM( src, uchar, i+1, j-1);    
  24.             neighborhood[0] = CV_IMAGE_ELEM( src, uchar, i,   j-1);    
  25.   
  26.             uchar center = CV_IMAGE_ELEM( src, uchar, i, j);    
  27.             uchar temp=0;    
  28.     
  29.             for(int k=0;k<8;k++){    
  30.                 temp+=(neighborhood[k]>center)*(1<<k);    
  31.             }     
  32.             CV_IMAGE_ELEM( dst, uchar, i, j)=table[temp];    
  33.         }    
  34.     }    
  35. }  
其中函數代碼:

 

  1. int getHopCount(uchar i){    
  2.     int a[8]={0};    
  3.     int k=7;    
  4.     int cnt=0;    
  5.     while(i){    
  6.         a[k]=i&1;    
  7.         i>>=1;    
  8.         --k;    
  9.     }    
  10.     for(int k=0;k<8;++k){    
  11.         if(a[k]!=a[k+1==8?0:k+1]) {    
  12.             ++cnt;    
  13.         }    
  14.     }    
  15.     return cnt;    
  16. }    
輸出結果

 

其中對應處理後,圖像像素值的分佈圖,如下所示:


參考資料

[1] T. Ojala, M. Pietikäinen, and D. Harwood (1994), "Performance evaluation of texture measures with classification based on Kullback discrimination of distributions", Proceedings of the 12th IAPR International Conference on Pattern Recognition (ICPR 1994), vol. 1, pp. 582 - 585.

[2] T. Ojala, M. Pietikäinen, and D. Harwood (1996), "A Comparative Study of Texture Measures with Classification Based on Feature Distributions", Pattern Recognition, vol. 29, pp. 51-59.

[3] Local Binary Pattern From Wikipedia, the free encyclopedia.

[4] Local Binary Pattern (LBP)methodology in Scholarpedia.

[5] Face Recognition With OpenCV.

發佈了150 篇原創文章 · 獲贊 197 · 訪問量 97萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章