La correlazione incrociata e la convoluzione sono strettamente correlate. In breve, per fare la convoluzione con le FFT, tu
- azzerare i segnali di input (aggiungere zeri alla fine in modo che almeno metà dell'onda sia "vuota")
- prendere la FFT di entrambi i segnali
- moltiplicare i risultati insieme (moltiplicazione degli elementi)
- fare l'inverso FFT
conv(a, b) = ifft(fft(a_and_zeros) * fft(b_and_zeros))
Devi fare lo zero padding perché il metodo FFT è in realtà una correlazione incrociata circolare , il che significa che il segnale si avvolge alle estremità. Quindi aggiungi abbastanza zeri per sbarazzarti della sovrapposizione, per simulare un segnale che è zero fuori all'infinito.
Per ottenere la correlazione incrociata anziché la convoluzione, è necessario invertire il tempo di uno dei segnali prima di eseguire la FFT o prendere il coniugato complesso di uno dei segnali dopo la FFT:
corr(a, b) = ifft(fft(a_and_zeros) * fft(b_and_zeros[reversed]))
corr(a, b) = ifft(fft(a_and_zeros) * conj(fft(b_and_zeros)))
qualunque sia più facile con il tuo hardware / software. Per l'autocorrelazione (correlazione incrociata di un segnale con se stesso), è meglio eseguire il coniugato complesso, perché è quindi necessario calcolare l'FFT una sola volta.
Se i segnali sono reali, è possibile utilizzare FFT reali (RFFT / IRFFT) e risparmiare metà del tempo di calcolo calcolando solo metà dello spettro.
Inoltre, puoi risparmiare tempo di calcolo riempiendo le dimensioni con una dimensione maggiore per cui l'FFT è ottimizzato (come un numero 5-smooth per FFTPACK, un numero ~ 13-smooth per FFTW o una potenza di 2 per una semplice implementazione hardware).
Ecco un esempio in Python della correlazione FFT rispetto alla correlazione della forza bruta: https://stackoverflow.com/a/1768140/125507
Questo ti darà la funzione di correlazione incrociata, che è una misura di somiglianza vs offset. Per ottenere l'offset in corrispondenza del quale le onde sono "allineate" tra loro, ci sarà un picco nella funzione di correlazione:
Il valore x del picco è l'offset, che potrebbe essere negativo o positivo.
L'ho visto solo per trovare l'offset tra due onde. È possibile ottenere una stima più precisa dell'offset (migliore della risoluzione dei campioni) utilizzando l'interpolazione parabolica / quadratica sul picco.
Per ottenere un valore di somiglianza tra -1 e 1 (un valore negativo che indica uno dei segnali diminuisce all'aumentare dell'altro) è necessario ridimensionare l'ampiezza in base alla lunghezza degli input, alla lunghezza della FFT, alla specifica implementazione della FFT ridimensionamento, ecc. L'autocorrelazione di un'onda con se stessa ti darà il valore della massima corrispondenza possibile.
Nota che funzionerà solo su onde che hanno la stessa forma. Se sono stati campionati su hardware diverso o hanno aggiunto del rumore, ma per il resto hanno ancora la stessa forma, questo confronto funzionerà, ma se la forma dell'onda è stata cambiata da filtri o sfasamenti, potrebbero suonare allo stesso modo, ma hanno vinto anche correlare.