Convolution 2D basée sur FFT et corrélation en Python
existe-t-il une fonction 2D de corrélation croisée ou de convolution basée sur 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 mise en oeuvre parconvolveND
sera lent pour les grandes données"scipy.ndimage.correlate
- "le tableau est corrélé avec le noyau donné en utilisant calcul exact (c'est-à-dire pas FFT)."scipy.fftpack.convolve.convolve
je ne comprends pas vraiment, mais semble mal
numarray avait un correlate2d()
la fonction fft=True
switch, mais je suppose que numarray était plié
dans numpy, et je ne peux pas trouver si cette fonction a été incluse.
5 réponses
j'ai trouvé scipy.signal.fftconvolve
, comme le souligne aussi magnus, mais je n'ai pas réalisé à l'époque que c'est ndimensions. Comme il est intégré et produit les bonnes valeurs, il semble être 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'un autre côté, nécessite un peu de travail supplémentaire pour corriger les limites?
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 compiler, que j'ai échoué avec (je viens de commenter les parties non-python), a quelques bugs comme et en modifiant les entrées ([1, 2] devient [[1, 2]]), etc. Alors j'ai changé ma réponse acceptée à l'intégré fftconvolve()
fonction.)
Corrélation, bien sûr, est la même chose que le produit de 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 tailles à l'interne (et puis I accéléré de plus par utilisation réelle de la FFT pour de vrai d'entrée et utilisant 5 longueurs lisses au lieu de puissances de 2: D).
je pense que vous voulez le scipy.STScI package:
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 en scipy, mais je sais que nous incluons ndimage dans le paquet release de stsci_python comme une commodité pour nos utilisateurs:
http://www.stsci.edu/resources/software_hardware/pyraf/stsci_python/current/download
ou vous devriez être en mesure de tirer à partir du référentiel si vous préférez:
https://www.stsci.edu/svn/ssb/stsci_python/stsci_python/trunk/ndimage/
j'ai écrit un wrapper cross-correlation / convolution qui prend soin de padding & nans et comprend un simple wrapper lisse ici. Ce n'est pas un paquet populaire, mais il n'a pas non plus de dépendances en dehors de numpy (ou fftw pour des ffts plus rapides).
j'ai aussi implémenté un code de test de vitesse FFT ici dans le cas où ça intéresse quelqu'un. Il montre - étonnamment - que le FFT de numpy est plus rapide que celui de scipy, du moins sur ma machine.
modifier: déplacer le code vers N-dimensionnel version ici