将对象掩码应用于 LBP 计算

Apply object mask to LBP calculation

我看到很多文章将 lbp 应用于基于纹理的图像分类。我只是想知道关于这项技术的三件事,我无法从 Google:

中找到明确的答案
  1. 算法如何计算周围没有足够相邻像素的图像边界像素的 lbp。

  2. 如果我们有八个相邻像素,那么中心像素将有 256 个图案(如果使用 uniform 则为 59 个)。但是如果我们增加相邻像素的大小(例如 8 或 10),那么图案的数量也会增加,对吗?在那种情况下,它如何影响直方图计算?

  3. 如何只计算对象的lbp。特别是,如果我们想比较图像中的物体,我们只需要计算物体的 lbp 和直方图。我已经尝试通过使用 opencv 直方图(它支持掩码和 numpy 直方图不支持掩码)到 lbp 输出来实现这个想法,但它没有用。关于如何基于掩码过滤 lbp 数组的任何想法,然后我们可以找到直方图。

谢谢。

  1. 边框像素通常会被丢弃(查看 Matlab implementation developed by the research group that first proposed LBP). In other implementations (see for example Python's scikit-learn),但会添加黑色边框。

  2. P 像素的局部邻域产生 2P-bin 直方图。如果设置 P=10,那么特征向量将有 1024 个分量。

  3. 这个玩具示例向您展示了如何从 LBP 直方图计算中过滤掉不需要的图像区域:

    import numpy as np
    from skimage.feature.texture import local_binary_pattern
    
    P, R = 8, 1
    dim = 2**P
    img = np.asarray([[5, 5, 5, 5], [5, 99, 100, 5], [5, 5, 5, 5]]], dtype=np.uint8)
    mask = img > 5
    codes = local_binary_pattern(img, P, R)
    hist, _ = np.histogram(codes[mask], bins=np.arange(dim+1), range=(0, dim))
    

    演示

    In [97]: img
    Out[97]: 
    array([[  5,   5,   5,   5],
           [  5,  99, 100,   5],
           [  5,   5,   5,   5]], dtype=uint8)
    
    In [98]: codes
    Out[98]: 
    array([[ 193.,  241.,  241.,  112.],
           [ 199.,    1.,    0.,  124.],
           [   7.,   31.,   31.,   28.]])
    
    In [99]: mask
    Out[99]: 
    array([[False, False, False, False],
           [False,  True,  True, False],
           [False, False, False, False]], dtype=bool)
    
    In [100]: hist
    Out[100]: 
    array([1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
           0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
           0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
           0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
           0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
           0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
           0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
           0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
           0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
           0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
           0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
           0, 0, 0], dtype=int32)
    

编辑

这是一个更真实的例子,正如您在评论中所要求的那样:

import numpy as np
from skimage import io
from skimage.feature.texture import local_binary_pattern
import matplotlib.pyplot as plt

P = 8
R = 1
dim = 2**P
h_bins = np.arange(dim+1)
h_range = (0, dim)

img = io.imread('https://i.stack.imgur.com/6ESoP.png')
mask = (img > 0)
codes = local_binary_pattern(img, P, R)
h_img, _ = np.histogram(codes.ravel(), bins=h_bins, range=h_range)
h_masked, _ = np.histogram(codes[mask], bins=h_bins, range=h_range)
h_img = h_img/h_img.sum(dtype=np.float)
h_masked = h_masked/h_masked.sum(dtype=np.float)

f, [[ax0, ax1], [ax2, ax3]] = plt.subplots(2, 2)
ax0.imshow(img, cmap=plt.cm.gray)
ax0.axis('off')
ax0.set_title('Image')
ax1.imshow(mask, cmap=plt.cm.gray)
ax1.axis('off')
ax1.set_title('Mask')
ax2.plot(h_img)
ax2.set_title('LBP of image')
ax3.plot(h_masked)
ax3.set_title('LBP of ROI')
plt.show(f)