根据邻居值查找元素

时间:2016-09-26 17:09:44

标签: python arrays numpy edge-detection

我想知道是否有一种有效的方法来查找Numpy数组中特定值旁边的元素索引。

如何在此数组A中找到所有等于1且在0旁边的元素的索引?没有循环检查每个元素的8个包围元素的值?

       A = [[ 0.,  0.,  0.,  0.,  0.,  0.],
           [ 0.,  1.,  1.,  1.,  1.,  0.],
           [ 0.,  1.,  1.,  1.,  1.,  0.],
           [ 0.,  1.,  1.,  1.,  1.,  0.],
           [ 0.,  1.,  1.,  1.,  1.,  0.],
           [ 0.,  0.,  0.,  0.,  0.,  0.]]

我希望从这样的结果中获取索引:

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

我使用了精确边缘检测,但它并不总是适用于在北/西南或北/东东邻居只有一个0的元素。例如:

           B = [[ 1.,  0.,  0.],
               [ 1.,  0.,  0.],
               [ 1.,  1.,  1.]]

可以导致

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

而不是

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

由于

更新1:我确实尝试了第一个canny边缘检测形式scikit.image,但它错过了元素。然后我用np.gradient尝试了相同的结果。

更新2:示例:

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

在这个例子中,canny边缘检测,渐变方法和ndimage.laplace(下面的答案中提到的方法)导致相同的结果,缺少元素(图中为黄色) results

更新2:

这是循环方法

def check_8neigh_Value(arr,eltvalue, neighvalue):
   "checking if the element of value=eltvalue is surrounded 
    by the value=neighvalue and returning the corresponding grid"

   l, c = np.shape(arr)
   contour = np.zeros(np.shape(arr))
   for i in np.arange(1,l-1):
      for j in np.arange(1,c-1):
         window = arr[i-1:i+2, j-1:j+2]
         if np.logical_and(arr[i,j]==eltvalue,neighvalue in window):
            contour[i,j]=1

return contour

image=check_8neigh_Value(B,1,0)

它给了我正在寻找的东西,但它在大阵列上效率不高。

我坚持使用as_strided方法,因为我不知道如何使用结果:

对于使用数组B的3乘3窗口,我可以获得as_stried B但无法进一步。

window_h=3
window_w=3
l, c = image.shape
l_new, c_new = l - window_h + 1, c - window_w + 1
shape=[c_new, l_new, window_w, window_h]
strides=B.strides + B.strides
strided_image = np.lib.stride_tricks.as_strided(B,shape=shape,strides=strides)

1 个答案:

答案 0 :(得分:2)

这是使用二元侵蚀的一种方法:

import numpy as np
from scipy import ndimage

eroded = ndimage.binary_erosion(A, np.eye(3))
diff = (A - eroded).astype(np.bool)
print(repr(diff))
# array([[False, False, False, False, False, False],
#        [False,  True,  True,  True,  True, False],
#        [False,  True, False, False,  True, False],
#        [False,  True, False, False,  True, False],
#        [False,  True,  True,  True,  True, False],
#        [False, False, False, False, False, False]], dtype=bool)

您还可以使用输入数组的拉普拉斯算子并找到它的负数:

lap = ndimage.laplace(A)
print(repr(lap < 0))
# array([[False, False, False, False, False, False],
#        [False,  True,  True,  True,  True, False],
#        [False,  True, False, False,  True, False],
#        [False,  True, False, False,  True, False],
#        [False,  True,  True,  True,  True, False],
#        [False, False, False, False, False, False]], dtype=bool)