Convolve2d seulement par l'utilisation de Numpy

Je suis des études de traitement de l'image à l'aide de Numpy et face à un problème de filtrage avec la convolution.

Je voudrais convolution d'une image en niveaux de gris de l'image. (convolution d'un Tableau 2d avec un petit Tableau 2d)

Quelqu'un a une idée pour affiner ma méthode ?

Je sais que scipy prend en charge convolve2d mais je veux faire un convolve2d que par l'utilisation de Numpy.

Ce que j'ai fait

Tout d'abord, j'ai fait un tableau 2d de la submatrices.

a = np.arange(25).reshape(5,5) # original matrix

submatrices = np.array([
     [a[:-2,:-2], a[:-2,1:-1], a[:-2,2:]],
     [a[1:-1,:-2], a[1:-1,1:-1], a[1:-1,2:]],
     [a[2:,:-2], a[2:,1:-1], a[2:,2:]]])

la submatrices semble compliqué, mais ce que je fais est montré sur le dessin suivant.

Convolve2d seulement par l'utilisation de Numpy

Prochaine, je multiplie chaque submatrices avec un filtre.

conv_filter = np.array([[0,-1,0],[-1,4,-1],[0,-1,0]])
multiplied_subs = np.einsum('ij,ijkl->ijkl',conv_filter,submatrices)

Convolve2d seulement par l'utilisation de Numpy

et additionnés entre eux.

np.sum(np.sum(multiplied_subs, axis = -3), axis = -3)
#array([[ 6,  7,  8],
#       [11, 12, 13],
#       [16, 17, 18]])

Donc ce procudure peut être appelé mon convolve2d.

def my_convolve2d(a, conv_filter):
    submatrices = np.array([
         [a[:-2,:-2], a[:-2,1:-1], a[:-2,2:]],
         [a[1:-1,:-2], a[1:-1,1:-1], a[1:-1,2:]],
         [a[2:,:-2], a[2:,1:-1], a[2:,2:]]])
    multiplied_subs = np.einsum('ij,ijkl->ijkl',conv_filter,submatrices)
    return np.sum(np.sum(multiplied_subs, axis = -3), axis = -3)

Cependant, je trouve cette my_convolve2d gênant pour 3 raisons.

  1. Génération de la submatrices est trop maladroit qui est difficile à lire et peut être utilisé seulement lorsque le filtre est de 3*3
  2. La taille de la variante submatrices semble être trop grand, car il est environ 9 fois plus grand que la matrice d'origine.
  3. Le résumé semble un peu non intuitive. Simplement dit, laid.

Je vous remercie pour la lecture de ce jour.

Genre de mise à jour. J'ai écrit un conv3d pour moi-même. Je vais laisser cela comme un domaine public.

def convolve3d(img, kernel):
    # calc the size of the array of submatracies
    sub_shape = tuple(np.subtract(img.shape, kernel.shape) + 1)

    # alias for the function
    strd = np.lib.stride_tricks.as_strided

    # make an array of submatracies
    submatrices = strd(img,kernel.shape + sub_shape,img.strides * 2)

    # sum the submatraces and kernel
    convolved_matrix = np.einsum('hij,hijklm->klm', kernel, submatrices)

    return convolved_matrix
merci de fournir les dessins de la matrices 🙂 Si je comprends bien, vous voulez des conseils sur la façon de faire de votre solution plus élégante?
Content que ça aide! Oui. Je vous serais reconnaissant si vous pouvez me donner des conseils pour surmonter les 3 problèmes écrite dans les toutes dernières lignes.
Je dois ajouter que les 3 points sont plutôt disposés dans un ordre de priorité. Le premier est assez important pour moi et le dernier semble un peu trivial. Je serai aussi heureux si il y a d'autres problèmes et les améliorations à apporter à ce sujet.
N'est-ce pas le deuxième dessin (après le signe de l'égalité) de mal? Ne devrait pas chaque submatrix être multipliés (élément-sage) avec le filtre, puis les éléments de chaque résultant de la submatrices résumé?
Ils produisent le même résultat.

OriginalL'auteur Allosteric | 2017-03-29