如何在Matlab中实现互相关操作,而不使用内置函数?

8

有人能告诉我如何在MATLAB中对两个语音信号进行交叉相关吗(每个信号都有40,000个样本),而不使用内置函数xcorr和相关系数?

提前致谢。


喜欢,但也不喜欢,http://stackoverflow.com/questions/7036628/xcorr-for-autocorrelation-with-nan-values - Alex
@jay:如果这是作业,请标记为作业。 - Amro
相关问题:使用Matlab中的FFT计算自相关 - Amro
3个回答

31

你可以使用 fft 进行交叉相关计算。两个向量的交叉相关实际上是它们各自傅里叶变换的乘积,其中一个变换被共轭。

示例:

a=rand(5,1);
b=rand(5,1);
corrLength=length(a)+length(b)-1;

c=fftshift(ifft(fft(a,corrLength).*conj(fft(b,corrLength))));

比较结果:

c =

    0.3311
    0.5992
    1.1320
    1.5853
    1.5848
    1.1745
    0.8500
    0.4727
    0.0915

>> xcorr(a,b)

ans =

    0.3311
    0.5992
    1.1320
    1.5853
    1.5848
    1.1745
    0.8500
    0.4727
    0.0915

我不能使用任何Matlab内置函数。你能给我推荐其他的东西吗? - jay
4
在你的问题中,你应该明确这一点。最初,你只是禁用了xcorr,那么在什么情况下你认为可以使用内置函数呢?2+2可以吗?plus(2,2)呢?你应该解释一下为什么有这些限制。 - user616736
我很抱歉说得不够清楚。由于我正在对两个信号进行交叉相关,每个信号有40,000个样本,这会在实时应用程序中造成一些延迟,以便处理整个40,000个样本。因此,我正在寻找其他方式,例如处理样本块而不是立即处理所有样本。我尝试进行卷积,但无法完成。 - jay
只需将数据分成较小的数据块并使用上述方法。您不需要不同的技术。对于大样本量,FFT方法比“xcorr”快得多。如果我对“a”和“b”都使用40,000个样本做上述操作,在我的计算机上需要约0.7秒。如果我简单地把它减半(即20,000个样本),那么只需要0.04秒,而对于10,000个样本,则几乎瞬间完成,仅需0.006秒。 - user616736
1
@yoda:不要使用填充信号的方法,而是使用FFT函数的第二个参数。 - Amro
@Amro 当然!我当时到底在想什么呢...谢谢。 - user616736

4

虽然Yoda已经给出了很好的答案,但我还是想提一下,以防万一。回到离散互相关的定义,你可以在不使用(太多)内置Matlab函数的情况下计算它(这应该是Matlab使用xcorr的方式)。当然,还有改进的空间,因为我没有尝试矢量化这个过程:

n=1000;
x1=rand(n,1);
x2=rand(n,1);
xc=zeros(2*n-1,1);
for i=1:2*n-1
    if(i>n)
        j1=1;
        k1=2*n-i;
        j2=i-n+1;
        k2=n;
    else
        j1=n-i+1;
        k1=n;
        j2=1;
        k2=i;
    end
    xc(i)=sum(conj(x1(j1:k1)).*x2(j2:k2));
end
xc=flipud(xc);

这与xcorr函数的结果相匹配。

更新:我忘了提到,在我的看法中,Matlab不适合实时交叉相关大数据集的处理,我宁愿尝试在C或其他编译语言中进行。


4

如果你不能使用内置的方法,也可以使用卷积代替。交叉相关是卷积没有反转的简单形式,因此为了“撤销”相关积分的反转,你可以首先在其中一个信号上应用额外的反转(这将会在卷积中被抵消掉)。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接