【问题标题】:Finding the difference between two signals找出两个信号之间的差异
【发布时间】:2013-03-12 20:35:19
【问题描述】:

我有两个信号,我们称它们为“a”和“b”。但是,它们都是几乎相同的信号(从相同的输入记录并包含相同的信息),因为我在两个不同的“b”处记录了它们,它们的时间偏移量未知。很明显,每个都有随机噪声。

目前,我正在使用互相关来计算时间偏移,但是,我仍然得到不正确的结果。

这是我用来计算时移的代码:

function [ diff ] = FindDiff( signal1, signal2 )
%FINDDIFF Finds the difference between two signals of equal frequency 
%after an appropritate time shift is applied
%   Calculates the time shift between two signals of equal frequency 
%   using cross correlation, shifts the second signal and subtracts the
%   shifted signal from the first signal. This difference is returned.
length = size(signal1);

if (length ~= size(signal2))
    error('Vectors must be equal size');
end

t = 1:length;
tx = (-length+1):length;
x = xcorr(signal1,signal2);
[mx,ix] = max(x);
lag = abs(tx(ix));
shifted_signal2 = timeshift(signal2,lag);
diff = signal1 - shifted_signal2;

end

function [ shifted ] = timeshift( input_signal, shift_amount )
input_size = size(input_signal);
shifted = (1:input_size)';
for i = 1:input_size
    if i <= shift_amount
        shifted(i) = 0;
    else
        shifted(i) = input_signal(i-shift_amount);
    end
end

end

plot(FindDiff(a,b));

但是,该函数的结果是周期波,而不是随机噪声,因此滞后必须仍然关闭。我会发布剧情的图片,但 imgur 目前不合作。

除了互相关之外,有没有更准确的方法来计算滞后,或者有没有办法改善互相关的结果?

【问题讨论】:

  • 实际上,如果您要比较两个大小相同的信号,xcorr 将不起作用,因为它将首先将 signal1 与 signal2 的一部分进行比较,该部分将用零填充(或者可能用最后一个值,但这仍然不是比较两个信号的好方法)。您可能应该将信号段与较大的信号进行比较,然后确定子信号在较大信号中的位置。此外,您正在覆盖“长度”内置函数并不必要地形成 t 和 tx。
  • @jucestain 我不认为这是正确的。我们在互相关中唯一看到的是它的最大值,所以开头的那些零不会产生影响。而且我知道当信号被用于自身时,这些函数可以完美地工作。
  • 您是否尝试过查看整个相关性而不仅仅是其最大值?如果处理现实世界的噪声信号,您的实时偏移可能不会产生最大相关性
  • @KyleRogers 了解互相关的工作原理。这是一个滑动点产品。如果您正在比较两个相同大小的向量,您认为它们将如何在开始或结束时进行比较?其中一个向量将被填充一些东西。从简要查看 xcorr 输出来看,它看起来像是用零填充向量之一。此外,当您说“开头的那些零不会产生影响”时,将使用这些值计算相关系数,因此它们无疑会产生影响,特别是因为您的实现不使用标准化。
  • @jucestain 我的代码实际上是完全正确的。我得到我认为不正确的结果的原因与仪器产生周期性噪声有关,而不是高斯噪声。

标签: matlab signal-processing


【解决方案1】:

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

%// Normalize signals to zero mean and unit variance
s1 = (signal1 - mean(signal1)) / std(signal1);
s2 = (signal2 - mean(signal2)) / std(signal2);

%// Compute time lag between signals
c = xcorr(s1, s2);                       %// Cross correlation
lag = mod(find(c == max(c)), length(s2)) %// Find the position of the peak

注意,这两个信号必须先归一化到相同的能级,这样结果才不会有偏差。

顺便说一句,不要使用diff 作为变量的名称。 MATLAB 中已经有一个built-in function 同名。

【讨论】:

  • 如何从延迟中判断 signal2 是否可以在 signal1 中找到?
  • @ZoltanSzabo 互相关的峰值,而不是“滞后”,可以帮助您确定您要询问的内容。峰值表示两个信号最相似的位置,或者换句话说,一个信号和另一个相似信号之间的时间偏移是多少。没有这样的峰值意味着信号是不同的。
  • 谢谢,我可以得到相关性最大指数的峰值。你知道我怎样才能得到一些百分比来显示这两个信号有多相似吗?例如,我有两个信号,它们几乎相似。第一个信号的长度在 130kbyte 左右,但是算法在 125kbyte 左右找到了峰值,所以它似乎找到了匹配,但我知道信号并不是很相似。所以我需要一些百分比。
  • @ZoltanSzabo 有多种测量信号相似性的方法。其中之一是比较频率分量...我建议您查看 MATLAB 官方文档网站上的this example
【解决方案2】:

现在Matlab中有两个函数:

一个叫finddelay

另一个叫alignsignals,我相信它可以做你想做的事。

【讨论】:

  • 鉴于新功能 - 现在应该认为这是解决此问题的最佳解决方案。
【解决方案3】:

corr 在向量(v1, v2) 之间找到一个点积。如果它对你的信号不好,我会尽量减少差异的平方和(即abs(v1 - v2))。

 signal = sin(1:100);
 signal1 = [zeros(1, 10) signal];
 signal2 = [signal zeros(1, 10)];

 for i = 1:length(signal1)
     signal1shifted = [signal1 zeros(1, i)];
     signal2shifted = [zeros(1, i) signal2];
     d2(i) = sum((signal1shifted - signal2shifted).^2);
 end

 [fval lag2] = min(d2);

 lag2

它在计算上比使用 FFT 可以加速的交叉计算更差。据我所知,你不能用欧几里德距离做到这一点。

UPD。删除了关于与周期信号互相关的错误想法

【讨论】:

    【解决方案4】:

    你可以尝试频域匹配过滤

    function [corr_output] = pc_corr_processor (target_signal, ref_signal)
    L = length(ref_signal);
    N = length(target_signal);
    
    matched_filter = flipud(ref_signal')';
    matched_filter_Res = fft(matched_filter,N);
    corr_fft = matched_filter_Res.*fft(target_signal);
    corr_out = abs(ifft(corr_fft));
    

    上面 corr_out 的匹配滤波器最大索引的峰值应该给你滞后量。

    【讨论】:

      猜你喜欢
      • 2021-12-05
      • 2016-07-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-04
      • 2014-08-15
      • 1970-01-01
      相关资源
      最近更新 更多