Кросс-корреляция и свертка тесно связаны. Короче говоря, чтобы сделать свертку с БПФ, вы
- обнуляйте входные сигналы (добавьте нули в конец, чтобы хотя бы половина волны была «пустой»)
- принять БПФ обоих сигналов
- умножить результаты вместе (поэлементное умножение)
- сделать обратное БПФ
conv(a, b) = ifft(fft(a_and_zeros) * fft(b_and_zeros))
Вам необходимо выполнить заполнение нулями, потому что метод 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)))
что проще с вашим аппаратным / программным обеспечением. Для автокорреляции (взаимной корреляции сигнала с самим собой) лучше сделать комплексное сопряжение, потому что тогда вам нужно только рассчитать БПФ один раз.
Если сигналы действительны, вы можете использовать реальные БПФ (RFFT / IRFFT) и сэкономить половину времени вычислений, рассчитав только половину спектра.
Также вы можете сэкономить время вычислений, дополнив его большим размером, для которого оптимизировано FFT (например, 5-гладким числом для FFTPACK, ~ 13-гладким числом для FFTW или степенью 2 для простой аппаратной реализации).
Вот пример в Python корреляции БПФ по сравнению с корреляцией грубой силы: https://stackoverflow.com/a/1768140/125507
Это даст вам функцию взаимной корреляции, которая является мерой сходства против смещения. Чтобы получить смещение, при котором волны «выровнены» друг с другом, в корреляционной функции будет пик:
Значение x пика - это смещение, которое может быть отрицательным или положительным.
Я видел только это, чтобы найти смещение между двумя волнами. Вы можете получить более точную оценку смещения (лучше, чем разрешение ваших выборок), используя параболическую / квадратичную интерполяцию на пике.
Чтобы получить значение подобия между -1 и 1 (отрицательное значение, указывающее, что один из сигналов уменьшается по мере увеличения другого), вам необходимо масштабировать амплитуду в соответствии с длиной входов, длиной FFT, вашей конкретной реализацией FFT. масштабирование и т. д. Автокорреляция волны с самим собой даст вам значение максимально возможного соответствия.
Обратите внимание, что это будет работать только на волнах, имеющих одинаковую форму. Если они были сэмплированы на другом оборудовании или имело некоторый добавленный шум, но в остальном они по-прежнему имеют одинаковую форму, это сравнение будет работать, но если форма волны была изменена фильтрацией или фазовыми сдвигами, они могут звучать одинаково, но выиграли не коррелирует также.