LBP特徵及其變體和python實現

一. LBP特徵

        LBP(Local Binary Pattern),局部二值模式,主要用於提取紋理特徵,根據文獻[1]我們可以瞭解到LBP及其變體。一般的使用方法是,先將圖像轉換爲灰度圖,接着計算LBP特徵圖,最後計算其直方圖作爲特徵向量。
0.如何描述紋理信息
        不多說,看圖。LBP特徵可以表示平坦、邊緣、角點等區域。


1.original LBP

        最經典的LBP特徵,對於某像素的8-鄰域,大於該像素值的置1,小於該像素值的置0,最後組成八位二進制碼。


2.採樣方式及角空間
        圓形鄰域的像素採樣方式會比8-鄰域的方式要更靈活,可以通過改變圓形的半徑R來調整鄰域大小。但半徑R越大,採樣點的數目P也越多。對於沒有落到像素格子中央的點的灰度值,一般採用插值法得到。
      除此之外,通過對採樣角度設置更高的量化等級,可以得到更精細的角度分辨率。

3.灰度不變性
        由於各鄰域像素的灰度值需要減去中心像素的灰度值,可以實現針對平均光源的灰度不變性。
4.旋轉不變性
        由於編碼的起始點是一定的,每一種二值編碼模式經旋轉(循環位移)後會產生不同的編碼結果。爲了形成旋轉不變的編碼模式,我們讓有同一編碼模式經旋轉後產生的編碼結果編碼爲同一值,定義二值編碼爲這些旋轉結果中的最小值。
        在具體代碼實現時,通過使用計算映射(mapping)的方式來將不同的旋轉二值編碼映射爲旋轉不變的二值編碼。
5.uniform LBP
        首先,我們將LBP的二值編碼看作是頭尾相接的,接着定義計數U爲二值編碼中0-1變化的次數(即0變成1,或者1變成0,記做一次),公式表達如下:

        對於U值小於等於2的二值編碼,我們定義其爲uniform pattern,例如半徑爲1,採樣點爲8的LBP特徵有如下8種uniform pattern:
 

        而對於其它的非uniform編碼,我們將其歸爲一類。之所以這樣定義,是因爲這類編碼易受噪聲影響,變化頻率非常大。

        最終的uniform LBP計算公式如下:


        總結一下,對於8個採樣點的LBP,灰度不變LBP有256種編碼輸出,旋轉不變LBP有36種編碼輸出,而uniform旋轉不變LBP只有9種編碼輸出(8種uniform編碼和剩餘的非uniform編碼),非旋轉不變的uniform LBP有58種輸出。

6.結合對比度的LBP
        根據灰度不變LBP的定義,我們直接捨棄了像素點間的灰度幅值差異,進而丟失了對比度的信息(即灰度值的方差)。因此,我們考慮結合對比度Var和LBP作爲聯合特徵. 對比度計算公式如下:

二. Python實現

        在研究了網上LBP的代碼實現後,我認爲使用ski-image包的LBP特徵提取函數比較好,因爲它封裝了多種LBP的方法,非常簡單易用。官網上的參考文檔如下:

Parameters:

image : (N, M) array

Graylevel image.

P : int

Number of circularly symmetric neighbour set points (quantization ofthe angular space).

R : float

Radius of circle (spatial resolution of the operator).

method : {‘default’, ‘ror’, ‘uniform’, ‘var’}

Method to determine the pattern.

  • ‘default’: original local binary pattern which is gray scale but not rotation invariant.
  • ‘ror’: extension of default implementation which is gray scale and rotation invariant.
  • ‘uniform’: improved rotation invariance with uniform patterns and finer quantization of the angular space which is gray scale androtation invariant.
  • ‘nri_uniform’: non rotation-invariant uniform patterns variant which is only gray scale invariant.
  • ‘var’: rotation invariant variance measures of the contrast of localimage texture which is rotation but not gray scale invariant.
Returns:

output : (N, M) array

LBP image.

代碼例程:
# settings for LBP
radius = 2
n_points = 8 * radius


def kullback_leibler_divergence(p, q):
    p = np.asarray(p)
    q = np.asarray(q)
    filt = np.logical_and(p != 0, q != 0)
    return np.sum(p[filt] * np.log2(p[filt] / q[filt]))


def match(refs, img):
    best_score = 10
    best_name = None
    lbp = local_binary_pattern(img, n_points, radius, METHOD)
    n_bins = int(lbp.max() + 1)
    hist, _ = np.histogram(lbp, normed=True, bins=n_bins, range=(0, n_bins))
    for name, ref in refs.items():
        ref_hist, _ = np.histogram(ref, normed=True, bins=n_bins,
                                   range=(0, n_bins))
        score = kullback_leibler_divergence(hist, ref_hist)
        if score < best_score:
            best_score = score
            best_name = name
    return best_name


brick = data.load('brick.png')
grass = data.load('grass.png')
wall = data.load('rough-wall.png')

refs = {
    'brick': local_binary_pattern(brick, n_points, radius, METHOD),
    'grass': local_binary_pattern(grass, n_points, radius, METHOD),
    'wall': local_binary_pattern(wall, n_points, radius, METHOD)
}

# classify rotated textures
print('Rotated images matched against references using LBP:')
print('original: brick, rotated: 30deg, match result: ',
      match(refs, rotate(brick, angle=30, resize=False)))
print('original: brick, rotated: 70deg, match result: ',
      match(refs, rotate(brick, angle=70, resize=False)))
print('original: grass, rotated: 145deg, match result: ',
      match(refs, rotate(grass, angle=145, resize=False)))

# plot histograms of LBP of textures
fig, ((ax1, ax2, ax3), (ax4, ax5, ax6)) = plt.subplots(nrows=2, ncols=3,
                                                       figsize=(9, 6))
plt.gray()

ax1.imshow(brick)
ax1.axis('off')
hist(ax4, refs['brick'])
ax4.set_ylabel('Percentage')

ax2.imshow(grass)
ax2.axis('off')
hist(ax5, refs['grass'])
ax5.set_xlabel('Uniform LBP values')

ax3.imshow(wall)
ax3.axis('off')
hist(ax6, refs['wall'])

plt.show()
結果如下:

網站參考:

doc文檔

官方例程

參考文獻:
[1] Ojala T, Pietikäinen M, Mäenpää T. Multiresolution Gray-Scale and Rotation Invariant Texture Classification with Local Binary Patterns[C]// European Conference on Computer Vision. Springer-Verlag, 2000:404-420.
[2] Walt S V D, Schönberger J L, Nuneziglesias J, et al. scikit-image: image processing in Python[J]. Peerj, 2014, 2(2):e453.
    
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章