2017-06-26 5 views
0

J'essaie de créer une matrice gaussienne floue. Je modifie le code de http://www.labri.fr/perso/nrougier/teaching/numpy/numpy.htmlVectorisation avec numpy

dev_data a des rangées de fonctionnalités de 784 pixels, et je voudrais flouter avec les voisins autour du pixel en question avec le pixel lui-même. Lorsque nous sommes sur les bords extérieurs (lignes 1, -1, colonnes 1, -1), ignorez les voisins hors limites. Je ne suis pas sûr de savoir comment faire ce rejet.

code:

# Initialize a new feature array with the same shape as the original data. 
blurred_dev_data = np.zeros(dev_data.shape) 

#we will reshape the 784 feature-long rows into 28x28 matrices 
for i in range(dev_data.shape[0]): 
    reshaped_dev_data = np.reshape(dev_data[i], (28,28)) 
    #the purpose of the reshape is to use the average of the 8 pixels + the pixel itself to blur 
    for idx, pixel in enumerate(reshaped_dev_data): 
     pixel = np.mean(reshaped_dev_data[idx-1:idx-1,idx-1:idx-1] + reshaped_dev_data[idx-1:idx-1,idx:idx] + reshaped_dev_data[idx-1:idx-1,idx+1:] + 
      reshaped_dev_data[idx:idx,idx-1:idx-1] + reshaped_dev_data[idx:idx,idx:idx] + reshaped_dev_data[idx:idx,idx+1:] + 
      reshaped_dev_data[idx+1: ,idx-1:idx-1] + reshaped_dev_data[idx+1: ,idx:idx] + reshaped_dev_data[idx+1: ,idx+1:]) 
    blurred_dev_data[i,:] = reshaped_dev_data.ravel() 

Je reçois une erreur avec l'index:

ValueError: operands could not be broadcast together with shapes (0,0) (0,27) 

Ce n'est pas un IndexError, donc je ne suis pas tout à fait sûr de ce que je fais mal ici/comment répare le.

+0

Editez 'reshaped_dev_data [idx-1: idx-1, idx-1: idx-1]' à 'reshaped_dev_data [idx-1, idx-1]' et ainsi de suite. – Divakar

+0

merci. maintenant je reçois l'erreur hors limites que je m'attendais. Connaissez-vous un bon moyen d'ignorer les indices hors limites? –

+0

Je suggère plutôt d'utiliser un filtre de flou guassien plutôt - https://docs.scipy.org/doc/scipy-0.14.0/reference/generated/scipy.ndimage.filters.gaussian_filter.html – Divakar

Répondre

1

Essayez ceci:

pixel = np.mean(reshaped_dev_data[idx-1:idx+1, idx-1:idx+1]) 

En outre, lire sur slicing.


Alors j'ai plus à votre code, et vous faites quelques choses mal:

  • Ce n'est pas un noyau gaussien.
  • Recalculer reshaped_dev_data plusieurs fois dans une boucle.
  • En boucle sur les mauvaises choses.
  • Essayer de muter pixel en ligne 9. Ceci est mauvais car:
    • Mutation de l'objet que vous bouclez est généralement mauvais
    • Ce ne sera pas muter de toute façon! pixel est comme un détenteur de "valeur". Le changer ne change pas le tableau que vous bouclez.
  • N'écrit pas de code vectorisé!

est ici une façon naïve, non vectorisée de le faire:

def conv(arr, i, j): 
    return np.mean(arr[i-1:i+1, j-1:j+1]) 

blurred_dev_data = np.zeros_like(dev_data) 
reshaped_dev_data = dev_data.reshape(28, 28) 

for i, row in enumerate(reshaped_dev_data): 
    for j, pixel in enumerate(row): 
     blurred_dev_data[i, j] = conv(reshaped_dev_data, i, j) 

Notez que nous faisons une convolution. Nous pouvons donc simplement utiliser les bibliothèques intégrées pour effectuer une convolution sur le noyau de calcul de la moyenne.


En ce qui concerne vos commentaires,

def conv(arr, i, j): 
    # Ensure the boundaries are not exceeded 
    a = max(i-1, 0) 
    b = min(i+1, 28) 
    c = min(j-1, 0) 
    d = max(i+1, 28) 

    return np.mean(arr[a:b, c:d]) 

blurred_dev_data = np.zeros_like(dev_data) 

for n, data in enumerate(dev_data): 
    reshaped = data.reshape(28, 28) 
    blurred = np.zeros_like(reshaped) 

    for i, row in enumerate(reshaped): 
     for j, pixel in enumerate(row): 
      blurred[i, j] = conv(reshaped, i, j) 

    blurred_dev_data[n] = blurred.ravel() 

Avis Je conv modifié parce que j'avais oublié d'assurer ne sont pas dépassé les limites.

Note: Il est beaucoup, beaucoup plus rapide d'utiliser les bibliothèques existantes telles que SciPy ou OpenCV pour effectuer la convolution 2D, ou dans ce cas, une moyenne du filtre de.

+0

Merci pour votre aide. Pouvez-vous me montrer comment utiliser .ravel() pour enrouler les lignes dans blurred_dev_data? J'ai changé votre ligne 5 à 'pour i dans la gamme (dev_data.shape [0]): reshaped_dev_data = np.reshape (dev_data [i], (28,28))' parce que j'ai besoin de remodeler chaque ligne de dev_data. –

+0

@FredericBastiat Voulez-vous dire aplanir une matrice de 28x28 dans un vecteur de longueur 764? Ce serait juste 'vector = matrix.ravel()' –