2015-04-08 34 views
1

我有一个NumPy的阵列仅由0和1的元素如下:提取索引

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所包围的元件1的索引在每个方向上2个像素。

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

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

回答

2

这是很容易与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)) 
3

你可以使用一些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) 
+0

感谢您的尝试。我有upvoted。不过,我正在考虑使用scipy.ndimage来做这件事。你能否提出一种替代方法? –

+0

like maximum_filter,minimum_filter? –

+1

@EricBal我不认为max或min过滤器可以在这里工作,但那些过滤器会在该窗口内寻找最大值。我们想要的是该窗口中的所有元素都是“ones”。所以我们需要的是在该窗口内的所有元素的总和,所以卷积适合这里。 – Divakar