我需要使用频域计算两个信号的互相关。因此,我使用以下等式进行计算。
max(IFFT(FFT(a)*conj(FFT(b))))
使用这个方程,如何找到滞后?(滞后类似于matlab的内置函数xcorr)(我观察到在频域交叉相关时,最大值总是出现在输出数组的第一个索引中。)任何基本的想法都将有助于我学习和应用它。
我需要使用频域计算两个信号的互相关。因此,我使用以下等式进行计算。
max(IFFT(FFT(a)*conj(FFT(b))))
使用这个方程,如何找到滞后?(滞后类似于matlab的内置函数xcorr)(我观察到在频域交叉相关时,最大值总是出现在输出数组的第一个索引中。)任何基本的想法都将有助于我学习和应用它。
第一个样本总是最大值是不正确的。滞后只是由结果绝对值的最大值的索引确定。
下面是一个简单的例子来说明正确的操作和结果:
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 在他们的评论中所说,频域乘法以循环卷积结束(或者如果你对其中一个序列进行复共轭,则为相关)。因此,您必须相应地对序列进行零填充。
从时域互相关计算我们知道得到的序列是长,在哪里是第一个序列的长度和第二个的长度。这意味着您应该相应地对您的序列进行零填充,以便两者都以该长度结束。这可以有效地完成(在 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 中,负频率位于正频率之后到, 在哪里是采样频率。这导致互相关函数循环移位整个窗口长度的一半。在 MATLAB/Octave 中,您可以使用fftshift()对ifft()函数的结果执行此操作。
或者,您可以使用以下公式计算感兴趣的滞后处的互相关
在哪里表示实部,是交叉谱,频率(您将使用与 FFT 中每个 bin 的中心频率相对应的频率)和兴趣滞后。交叉谱由下式给出
在哪里和是时域序列的频谱和表示复共轭。