FFT-2D à base de convolution et de corrélation dans le python
-
11-09-2019 - |
Question
Y at-il une fonction de corrélation croisée ou convolution 2D FFT intégrée dans scipy (ou une autre bibliothèque populaire)?
Il y a des fonctions comme celles-ci:
-
scipy.signal.correlate2d
- « la méthode directe mis en œuvre parconvolveND
sera lent pour les grandes données " -
scipy.ndimage.correlate
- « Le tableau est en corrélation avec le noyau donné à l'aide calcul exact (à savoir non FFT). " -
scipy.fftpack.convolve.convolve
, que je ne comprends pas vraiment, mais il semble mal
numarray avait une correlate2d()
avec un commutateur fft=True
, mais je suppose que numarray était plié
en numpy, et je ne trouve pas si cette fonction a été inclus.
La solution
J'ai trouvé scipy.signal.fftconvolve
, comme également souligné par magnus , mais ne savais pas au moment où il est n -dimensionnelle. Comme il est intégré et produit les bonnes valeurs, il semble que la solution idéale.
In [1]: a = asarray([[ 1, 2, 3],
...: [ 4, 5, 6],
...: [ 7, 8, 9]])
In [2]: b = asarray([[-1,-2,-1],
...: [ 0, 0, 0],
...: [ 1, 2, 1]])
In [3]: scipy.signal.fftconvolve(a, b, mode = 'same')
Out[3]:
array([[-13., -20., -17.],
[-18., -24., -18.],
[ 13., 20., 17.]])
Correct! La version STSCI, d'autre part, exige un travail supplémentaire pour rendre les limites correctes?
In [4]: stsci.convolve2d(a, b, fft = True)
Out[4]:
array([[-12., -12., -12.],
[-24., -24., -24.],
[-12., -12., -12.]])
(La méthode STSCI exige également la compilation, que j'a échoué avec (je viens de parler les parties non-python), a quelques bugs comme cette et de modifier les entrées ([1, 2] devient [[1, 2]]), etc. Je suis donc changé ma réponse acceptée à la fonction fftconvolve()
intégrée .)
Corrélation, bien sûr, est la même chose que convolution, mais avec une entrée inversée:
In [5]: a
Out[5]:
array([[3, 0, 0],
[2, 0, 0],
[1, 0, 0]])
In [6]: b
Out[6]:
array([[3, 2, 1],
[0, 0, 0],
[0, 0, 0]])
In [7]: scipy.signal.fftconvolve(a, b[::-1, ::-1])
Out[7]:
array([[ 0., -0., 0., 0., 0.],
[ 0., -0., 0., 0., 0.],
[ 3., 6., 9., 0., 0.],
[ 2., 4., 6., 0., 0.],
[ 1., 2., 3., 0., 0.]])
In [8]: scipy.signal.correlate2d(a, b)
Out[8]:
array([[0, 0, 0, 0, 0],
[0, 0, 0, 0, 0],
[3, 6, 9, 0, 0],
[2, 4, 6, 0, 0],
[1, 2, 3, 0, 0]])
et la dernière révision a été accéléré en utilisant la puissance de deux enfants tailles en interne (et j'accélérai vers le haut plus par en utilisant FFT réel pour l'entrée réelle et utilisant des longueurs 5-lisses plutôt que des puissances de 2 :. D)
Autres conseils
regard sur scipy.signal.fftconvolve, signal.convolve et signal.correlate (il y a un signal.correlate2d mais il semble retourner un tableau décalé, non centré).
Je pense que vous voulez que le paquet scipy.stsci:
http://docs.scipy.org/doc/scipy/reference /stsci.html
In [30]: scipy.__version__
Out[30]: '0.7.0'
In [31]: from scipy.stsci.convolve import convolve2d, correlate2d
J'ai perdu la trace de l'état de ce paquet dans scipy, mais je sais que nous incluons ndimage dans le cadre du paquet de libération de stsci_python comme commodité pour nos utilisateurs:
http://www.stsci.edu/resources/software_hardware / pyraf / stsci_python / courant / télécharger
ou vous devriez pouvoir tirer du référentiel si vous préférez:
https://www.stsci.edu/svn/ BFS / stsci_python / stsci_python / trunk / ndimage /
J'ai écrit une enveloppe de corrélation croisée / convolution qui prend soin de rembourrage et nans et comprend simple enveloppe lisse ici . Ce n'est pas un paquet populaire, mais il n'a pas non plus dépendances en plus numpy (ou fftw pour TFR plus rapide).
J'ai aussi mis en place un code de test de vitesse FFT au cas où quelqu'un est intéressé. Il montre - étonnamment -. Que la fft de numpy est plus rapide que celle des SciPy, au moins sur ma machine
EDIT: déplacé le code à la version N dimensions ici