Je veux me familiariser avec les convolutions basées sur Fourier. Par conséquent, j'ai créé un petit exemple en utilisant numpy.fft et scipy.signal.convolve. Cependant, les résultats des deux opérations sont différents et Je ne sais pas pourquoi. Quelqu'un a-t-il une idée?

J'ai déjà essayé d'utiliser les différents modes de scipy.signal.convolve.

L'exemple:

import numpy as np
from scipy.signal import convolve

# Generate example data
data = np.array([1, 1, 1, 1, 1, 1])
kernel = np.array([0, 1, 2, 1, 0, 0])

# Using scipy.signal.convolve
A = convolve(kernel, data, mode='full')
B = convolve(kernel, data, mode='valid')
C = convolve(kernel, data, mode='same')

# Using the convolution theorem 
D = np.fft.ifft(np.fft.fft(kernel) * np.fft.fft(data))

Les résultats sont:

A = array([0, 1, 3, 4, 4, 4, 4, 3, 1, 0, 0])
B = array([4])
C = array([3, 4, 4, 4, 4, 3])

D = array([4.+0.j, 4.+0.j, 4.+0.j, 4.+0.j, 4.+0.j, 4.+0.j])
1
beckstev 7 oct. 2019 à 10:02

1 réponse

Meilleure réponse

Vous devez remplir data et kernel avec des zéros N-1 pour éviter la convolution circulaire ...

import numpy as np
from scipy.signal import convolve

# Generate example data
data = np.array([1, 1, 1, 1, 1, 1])
kernel = np.array([0, 1, 2, 1, 0, 0])

# Using scipy.signal.convolve
A = convolve(kernel, data, mode='full')

# Using the convolution theorem - need to pad with N-1 zeroes
data = np.array([1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0])
kernel = np.array([0, 1, 2, 1, 0, 0, 0, 0, 0, 0, 0])

D = np.fft.ifft(np.fft.fft(kernel) * np.fft.fft(data))

print (A)
print (D)

Résultat:

[0 1 3 4 4 4 4 3 1 0 0]
[2.4e-16+0.j 1.0e+00+0.j 3.0e+00+0.j 4.0e+00+0.j 4.0e+00+0.j 4.0e+00+0.j
 4.0e+00+0.j 3.0e+00+0.j 1.0e+00+0.j 3.2e-16+0.j 1.6e-16+0.j]
2
Paul R 7 oct. 2019 à 08:23