提取 NumPy 数组的索引

Extract indices of a NumPy array

我有一个仅包含 0 和 1 元素的 NumPy 数组,如下所示:

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

我必须找出元素 1 的索引,它在每个方向上被 2 x 2 像素中的 1 包围。

预期答案的位置以粗体显示。

我正在寻找更简单快捷的方法。

你可以使用一些 signal processing -

import numpy as np
from scipy import signal

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

# Extent of the search           
extent = 2;

# Kernel to be used with 2D convolution                 
kernel = np.ones((2*extent+1,2*extent+1))

# Perform 2D convolution with input data and kernel 
filt_out = signal.convolve2d(data, kernel, boundary='symm', mode='same')

# Find where the convolution resulted in a perfect score, 
# i.e is equal to the number of elements in kernel
R,C = np.where( filt_out == kernel.size )

输出-

In [66]: print(R,C)
[3] [4]

本节中列出的是另一种方法,ndimage 执行与先前方法相同的卷积,其余步骤保持相同。这是获取卷积输出的代码 filt_out -

import scipy.ndimage
filt_out = scipy.ndimage.convolve(data,kernel)

这很容易 basic morphological operation:

import numpy as np
from scipy.ndimage.morphology import binary_erosion


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

expected = np.array([[0, 0 , 0 , 0 , 0 , 0 , 0 , 0],
                     [0, 0 , 0 , 0 , 0 , 0 , 0 , 0],
                     [0, 0 , 0 , 0 , 0 , 0 , 0 , 0],
                     [0, 0 , 0 , 0 , 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]])

# otherwise known as np.ones((5, 5))
structuring_element = np.array([[1, 1, 1, 1, 1],
                                [1, 1, 1, 1, 1],
                                [1, 1, 1, 1, 1],
                                [1, 1, 1, 1, 1],
                                [1, 1, 1, 1, 1]])

# will be of dtype np.bool but you can convert with .astype(np.int)
# if you really need
result = binary_erosion(data, structuring_element)

print(result)

print(np.allclose(result, expected))