5

我正在使用local_binary_patternscikit-image 包中的函数。我想计算半径 1 内 8 个邻居的旋转不变均匀 LBP。这是我的 Python 代码:

import numpy as np
from skimage.feature import local_binary_pattern

image = np.array([[150, 137, 137, 146, 146, 148],
                  [145, 144, 144, 144, 142, 144],
                  [149, 144, 144, 143, 153, 147],
                  [145, 144, 147, 150, 145, 150],
                  [146, 146, 139, 148, 144, 148],
                  [129, 139, 142, 150, 146, 140]]).astype(np.uint8)

lbp = local_binary_pattern(image, 8, 1, "uniform")

print("image =")
print(image)
print("lbp =")
print(lbp)

这是输出

image =
[[150 137 137 146 146 148]
 [145 144 144 144 142 144]
 [149 144 144 143 153 147]
 [145 144 147 150 145 150]
 [146 146 139 148 144 148]
 [129 139 142 150 146 140]]
lbp =
[[ 0.  5.  5.  1.  9.  0.]
 [ 9.  6.  9.  9.  8.  9.]
 [ 0.  8.  6.  8.  0.  3.]
 [ 9.  7.  1.  0.  7.  0.]
 [ 1.  1.  8.  9.  7.  1.]
 [ 3.  4.  9.  0.  2.  3.]]

让我感到困惑的是,一些相同的值lbp并不对应于相同的统一模式。例如lbp[1, 1]lbp[2, 2]都是6,但 LBPimage[1, 1]是:

1 0 0
1 x 1
1 1 1

的 LBPimage[2, 2]为:

1 1 1
1 x 0
1 1 1

根据 中的值lbp,我假设该local_binary_pattern函数使用“大于或等于”与邻居进行比较。

image[1, 1]和的 LBPimage[2, 2]都是一致的。但是如何能够image[1, 1]image[2, 2]具有相同的 LBP 值呢?

4

2 回答 2

4

为了提高对 LBP 描述符旋转的鲁棒性,方形邻域被圆形邻域所取代。在由八个像素形成的圆形邻域中,对角线上的四个邻域与像素中心不重合。这些邻居的强度值通常通过双线性插值计算。下图以图形方式解释了为什么在您的示例图像中,一些 LBP 3×3模式与 LBP 8,1模式不同。

方形和圆形街区

代码

w_cen  =  (1-1/np.sqrt(2))**2  # Weights
w_diag  =  (1/np.sqrt(2))**2
w_orto  =  (1-1/np.sqrt(2))*(1/np.sqrt(2))

def bilinear_interpoplation(i_cen, i_diag, i_hor, i_ver):
    return i_cen*w_cen + i_diag*w_diag + i_hor*w_orto + i_ver*w_orto

def circular_neighbourhood(x):
    [I7, I6, I5] = x[0, :]
    [I0, Ic, I4] = x[1, :]
    [I1, I2, I3] = x[2, :]
    I7i = bilinear_interpolation(Ic, I7, I0, I6)
    I5i = bilinear_interpolation(Ic, I5, I4, I6)
    I3i = bilinear_interpolation(Ic, I3, I4, I2)
    I1i = bilinear_interpolation(Ic, I1, I0, I2)
    interpolated = np.array([[I7i, I6, I5i], 
                             [ I0, Ic,  I4], 
                             [I1i, I2, I3i]])
    return interpolated

def binary_pattern(x):
    return np.where(x >= x[1, 1], 1, 0)

def display_lbps(patch):
    interpolated = circular_neighbourhood(patch)
    print('Patch =')
    print(patch)
    print('LBP of patch =')
    print(binary_pattern(patch))
    print('Interpolated patch =')
    print(interpolated)
    print('LBP of interpolated patch =')
    print(binary_pattern(interpolated))

display_lbps(image[0:3, 0:3])
display_lbps(image[1:4, 1:4])
于 2017-07-01T22:55:23.280 回答
3

旋转不变的 LBP 不直接使用邻居的像素值,而是在圆上插值(用于旋转不变性)。见https://github.com/scikit-image/scikit-image/blob/master/skimage/feature/_texture.pyx#L156

另请参阅原始 LBP 论文http://vision.stanford.edu/teaching/cs231b_spring1415/papers/lbp.pdf,其中提到“通过插值估计不完全落在像素中心的邻居的灰度值”。

于 2016-08-18T11:32:51.547 回答