基于互相关实现不同采样率信号的对齐方法求助
不同采样率带时间向量的信号互相关对齐问题
我需要用互相关对齐两个相似但存在时间偏移的信号,但现有方案不适用,因为两个信号采样率不同,且输入包含对应的时间向量。原本尝试插值到同一采样率后用互相关,但计算出的偏移量错误(预期7秒,得到-4.8秒)。
我的尝试步骤
- 构造带偏移的不同采样率信号
import matplotlib.pyplot as plt import numpy as np from scipy.signal import correlate from scipy.interpolate import interp1d dt1 = 2.4 t1 = np.arange(0,20,dt1) y1 = np.sin(t1) + t1/10 dt2 = 1 t2 = np.arange(0,20,dt2) y2 = np.sin(t2) + t2/10 offset_t2 = 7 # 需要恢复的偏移量 t2 = t2 + offset_t2
- 插值到同一低采样率时间轴
max_dt = max(dt1,dt2) t1_resampled = np.arange(t1[0],t1[-1],max_dt) t2_resampled = np.arange(t2[0],t2[-1],max_dt) y1_resampled = interp1d(t1,y1)(t1_resampled) y2_resampled = interp1d(t2,y2)(t2_resampled)
- 互相关计算偏移量(结果错误)
fig,axs=plt.subplots(2,1) ax = axs[0] ax.plot(t1,y1,"-o",label='y1') ax.plot(t2,y2,"-o",label='y2') xcorr = correlate(y1_resampled,y2_resampled) argmax_index = np.argmax(xcorr) shift = (argmax_index-(len(y2_resampled)+1))*max_dt ax.plot(t2+shift,y2,"-o",label='y2 shifted') ax = axs[1] ax.plot(xcorr) ax.scatter(argmax_index,xcorr[argmax_index],color='red') axs[0].legend() print(f"computed shift: {shift}\nexpected shift: {offset_t2}")

问题核心
插值后互相关计算偏移的公式错误,且未考虑两个信号时间轴起始点的差异,导致偏移量计算完全偏离预期。
修正方案
关键要点
- 将两个信号插值到同一全局时间轴(覆盖两个信号的时间范围),而非各自独立的时间轴
- 正确计算互相关对应的时间偏移:互相关的索引偏移需要映射到实际时间偏移,同时结合原始时间轴的起始差
完整实现的shift函数
def shift(t1, y1, t2, y2): # 确定覆盖两个信号的全局时间范围 t_min = min(t1[0], t2[0]) t_max = max(t1[-1], t2[-1]) # 使用较高采样率(更小的dt)提升对齐精度,取两个采样率的最小值 dt = min(np.mean(np.diff(t1)), np.mean(np.diff(t2))) # 生成统一的时间轴 t_common = np.arange(t_min, t_max, dt) # 插值到统一时间轴,超出原始范围的部分填充0 f1 = interp1d(t1, y1, bounds_error=False, fill_value=0) f2 = interp1d(t2, y2, bounds_error=False, fill_value=0) y1_common = f1(t_common) y2_common = f2(t_common) # 计算全模式互相关,覆盖所有可能偏移情况 xcorr = correlate(y1_common, y2_common, mode='full') # 获取互相关最大值的索引 argmax_idx = np.argmax(xcorr) # 转换为样本偏移量:full模式下偏移范围为[-(N-1), M-1],N为y2长度,M为y1长度 sample_shift = argmax_idx - (len(y2_common) - 1) # 样本偏移转时间偏移 delta_t = sample_shift * dt return delta_t
验证代码
# 调用函数计算偏移量 delta_t = shift(t1, y1, t2, y2) print(f"computed shift: {delta_t:.2f}") print(f"expected shift: {offset_t2}") # 绘图验证信号对齐效果 fig, ax = plt.subplots() ax.plot(t1, y1, "-o", label='y1') ax.plot(t2 + delta_t, y2, "-o", label='y2 shifted') ax.legend() plt.show()
解释
- 统一时间轴确保两个信号在相同的时间点上进行比较,避免了各自时间轴起始点不同的干扰
- 使用
mode='full'计算互相关,能覆盖所有可能的偏移情况,不会遗漏有效对齐位置 - 样本偏移量直接乘以统一时间轴的步长
dt,即可得到准确的时间偏移量delta_t
参考文献
- Use of pandas.shift() to align datasets based on scipy.signal.correlate
- Python aligning, stretching and synchronizing array data in python (signal processing)
- Python cross correlation - why does shifting a timeseries not change the results (lag)?
内容的提问来源于stack exchange,提问作者Thomas
相关产品推荐
相关产品推荐

