将对象掩码应用于LBP计算

时间:2018-01-24 01:13:54

标签: python opencv image-processing feature-extraction lbph-algorithm

我看到很多文章都将lbp应用于基于纹理的图像分类。我只是想知道有关这项技术的三件事,我无法从谷歌找到明确的答案:

  1. 算法如何为图像的边界像素计算lbp,而这些像素周围没有足够的邻居像素。

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

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

  4. 谢谢。

1 个答案:

答案 0 :(得分:0)

  1. 边框像素通常被丢弃(看看首先提出LBP的研究小组开发的Matlab implementation)。在其他实现中(参见例如Python的scikit-learn),虽然添加了黑色边框。

  2. P像素的局部邻域导致2 P -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)
    
  4. 修改

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

    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)
    

    Results