2009-07-08 13 views
20

Esiste una funzione di cross-correlazione 2D o convoluzione basata su FFT incorporata in scipy (o un'altra libreria popolare)?Convoluzione 2D e correlazione basata su FFT in Python

Ci sono funzioni come questi:

  • scipy.signal.correlate2d - "il metodo diretto implementato da convolveND sarà lento per grandi dati"
  • scipy.ndimage.correlate - "La matrice viene correlato con il dato kernel usando esatta calcolo (cioè non FFT). "
  • scipy.fftpack.convolve.convolve, che io non capisco, ma sembra sbagliato

numarray aveva un correlate2d() function with an fft=True switch, ma credo che numarray stato piegato in NumPy, e non riesco a trovare se questa funzione è stata inclusa.

+1

nota che mediante il calcolo esatto (senza FFT) è esattamente la stessa dicendo che è lento :) Più precisamente, il metodo basato su FFT sarà molto più veloce se avete un segnale e un kernel approssimativamente della stessa dimensione (se il kernel è molto più piccolo dell'input, allora FFT potrebbe essere effettivamente più lento del calcolo diretto). –

+0

Idealmente, l'algoritmo FFT si prenderà automaticamente cura delle cose di riempimento zero alla giusta dimensione per la migliore velocità. – endolith

+1

Oh non stai parlando di padding zero, stai parlando di abbinare un'immagine 5x5 con un'immagine 2000x2000. Perché l'algoritmo non può solo indovinare se la FFT sarebbe più efficiente e farlo in qualsiasi modo è più veloce? – endolith

risposta

17

ho trovato scipy.signal.fftconvolve, as also pointed out by magnus, ma non mi rendevo conto al momento che si tratta di n dimensionale. Poiché è integrato e produce i giusti valori, sembra la soluzione ideale.

Da Example of 2D Convolution:

corretta! La versione STSCI, d'altra parte, richiede un lavoro extra per rendere i confini corretti?

In [4]: stsci.convolve2d(a, b, fft = True) 
Out[4]: 
array([[-12., -12., -12.], 
     [-24., -24., -24.], 
     [-12., -12., -12.]]) 

(Procedimento STScI richiede inoltre la compilazione, che ero riuscita con (I appena commentato le parti non pitone), ha alcuni insetti come this e modificando gli ingressi ([1, 2] diventa [[ 1, 2]]), ecc Così ho cambiato la mia risposta accettata alla correlazione built-in funzione di fftconvolve())

, naturalmente, è la stessa cosa di convoluzione, ma con un ingresso invertito:.

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]]) 

e the latest revision sono stati velocizzati usando le due dimensioni di alimentazione interna (e poi l'ho accelerato di più con using real FFT for real input e using 5-smooth lengths instead of powers of 2: D).

4

Penso che si desidera il pacchetto 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 
+0

L'ho visto anch'io, ma non lo fa t sembra essere più incluso in SciPy? >>> import scipy.stsci.convolve Traceback (chiamata più recente scorso): file "", linea 1, in ImportError: No module named convolve – endolith

+0

Hi - Ho incollato l'uscita dal mio prompt di sopra. Qual è la tua versione? – ars

+0

Chiaramente qualcosa non va: http://pastebin.com/mdd2bc6d Buono a sapersi, esiste. – endolith

2

Ho perso traccia dello stato di questo pacchetto in SciPy, ma so includiamo ndimage come parte del pacchetto di rilascio stsci_python come vantaggio per i nostri utenti:

http://www.stsci.edu/resources/software_hardware/pyraf/stsci_python/current/download

o si dovrebbe essere in grado di pull dal repositor y se si preferisce:

https://www.stsci.edu/svn/ssb/stsci_python/stsci_python/trunk/ndimage/

+0

Secondo i documenti di SciPy, non è basato su FFT, come ho menzionato nella domanda. http://www.scipy.org/SciPyPackages/Ndimage – endolith

+1

Il pacchetto convolve è disponibile anche dal repository stsci_python. Include la funzione correl2d che ha l'interruttore fft = True che hai anche menzionato. https://www.stsci.edu/svn/ssb/stsci_python/stsci_python/trunk/convolve/lib/Convolve.py –

+0

Oh! Posso solo importare direttamente il file python, se rimuovo il riferimento a _correlate. La correlazione FFT è tutto in Python. Ora ho funzionato. :) Grazie! – endolith

6

sguardo scipy.signal.fftconvolve, signal.convolve e signal.correlate (c'è un signal.correlate2d ma sembra restituire un array spostato, non centrato).

+0

Ho cambiato la mia risposta accettata a questo, come spiegato di seguito http://stackoverflow.com/questions/1100100/fft-based-2d-convolution-and-correlation-in-python/1768140#1768140 – endolith

2

Ho scritto un wrapper di cross-correlation/convolution che si occupa del padding & nans e include un semplice wrapper liscio here. Non è un pacchetto popolare, ma non ha nemmeno dipendenze oltre a numpy (o fftw per fft più veloci).

Ho anche implementato un codice di prova velocità FFT here nel caso qualcuno fosse interessato. Mostra - sorprendentemente - che il fft di Numpy è più veloce di quello di Scipy, almeno sulla mia macchina.

EDIT: spostato il codice per N-dimensionale versione here