Matlab:使用互协方差对齐数据

Matlab:使用互协方差对齐数据,matlab,Matlab,我想在Matlab中获得两个数据集之间的样本偏移量(使它们及时同步),这是一个非常常见的问题。因此,我使用互相关函数xcorr或互协方差函数xcov(这两个函数在大多数情况下都提供类似的结果)。对于人工数据,它工作得很好,但我很难处理“真实”数据,尽管它应该差不多。Matlab总是说偏移量为零。我使用的是一段简单的代码: [crossCorr] = xcov(b, c); [~, peakIndex] = max(crossCorr()) offset = peakIndex - length(

我想在Matlab中获得两个数据集之间的样本偏移量(使它们及时同步),这是一个非常常见的问题。因此,我使用互相关函数xcorr或互协方差函数xcov(这两个函数在大多数情况下都提供类似的结果)。对于人工数据,它工作得很好,但我很难处理“真实”数据,尽管它应该差不多。Matlab总是说偏移量为零。我使用的是一段简单的代码:

[crossCorr] = xcov(b, c);
[~, peakIndex] = max(crossCorr())
offset = peakIndex - length(b)
我在pastebin上发布了一个完全可运行的示例m文件,其中包含一个下采样数据摘录:

编辑:下采样摘录似乎不完全适合评估效果。不幸的是,它对pastebin来说太大了

如图所示,通过互协方差获得偏移量应该没有任何问题。为了避免数值问题,我还尝试更好地缩放数据,但这丝毫没有改变任何事情


如果有人能告诉我我的错误,那就太好了。

您的数据在5左右有一个小峰值,在101左右有一个大峰值

如果我对我的数据有所了解,那么我可能会在如下所示的可接受的偏移范围内打开窗口

初步勘探代码:

figure; clc;
subplot(2,1,1) 
plot(1:numel(b), b);
hold on
plot(1:numel(c), c, 'r');
legend('b','c')

subplot(2,1,2)
plot(crossCorr,'.b-')
hold on
plot(peakIndex,crossCorr(peakIndex),'or')
legend('crossCorr','peak')
初始图像:

如果放大第一个峰值,您可以看到它不仅在5左右很高,而且是多项式“足够”允许子元素偏移。那很方便

图像显示:

以下是曲线拟合工具为立方体提供的分析:

Linear model Poly3:
     f(x) = p1*x^3 + p2*x^2 + p3*x + p4
Coefficients (with 95% confidence bounds):
       p1 =  8.515e-013  (8.214e-013, 8.816e-013)
       p2 = -3.319e-011  (-3.369e-011, -3.269e-011)
       p3 =  2.253e-010  (2.229e-010, 2.277e-010)
       p4 = -4.226e-012  (-7.47e-012, -9.82e-013)

Goodness of fit:
  SSE: 2.799e-024
  R-square: 1
  Adjusted R-square: 1
  RMSE: 6.831e-013
您可以注意到,SSE适合舍入。 如果计算根(接近n=4),则使用以下matlab代码:

% Coefficients
       p1 =  8.515e-013
       p2 = -3.319e-011
       p3 =  2.253e-010
       p4 = -4.226e-012
% Linear model Poly3:
syms('x')
f = p1*x^3 + p2*x^2 + p3*x + p4

xz1=fzero(@(y) subs(diff(f),'x',y), 4)
得到的解析根是4.014204431444

编辑: 嗯,用高斯混合模型拟合卷积怎么样?扫描一个良好的组件计数范围,重复10到30次,然后找到哪个组件计数具有最佳/最低BIC。因此,将gm分布拟合到第一个图的较低子图中,然后按分量的平均值降序测试协方差

我会尝试平均值的偏移量,只看平方和误差。然后我将选择误差最小的偏移量

程序:

  • 计算互相关
  • 高斯混合模型的互相关拟合
    • 扫掠组件的合理范围(从1-10开始)
    • 使用合理的重复次数(10到30次,取决于运行到运行的变化)
    • 计算每个级别的Bayes信息标准(BIC),选择最低的,因为它表明错误和参数计数的合理平衡
  • 每个分量都有一个平均值,将该平均值作为一个候选偏移量进行评估,并在这样偏移时计算平方和误差(sse)
  • 拾取提供最佳SSE的组件的偏移

让我知道它的效果如何。

原则上,您的方法没有问题,我成功地使用了完全相同的方法,对同一信号的不同录音进行了临时对齐

然而,对于时间序列而言,相关性(或协方差)显然不是比较移位版本的正确度量——可能是因为它们包含与总长度相当的时间尺度分量。另一种方法是使用剩余方差,即移位版本之间差异的方差。下面是这个想法的一个实现(不是特别优雅):

lags = -1000 : 1000;
v = nan(size(lags));
for i = 1 : numel(lags)
    lag = lags(i);
    if lag >= 0
        v(i) = var(b(1 + lag : end) - c(1 : end - lag));
    else
        v(i) = var(b(1 : end + lag) - c(1 - lag : end));
    end
end
[~, ind] = min(v);
minlag = lags(ind);
对于(较长的)数据集,这将导致
minlag=169
。绘制滞后的剩余方差,得出:


如果两个信号因非整数样本数(例如3.7个样本)而不对齐,则xcorr方法可能会在4个样本处找到最大值,它将无法找到准确的时间偏移。在这种情况下,您应该尝试一种称为“统一更改检测”的方法。该论文的网页链接为: [


祝你好运。

你的理论数据看起来怎么样?我不完全确定,但可能是你的数据中有几个周期。假设一组数据中有一个峰值在0,另一组数据中有一个峰值在5。那么5与其他数据相比应该有非常高的相关性。但是你的数据就像一个长斜率。0处的值是comparable到5中的值。这将为您提供(正如您可能已经看到的)总的来说,相关性很低。这项技术可能无论如何都会起作用,但这是我的猜测。你可以尝试不同的理论数据并进行比较。谢谢。这是我的。我印象深刻的是,即使是与随机信号振幅相同的噪声也没有问题。真实数据不是周期性的,但他的摘录有点短,但不幸的是,为了让pastebin接受它,我不得不对其进行更多的取样。谢谢你的回答。不幸的是,这种效果似乎不是普遍适用的,它在这里是随机工作的。我已经对数据进行了取样并进行了缩短,以便将其很好地放在pastebin上,这似乎不是正确的决定此示例未显示效果。采样20000后的第一个局部最大值,而偏移量约为160。非常感谢,该方法对我有效。在该实现中,合理范围(预期)所需的时间比xcov函数长得多,但它返回了预期的结果。太好了!应该可以加快速度,但现在我还不清楚如何加快速度。