La correlación cruzada y la convolución están estrechamente relacionadas. En resumen, para hacer convolución con FFTs, usted
- rellene con cero las señales de entrada (agregue ceros al final para que al menos la mitad de la onda esté "en blanco")
- tomar la FFT de ambas señales
- multiplicar los resultados juntos (multiplicación por elementos)
- hacer el inverso FFT
conv(a, b) = ifft(fft(a_and_zeros) * fft(b_and_zeros))
Debe hacer el relleno de cero porque el método FFT es en realidad una correlación cruzada circular , lo que significa que la señal se envuelve en los extremos. Entonces agrega suficientes ceros para deshacerse de la superposición, para simular una señal que es cero al infinito.
Para obtener una correlación cruzada en lugar de una convolución, debe invertir una de las señales antes de realizar la FFT o tomar el complejo conjugado de una de las señales después de 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)))
lo que sea más fácil con su hardware / software. Para la autocorrelación (correlación cruzada de una señal consigo misma), es mejor hacer el conjugado complejo, porque solo necesita calcular la FFT una vez.
Si las señales son reales, puede usar FFT reales (RFFT / IRFFT) y ahorrar la mitad de su tiempo de cálculo calculando solo la mitad del espectro.
Además, puede ahorrar tiempo de cálculo rellenando a un tamaño más grande para el que está optimizado el FFT (como un número de 5 para FFTPACK, un número de ~ 13 para FFTW o una potencia de 2 para una implementación de hardware simple).
Aquí hay un ejemplo en Python de correlación FFT en comparación con la correlación de fuerza bruta: https://stackoverflow.com/a/1768140/125507
Esto le dará la función de correlación cruzada, que es una medida de similitud frente a desplazamiento. Para obtener el desplazamiento en el que las ondas están "alineadas" entre sí, habrá un pico en la función de correlación:
El valor x del pico es el desplazamiento, que podría ser negativo o positivo.
Solo he visto esto usado para encontrar el desplazamiento entre dos ondas. Puede obtener una estimación más precisa del desplazamiento (mejor que la resolución de sus muestras) mediante el uso de interpolación parabólica / cuadrática en el pico.
Para obtener un valor de similitud entre -1 y 1 (un valor negativo que indica que una de las señales disminuye a medida que aumenta la otra) necesitaría escalar la amplitud de acuerdo con la longitud de las entradas, la longitud de la FFT, su implementación particular de FFT escala, etc. La autocorrelación de una onda consigo misma le dará el valor de la máxima coincidencia posible.
Tenga en cuenta que esto solo funcionará en ondas que tengan la misma forma. Si se han muestreado en un hardware diferente o se ha agregado algo de ruido, pero de lo contrario todavía tienen la misma forma, esta comparación funcionará, pero si la forma de onda se ha cambiado mediante filtros o cambios de fase, puede sonar igual, pero ganó No se correlacionan también.