【问题标题】:Identify the interior of a boolean array / blob - NumPy / Python识别布尔数组/blob的内部 - NumPy / Python
【发布时间】:2019-08-09 08:42:28
【问题描述】:

假设我有一个形状为 (nrows,ncols) 的布尔数组。 True 表示我有一个定义的值(实数),而 False 表示一个未定义的/(不感兴趣的)值。

我试图找出一种有效的方法来提取边界和内部的行和列,例如,如果我有一个流动的布尔数组,我用红色标记边界,用绿色标记内部:

那么所需的输出将是(绿色 True 的位置):

内部 = [(2,3), (2,4)]

我们可以假设内部总是相连的。

使用 np.where(array == False)[0],我得到了 False 的索引,但是如何从这里到边界索引,然后到内部?我当然可以遍历每个布尔值并检查是否有任何邻居是 False,如果不是,那么它是内部的。

关于如何在不循环的情况下有效地执行此操作的任何提示?另一个要清楚的例子:

期望的输出: 内部 = [(2,3) , (2,4) , (3,3) , (3,4) , (3,5) , (4,3), (4,4), (4 ,5)]

输出也可以是一个布尔数组,在内部位置包含 True,否则为 False。不要紧。提前致谢。

【问题讨论】:

    标签: python python-3.x numpy image-processing


    【解决方案1】:

    方法#1

    我们可以使用2D convolution -

    from scipy.signal import convolve2d
    
    def interior_indices(a):
        kernel = np.ones((3,3),dtype=int)
        return np.argwhere(convolve2d(a,kernel,'same')==9)
    

    示例运行 -

    In [44]: a1
    Out[44]: 
    array([[False, False, False, False, False, False, False, False],
           [ True,  True,  True,  True,  True,  True, False, False],
           [False,  True,  True,  True,  True,  True,  True, False],
           [False, False,  True,  True,  True,  True, False, False]])
    
    In [45]: interior_indices(a1)
    Out[45]: 
    array([[2, 3],
           [2, 4]])
    
    In [46]: a2
    Out[46]: 
    array([[False, False, False, False, False, False, False, False],
           [False,  True,  True,  True,  True,  True, False, False],
           [False,  True,  True,  True,  True,  True,  True, False],
           [False, False,  True,  True,  True,  True,  True, False],
           [False, False,  True,  True,  True,  True,  True, False],
           [False,  True,  True,  True,  True,  True,  True, False],
           [False, False, False,  True,  True, False, False, False]])
    
    In [47]: interior_indices(a2)
    Out[47]: 
    array([[2, 3],
           [2, 4],
           [3, 3],
           [3, 4],
           [3, 5],
           [4, 3],
           [4, 4],
           [4, 5]])
    

    方法 #2

    或者,uniform-filter -

    In [61]: from scipy.ndimage import uniform_filter
    
    In [62]: np.argwhere(uniform_filter(a1,mode='constant'))
    Out[62]: 
    array([[2, 3],
           [2, 4]])
    
    In [63]: np.argwhere(uniform_filter(a2,mode='constant'))
    Out[63]: 
    array([[2, 3],
           [2, 4],
           [3, 3],
           [3, 4],
           [3, 5],
           [4, 3],
           [4, 4],
           [4, 5]])
    

    方法#3

    还有binary-erosion -

    In [72]: from scipy.ndimage.morphology import binary_erosion
    
    In [73]: kernel = np.ones((3,3),dtype=bool)
    
    In [74]: np.argwhere(binary_erosion(a1,kernel))
    Out[74]: 
    array([[2, 3],
           [2, 4]])
    
    In [75]: np.argwhere(binary_erosion(a2,kernel))
    Out[75]: 
    array([[2, 3],
           [2, 4],
           [3, 3],
           [3, 4],
           [3, 5],
           [4, 3],
           [4, 4],
           [4, 5]])
    

    【讨论】:

    • 这对我来说很神奇 :) 我想这比我的要快得多,因为您在计算过程中不存储 8 个矩阵?
    【解决方案2】:

    找到方法了!如果它太琐碎,投票删除:)

        #data: the boolean array
    
        d0 = data[1:-1, 2:]
        d1 = data[:-2, 2:]
        d2 = data[:-2, 1:-1]
        d3 = data[:-2, :-2]
        d4 = data[1:-1, :-2]
        d5 = data[2:, :-2]
        d6 = data[2:, 1:-1]
        d7 = data[2:, 2:]
    
    
        interior = np.where(d0 & d1 & d2 & d3 & d4 & d5 & d6 & d7, True, False)
    

    【讨论】:

      猜你喜欢
      • 2013-08-07
      • 1970-01-01
      • 2016-12-08
      • 2016-03-11
      • 2011-04-12
      • 2018-05-20
      • 2016-08-22
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多