2016-09-26 1 views
2

Je voudrais savoir s'il existe un moyen efficace de trouver des index d'éléments à côté d'une valeur spécifique dans un tableau Numpy.Recherche d'éléments basés sur des valeurs voisines

Comment puis-je trouver des index de tous les éléments qui sont égaux à 1 et qui sont à côté d'un 0 dans ce tableau A? Sans une boucle vérifiant la valeur des 8 éléments entourés pour chaque élément?

 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.]] 

j'attendre d'obtenir les indices d'un résultat comme celui-ci:

   [[ 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]] 

je détection de Canny, mais il ne fonctionne pas toujours pour les éléments qui ont seulement un 0 sur le Nord/Sud Voisin ouest ou nord/sud-est. Par exemple:

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

peut conduire à

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

au lieu de

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

Merci

mise à jour 1: J'ai essayé la première forme de détection Canny scikit.image mais manque des éléments. J'ai ensuite essayé avec np.gradient avec les mêmes résultats.

mise à jour 2: Exemple:

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]]) 

Dans cet exemple, la détection de bord de Canny, la méthode du gradient, et la ndimage.laplace (méthode mentionnée dans la réponse ci-dessous) conduisent aux mêmes résultats, avec éléments manquants (en jaune sur la figure) results

mise à jour 2:

Voici la méthode de mise en boucle

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) 

Il me donne ce que je cherche, mais il n'est pas efficace sur grand tableau.

Je suis coincé avec la méthode as_strided, puisque je ne suis pas faible comment utiliser le résultat:

Pour 3 par 3 fenêtre à l'aide du tableau B, je suis en mesure d'obtenir le as_stried B mais peut » t aller plus loin.

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) 
+0

Avez-vous essayé quelque chose ou sont vous cherchez juste des réponses? – depperm

+0

cochez ce site pour les références aux fonctions de glissement 'glissant', 'mobile' ou 'roulant' utilisées dans le code. C'est une zone relativement bien documentée. Dans votre cas, la somme de huit voisins serait un bon début – NaN

+0

Merci pour l'info NaN, y a-t-il un lien vers le site que vous avez mentionné? – egayer

Répondre

2

est ici une approche par l'érosion binaire:

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) 

Vous pouvez aussi prendre le Laplacien de votre tableau d'entrée et de trouver où il est négatif:

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) 
+0

Une idée intelligente avec l'érosion!Pour une amélioration des performances, je pense que nous pouvons nous en tenir à des tableaux booléens et faire quelque chose comme: 'A.astype (bool) & ~ eroded'. – Divakar

+0

Merci pour vos réponses les gars, mais malheureusement, cette méthode ne fournit pas ce que je cherche. J'ai mis à jour ma question ci-dessus avec un nouvel exemple – egayer