在频域中使用互相关计算延迟/滞后

信息处理 matlab fft 声音的 互相关 IFFT
2022-02-06 11:14:34

我需要使用频域计算两个信号的互相关。因此,我使用以下等式进行计算。

 max(IFFT(FFT(a)*conj(FFT(b))))

使用这个方程,如何找到滞后?(滞后类似于matlab的内置函数xcorr)(我观察到在频域交叉相关时,最大值总是出现在输出数组的第一个索引中。)任何基本的想法都将有助于我学习和应用它。

3个回答

第一个样本总是最大值是不正确的。滞后只是由结果绝对值的最大值的索引确定。

下面是一个简单的例子来说明正确的操作和结果:

x = randn(512,1);
y = circshift(x, 20);    # y is a shifted version of x
out = ifft(fft(y).*conj(fft(x));
plot(abs(y))
[peak, lagp1] = max(abs(out))  # lag is one less than lagp1  

阴谋

当延迟足够小于捕获的整个数据块时,执行频域(循环相关)非常适合此应用程序。与线性卷积不同,它不受每个信号上相同的 DC 偏移的影响(整个结果向上移动)并且可以有效地计算结果。当我们在更大的数据块中搜索持续时间相对较短的波形实例时,线性相关是一个很好的应用选择。为此,我们可以使用相同的方法,将较短的数据集零填充到较大块的长度,或者在时域中进行相关作为 FIR 滤波器。当数据集在时间上具有相似的持续时间时,不需要零填充或线性相关。

您可以检查 MATLAB 内置函数,尝试edit xcorr.m在 MATLAB 命令提示符下键入。这应该让您了解应该如何设置事物(滞后、如何对输入进行零填充等)。

您确实对如何实现频域互相关计算有了基本的了解。现在,正如 Hilmar 在他们的评论中所说,频域乘法以循环卷积结束(或者如果你对其中一个序列进行复共轭,则为相关)。因此,您必须相应地对序列进行零填充。

从时域互相关计算我们知道得到的序列是L=M+N1长,在哪里M是第一个序列的长度和N第二个的长度。这意味着您应该相应地对您的序列进行零填充,以便两者都以该长度结束。这可以有效地完成(在 MATLAB/Octave 代码中)

% Create the sequences
x1 = rand(100, 1);
x2 = rand(80, 1);

% Get the lengths
x1Len = length(x1);
x2Len = length(x2);
L = x1Len + x2Len - 1;

% Zero pad
xzp1 = [x1; zeros(L - x1Len, 1)];
xzp2 = [x2; zeros(L - x2Len, 1)];

现在,您可以使用您提供的计算来获得互相关函数。请记住,您可能必须改变结果。例如,在 MATLAB/Octave 中,负频率位于正频率之后fs2fs, 在哪里fs是采样频率。这导致互相关函数循环移位整个窗口长度的一半。在 MATLAB/Octave 中,您可以使用fftshift()ifft()函数的结果执行此操作。

或者,您可以使用以下公式计算感兴趣的滞后处的互相关

rx1,x2(τ)=f=fs2fs2R{Rx1,x2ej2πfτ}

在哪里R表示实部,Rx1,x2是交叉谱,f频率(您将使用与 FFT 中每个 bin 的中心频率相对应的频率)和τ兴趣滞后。交叉谱由下式给出

Rx1,x2=X1X2¯

在哪里X1X2是时域序列的频谱和[  ]¯表示复共轭。