Exemples de comment faire une convolution 2D en python avec scipy:
Créer un kernel ("noyau") 2D avec numpy
Créons d'abord un noyau 2D simple avec numpy
import numpy as np
import matplotlib.pyplot as plt
import matplotlib as mpl
import seaborn as sns; sns.set()
K = np.zeros((10,10))
K[:,:] = 1
K[:,0:5] = -1.
print(K)
plt.imshow(K)
plt.colorbar()
plt.title("Kernel 01")
plt.savefig("kernel_01.png", bbox_inches='tight', dpi=100)
plt.show()
donne
[[-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. 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.]
[-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. 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.]]
et
Créer une fausse image avec numpy
Créons maintenant une matrice (ou image) 2D très simple avec numpy
img = np.zeros((100,100))
img[0:50,0:40] = 1.
img[50:100,0:60] = 1.
print(img)
plt.imshow(img)
plt.colorbar()
plt.savefig("img_01.png", bbox_inches='tight', dpi=100)
plt.show()
donne
Convoluer deux tableaux à 2 dimensions
Convoluer maintenant l'image avec le kernel. une solution est d'utiliser scipy.signal.convolve2d:
from scipy import signal
f1 = signal.convolve2d(img, K, boundary='symm', mode='same')
plt.imshow(f1)
plt.colorbar()
plt.savefig("img_01_kernel_01_convolve2d.png", bbox_inches='tight', dpi=100)
plt.show()
donne
Notez qu'ici les valeurs de la convolution sont positives.
Un autre exemple
Attention : lors d'une convolution le noyau est inversé (voir discussion ici par exemple scipy convolve2d outputs wrong values).
Un autre exemple de noyau:
K = np.zeros((10,10))
K[:,:] = -1
K[:,0:5] = 1.
print(K)
plt.imshow(K)
plt.colorbar()
plt.title("Kernel 02")
plt.savefig("kernel_02.png", bbox_inches='tight', dpi=100)
plt.show()
donne
2d convolution
f1 = signal.convolve2d(img, K, boundary='symm', mode='same')
plt.imshow(f1)
plt.colorbar()
plt.title("2D Convolution")
plt.savefig("img_01_kernel_02_convolve2d.png", bbox_inches='tight', dpi=100)
plt.show()
donne ici