【问题标题】:Apply object mask to LBP calculation将对象掩码应用于 LBP 计算
【发布时间】:2018-07-02 23:05:38
【问题描述】:

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

  1. 算法如何为周围没有足够相邻像素的图像的边界像素计算 lbp。

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

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

谢谢。

【问题讨论】:

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


    【解决方案1】:
    1. 通常会丢弃边框像素(请查看由最先提出 LBP 的研究小组开发的 Matlab implementation)。在其他实现中(例如,参见 Python 的 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)
      

    编辑

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

    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)
    

    【讨论】:

    • 你好 Tonechas。感谢您的明确答复。在第 3 部分中,演示中的掩码是布尔类型,而实际上,我们从图像创建的对象掩码是整数。它们之间有什么大的区别吗?我的意思是,在放入 numpy histogram 函数之前,我是否必须将对象掩码转换为 boonlean 值?
    • 如果可能的话,你有没有类似的真实图像演示。非常感谢 Tonechas。
    • 掩码值可以是整数或布尔值
    • 非常感谢 Tonechas。
    猜你喜欢
    • 2015-03-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-06-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多