Kreuzkorrelation und Faltung sind eng miteinander verbunden. Kurz gesagt, um mit FFTs Faltung zu machen, Sie
- Null-Pad für die Eingangssignale (fügen Sie am Ende Nullen hinzu, so dass mindestens die Hälfte der Welle "leer" ist)
- nimm die FFT beider Signale
- Multiplizieren Sie die Ergebnisse (elementweise Multiplikation)
- mache die inverse FFT
conv(a, b) = ifft(fft(a_and_zeros) * fft(b_and_zeros))
Sie müssen das Auffüllen mit Nullen durchführen, da es sich bei der FFT-Methode um eine zirkuläre Kreuzkorrelation handelt, dh, das Signal wird an den Enden herumgewickelt. Sie addieren also genügend Nullen, um die Überlappung zu beseitigen und ein Signal zu simulieren, das null bis unendlich ist.
Um Kreuzkorrelation statt Faltung zu erhalten, müssen Sie entweder eines der Signale vor der FFT zeitlich umkehren oder das komplexe Konjugat eines der Signale nach der FFT nehmen:
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)))
je nachdem, was mit Ihrer Hardware / Software einfacher ist. Für die Autokorrelation (Kreuzkorrelation eines Signals mit sich selbst) ist es besser, das komplexe Konjugat durchzuführen, da Sie dann die FFT nur einmal berechnen müssen.
Wenn die Signale echt sind, können Sie echte FFTs (RFFT / IRFFT) verwenden und die Hälfte Ihrer Rechenzeit sparen, indem Sie nur die Hälfte des Spektrums berechnen.
Sie können auch Rechenzeit sparen, indem Sie eine größere Größe auffüllen, für die die FFT optimiert ist (z. B. eine 5-glatte Zahl für FFTPACK, eine ~ 13-glatte Zahl für FFTW oder eine Potenz von 2 für eine einfache Hardwareimplementierung).
Hier ist ein Beispiel der Python-FFT-Korrelation im Vergleich zur Brute-Force-Korrelation: https://stackoverflow.com/a/1768140/125507
Dadurch erhalten Sie die Kreuzkorrelationsfunktion, die ein Maß für die Ähnlichkeit gegenüber dem Offset ist. Um den Versatz zu erhalten, bei dem die Wellen "aneinandergereiht" sind, gibt es eine Spitze in der Korrelationsfunktion:
Der x-Wert des Peaks ist der Offset, der negativ oder positiv sein kann.
Ich habe nur gesehen, dass dies verwendet wurde, um den Versatz zwischen zwei Wellen zu finden. Sie können eine genauere Schätzung des Offsets (besser als die Auflösung Ihrer Proben) erhalten, indem Sie eine parabolische / quadratische Interpolation für den Peak verwenden.
Um einen Ähnlichkeitswert zwischen -1 und 1 zu erhalten (ein negativer Wert, der anzeigt, dass eines der Signale abnimmt, wenn das andere zunimmt), müssen Sie die Amplitude entsprechend der Länge der Eingänge, der Länge der FFT und Ihrer speziellen FFT-Implementierung skalieren Skalierung usw. Die Autokorrelation einer Welle mit sich selbst gibt Ihnen den Wert der maximal möglichen Übereinstimmung.
Beachten Sie, dass dies nur bei Wellen funktioniert, die dieselbe Form haben. Wenn sie auf einer anderen Hardware abgetastet wurden oder Rauschen hinzugefügt wurden, aber ansonsten immer noch dieselbe Form haben, funktioniert dieser Vergleich. Wenn die Wellenform jedoch durch Filterung oder Phasenverschiebung geändert wurde, klingen sie möglicherweise gleich, haben aber gewonnen auch nicht korrelieren.