提取二维二进制数组的索引

Extract indices of a 2D binary array

我有一个由 0 和 1 组成的 numpy 数组(数据)。

import numpy as np

data = np.array([[1, 1, 1, 1, 1, 1],
                 [1, 1, 1, 1, 1, 0],
                 [1, 1, **1**, 1, 1, 0],
                 [1, 1, 1, 1, 1, 1],
                 [1, 1, 1, 1, 1, 0],
                 [1, 1, 1, 1, 1, 1]])

我想提取其中“1”被由 1 组成的相邻 5*5 元素包围的索引。

预期索引用星号表示,即 (3,3)。 布尔数组形式的答案也可以。

[[False False False False False False]
 [False False False False False False]
 [False False **True** False False False]
 [False False False False False False]
 [False False False False False False]
 [False False False False False False]]

我试过

from scipy.ndimage.morphology import binary_erosion


kernel = np.ones((5,5))

result = binary_erosion(data, kernel)
print result

[[False False False False False False]
 [False False False False False False]
 [False False  True False False False]
 [False False  True False False False]
 [False False False False False False]
 [False False False False False False]]

它产生了两个 'True' 个位置,但我只想要一个 (3,3)。

怎么做?

编辑:链接问题中显示的解决方案也给出了意想不到的答案。

替代 binary_erosion,您可以使用 scipy.ndimage.generic_filter 来实现此目的,

from scipy.ndimage import generic_filter
generic_filter(data, np.all, size=(5,5), mode='constant', cval=0).astype(np.bool)

但是你会得到与上面相同的结果,

array([[0, 0, 0, 0, 0, 0],
       [0, 0, 0, 0, 0, 0],
       [0, 0, 1, 0, 0, 0],
       [0, 0, 1, 0, 0, 0],
       [0, 0, 0, 0, 0, 0],
       [0, 0, 0, 0, 0, 0]])  # using 1, 0 instead of True, False for readability

因为这是您问题的正确答案。示例矩阵中的 6 行是对称的,对于给定的内核,结果中会有 2 个对称的 True 元素。

如果您想避免这种情况,您可以使用非对称内核大小:size=(6,5),尽管这会在第 3 行而不是第 2 行中产生一个真元素。这可以通过手动填充 kernel 使用 binary_erosion 时为零的数组。

另一种类似于@rth

的方法

由于您的数据由 10 组成,您可以将其放在 int 数组中并使用 uniform_filter 来实现相同的目的:

>>> mask = uniform_filter(data, 5, mode='constant')
>>> mask
array([[0, 0, 0, 0, 0, 0],
       [0, 0, 0, 0, 0, 0],
       [0, 0, 1, 0, 0, 0],
       [0, 0, 1, 0, 0, 0],
       [0, 0, 0, 0, 0, 0],
       [0, 0, 0, 0, 0, 0]])

不被个包围的均值小于1,因为是整型数组,四舍五入为0

要获取第一个索引,您可以执行以下操作:

>>> y, x = np.where(mask)
>>> y[0], x[0]
(2, 2)