xcorr与finddelay延迟计算输出结果不一致的原因
Matlab互相关延迟检测异常问题分析
复现代码
fs = 1.0e4; t = 0:1/fs:0.005; signal = cos(2*pi*1000*t)'; shifted_signal = delayseq(signal,5); subplot(2,1,1) plot(t.*1000,signal) title('Input') subplot(2,1,2) plot(t.*1000,shifted_signal) title('5 Sample Delay') xlabel('msec') [c, lags]=xcorr(signal,shifted_signal); [A,I]=max(abs(c)); figure (2) plot(lags,c); d1=finddelay(signal,shifted_signal); d2=lags(I);
异常现象
运行上述代码会得到两个和预期不符的结果:
- 取
xcorr互相关绝对值峰值对应的延迟值d2=-5,和预期的5个采样点延迟符号相反 finddelay函数返回的延迟值d1=0,完全不符合预设的5采样点延迟
具体原因
两个异常分别由函数定义理解偏差、测试参数踩坑导致:
1. xcorr返回-5的原因
这个结果完全符合函数定义,不存在计算错误:xcorr(x,y)的互相关计算公式为 $R_{xy}[k] = \sum_n x[n+k] \cdot y^*[n]$,返回的lags(k)对应的物理意义是:y序列固定,将x序列向左移动k个采样点后,两个序列的相似程度。
测试中的shifted_signal是原信号向右延迟5个采样点得到的,即满足shifted_signal[n] = signal[n-5],代入公式可以推导得到互相关峰值出现在k=-5的位置。如果需要得到正的5作为结果,只需要调换输入顺序,调用xcorr(shifted_signal, signal)即可。
2. finddelay返回0的原因
这个问题是测试参数刚好命中了函数的检测逻辑盲区:
- 首先信号参数存在特殊对应关系:采样率为1e4Hz,信号频率为1000Hz,因此余弦信号的周期恰好为10个采样点,延迟5个采样点刚好对应半个信号周期,延迟后的信号和原信号完全反相,即
shifted_signal[n] = -signal[n-5]。 - 其次
finddelay的默认检测逻辑是寻找互相关的正最大值作为匹配位置,不会考虑负的相关峰值。而真实延迟位置(lag=-5)的相关值是负的,不会被判定为有效匹配。 - 最后
delayseq生成整数延迟信号时,会在序列头部补对应数量的零、尾部截断超出原长度的部分,破坏了余弦信号的严格周期性,最终互相关的正最大值恰好出现在lag=0位置,因此返回0。
验证方法
任意修改一个参数打破半周期延迟的特殊条件即可复现正确结果,比如将信号频率改为1001Hz,或者将延迟采样数改为4,重新运行就会发现finddelay可以返回正确的延迟值。
内容的提问来源于stack exchange,提问作者Mrinmoyee Mukherjee
相关产品推荐
相关产品推荐

