从互相关中查找信号或相位延迟

Find signal or phase delay from cross correlation

我正在使用 python,但这是一个一般性问题(与算法等更相关),因此我跳过了一些步骤以了解问题的要点:

我生成这样的正弦信号:

import math as m
signal = [m.sin(2*m.pi*1*(t/n-d)) for t in range(n)]

所以一个正弦信号,归一化后,频率为 1,时间从 0 到 1 秒(所以基本上是一个简单的正弦波周期)。还有一个延迟项 d,它会延迟信号(导致相移)。 n只是样本数

我还创建了另一个信号,但有另一个延迟。假设我对第一个信号使用 0 延迟,对第二个信号使用 x 延迟(为了清楚起见,我缩写为 previous):

signal1 = signal(delay=0)
signal2 = signal(delay=x)

然后我做一个相关:

from scipy import signal as sgn
corr11 = sgn.correlate(signal1, signal1, mode = 'full')
corr12 = sgn.correlate(signal1, signal2, mode = 'full')

我也知道信号延迟与相关点的最大值相关,所以我取出两点:

import numpy as np

a1 = np.argmax(corr11)
a2 = np.argmax(corr12)

所以我发现信号与自身的相关性在相关性数组的中间有最大峰值(或 plot/function)。但是另一个峰很奇怪:

所以问题是,延迟 d 与信号相关后的峰值位置有何关系?

似乎延迟大约等于(a1 - a2) / n。但是,我认为答案有些扭曲,因为 a) 您只使用一个周期的正弦波,并且 b) 您使用的数据点数量有限(显然)。为了对单周期正弦波的情况获得更准确的答案,您可能希望获得相关性的数学定义并使用正确的限制进行必要的整合(但我不确定 SO 是正确的地方寻求集成方面的帮助)。

这是一个 self-contained 脚本,它绘制了信号和相关性,希望能提供更多直觉。注意:当您重复正弦波的周期数时,我上面给出的近似值似乎会变得更准确。例如,对于 100 个周期和 100000 个数据点,上面的近似值(此处修改为 n_repeats * (a1 - a2) / n)似乎变得更加准确。

脚本

import numpy as np
from scipy import signal
import matplotlib.pyplot as plt

# Set parameters

# x = 0.5
x = 0.28328
# x = 0.25
# x = 0.1
# n = 100000
# n_repeats = 100
n = 1000
n_repeats = 1

# Get correlations
t = np.linspace(0, n_repeats, n)

sin_delay = lambda delay: np.sin(2.0 * np.pi * (t - delay))

signal1 = sin_delay(delay=0)
signal2 = sin_delay(delay=x)

corr11 = signal.correlate(signal1, signal1, mode = 'full')
corr12 = signal.correlate(signal1, signal2, mode = 'full')

a1 = np.argmax(corr11)
a2 = np.argmax(corr12)

# Print output
print(a1, a2, x, n_repeats * (a1 - a2) / n)

# Make plots
plt.figure()
plt.plot(signal1, "r")
plt.plot(signal2, "b")
plt.title("Signals, delay = {:.3f}".format(x))
plt.legend(["Original signal", "Delayed signal"], loc="upper right")
plt.grid(True)
plt.savefig("Signals")
plt.figure()
plt.plot(corr11, "r")
plt.plot(corr12, "b")
plt.title("Correlations, delay = {:.3f}".format(x))
plt.legend(["Auto-correlation", "Cross-correlation"], loc="upper right")
plt.grid(True)
plt.savefig("Correlations")

控制台输出 n = 1000, n_repeats = 1

999 749 0.28328 0.25

控制台输出 n = 100000, n_repeats = 100

99999 99716 0.28328 0.283

输出图像 n = 1000, n_repeats = 1