使用 MATLAB 检测时间序列内的信号xc o r r ( ) _xcorr()

信息处理 matlab 信号检测 互相关 匹配过滤器
2021-12-28 12:38:56

我想在时间序列 B 中找到信号 A 的精确副本。我正在使用下面的简单玩具示例,其中 A 位于 B 中的第 4 个位置。

我认为使用xcorr可以实现这一点,但我显然在某个地方失败了。尽管有 MATLAB 帮助说明和以下评论,xcorr但似乎不是正确的功能xcorr

互相关通常是确定两个信号之间时间延迟的最简单方法。峰值位置表示两个信号最相似的时间偏移量。

A = [1 2 1];
B = [0 9 8 1 2 1 7 3 1 0];  
[c, lags] = xcorr(A,B)
lags(c==max(c))
c =
Columns 1 through 12
  0.0000    1.0000    5.0000   14.0000   18.0000   11.0000    6.0000   12.0000   26.0000   26.0000    9.0000    0.0000
Columns 13 through 19
  0.0000    0.0000    0.0000   -0.0000   -0.0000   -0.0000   -0.0000
lags =
  -9    -8    -7    -6    -5    -4    -3    -2    -1     0     1     2     3     4     5     6     7     8     9
ans =
  -1     0

最大相关值位于 -1 和 0 的滞后处,这与使 A 匹配 B 所需的偏移不匹配。这让我问:

  1. 什么时候可以xcorr在另一个信号中找到准确的信号?2. 我应该使用什么函数来找到 A 在 B 中的位置?

理想情况下,我想在更复杂的信号上测试这种方法,并寻找在其他(更长)信号中检测“相似”信号的方法。

2个回答

该函数xcorr计算 2 个信号的相关性。
已知相关性对于高斯噪声下的延迟估计是一个很好的(MLE)。

然而,从您的数据中可以看出,您在本应使用的情况下并未使用它。
如果我们假设您有一个带有加性高斯白噪声(AWGN 或任何其他加性白噪声)的已知信号模型,那么 SNR 非常糟糕,您不能期望它表现良好。

如果您的信号模型是附加确定性信号(该示例中的信号 [0 9 8 0 0 0 7 3 1 0]),那么您应该寻找一种不同的方法(尽管xcorr可以是其中的一部分)。

您使用的任何工具,您都必须了解其设计的模型。

使用归一化互相关来查找小模板在其他较长信号上的位置通常很有用。归一化互相关系数的值不受信号幅度和偏差的影响。

xcorr函数不计算长度不等的向量的归一化互相关系数。我准备了代码片段,用于计算归一化的互相关系数:

%prepare template Y and signal X
Y = [1 2 1];
X = [0 9 8 1 2 1 7 3 1 0];

% calculation normalized cross-correlation
lngX = length(X);
lngY = length(Y);
assert(lngX >= lngY);
lags = 0:(lngX-lngY);
for i = lags
   c(i+1) = xcorr(X(i+1:i+lngY) - mean(X(i+1:i+lngY)), Y - mean(Y),0,'coeff');
end
[m,i]=max(c);
printf('max=%f, lag=%d\n',c(i),lags(i));
plot(lags,c,'-',lags(i),c(i),'*r');
text(lags(im)+4,c(im)-0.05,'max correlation', 'color','red');
xlabel('lags'); title('normalized cross-correlation'); grid on;

结果:

 max=1.000000, lag=3

在此处输入图像描述

更新 1

Matlab 的xcorr不计算真正的归一化互相关,因此我在调用xcorr之前从信号中减去平均值

更新 2 我修改了我的代码以演示更有趣的模板和信号示例。计算归一化互相关的部分代码是相同的。

%prepare template Y and signal X
Y = exp(-((1:40)-20).^2/20.).*cos(((1:40)-20)*2*pi/10);
Y2 = exp(-((1:100)-50).^2/100.);
X = [zeros(1,40) 2*Y zeros(1,10) 3*Y2 zeros(1,10)];
noise=1.;
X=X+noise*(rand(1,length(X))-0.5);

% calculation normalized cross-correlation
lngX = length(X);
lngY = length(Y);
assert(lngX >= lngY);
lags = 0:(lngX-lngY);
for i = lags
   c(i+1) = xcorr(X(i+1:i+lngY) - mean(X(i+1:i+lngY)), Y -     mean(Y),0,'coeff');
end
[m,im]=max(c);
printf('max=%f, lag=%d\n',c(im),lags(im));

%plotting
subplot(2,1,2);
plot(lags(im)+1:(lngY+lags(im)),Y,'r','linewidth',2,1:lngX,X,'b');
legend('template','signal'); grid on;
subplot(2,1,1);
plot(lags,c,'-',lags(im),c(im),'*r');
text(lags(im)+4,c(im)-0.05,'max correlation', 'color','red');
xlabel('lags'); title('normalized cross-correlation'); grid on;

结果:

max=0.905503, lag=40

归一化互相关