提取2D二进制数组的索引

时间:2015-06-21 12:15:58

标签: python numpy scipy scikit-learn scikit-image

我有一个由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'周围是由1s组成的相邻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]]

它产生了两个真实的'我只想要一个位置(3,3)。

怎么做?

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

2 个答案:

答案 0 :(得分:2)

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行。这可以修复,手动填充{{1使用kernel时使用零的数组。

答案 1 :(得分:1)

另一种类似于@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包围的平均值小于1并且舍入为0,因为它是整数数组。

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

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