识别信号之间的相移

Emm*_*bbs 18 matlab signal-processing phase

我已经生成了三个相同的波,每个波都有一个相移.例如:

t = 1:10800; % generate time vector
fs = 1; % sampling frequency (seconds)
A = 2; % amplitude
P = 1000; % period (seconds), the time it takes for the signal to repeat itself
f1 = 1/P; % number of cycles per second (i.e. how often the signal repeats itself every second).
y1 = A*sin(2*pi*f1*t); % signal 1
phi = 10; % phase shift
y2 = A*sin(2*pi*f1*t + phi); % signal 2
phi = 15; % phase shift
y3 = A*sin(2*pi*f1*t + phi); % signal 3

YY = [y1',y2',y3'];

plot(t,YY)
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

我现在想用一种方法来检测波之间的这种相移.这样做的目的是使我最终能够将该方法应用于实际数据并识别信号之间的相移.

到目前为止,我一直在考虑计算每个波和第一个波之间的交叉光谱(即没有相移):

for i = 1:3;
    [Pxy,Freq] = cpsd(YY(:,1),YY(:,i));
    coP = real(Pxy);
    quadP = imag(Pxy);
    phase(:,i) = atan2(coP,quadP);
end
Run Code Online (Sandbox Code Playgroud)

但我不确定这是否有意义.

还有其他人做过类似的事吗?对于波2和3,期望的结果应分别在10和15处显示相移.

任何意见,将不胜感激.

chi*_*tte 45

有几种方法可以测量信号之间的相移.在您的回复,您的回复下方的评论以及其他答案之间,您已经获得了大部分选项.技术的具体选择通常基于以下问题:

  • 嘈杂或干净:信号中是否有噪音?
  • 多分量或单分量:录音中是否有多种类型的信号(多个频率的多个音调向不同的方向移动)?或者,只有一个信号,就像你的正弦波示例一样?
  • 瞬时或平均:您是在寻找整个录音的平均相位滞后,还是在寻找整个录音过程中相位的变化?

根据您对这些问题的回答,您可以考虑以下技巧:

  • 互相关:使用a命令[c,lag]=xcorr(y1,y2);来获得两个信号之间的互相关.这适用于原始时域信号.您查找索引c最大值([maxC,I]=max(c);),然后以样本为单位获得滞后值lag = lag(I);.此方法为您提供整个录制的平均相位滞后.它要求您在录音中感兴趣的信号强于录音中的任何其他信号......换句话说,它对噪音和其他干扰很敏感.

  • 频域:在这里,您将您的信号到频域(使用fftcpsd或其他).然后,您将找到与您关注的频率相对应的bin,并获得两个信号之间的角度.因此,例如,如果bin#18对应于您的信号的频率,则您将获得以弧度为单位的相位滞后phase_rad = angle(fft_y1(18)/fft_y2(18));.如果您的信号具有恒定频率,这是一种很好的方法,因为它可以自然地抑制其他频率的所有噪声和干扰.您可以在一个频率上产生非常强的干扰,但您仍然可以干净地以另一个频率获取信号.对于在fft分析窗口期间改变频率的信号,该技术不是最佳的.

  • 希尔伯特变换:经常被忽视的第三种技术是通过希尔伯特变换将时域信号转换为分析信号:y1_h = hilbert(y1);.一旦你这样做,你的信号就是一个复数的向量.在时域中持有简单正弦波的矢量现在将是复数的矢量,其大小是恒定的并且其相位与原始正弦波同步变化.这种技术可以让你获得两个信号之间的瞬时相位滞后......它很强大:phase_rad = angle(y1_h ./ y2_h);或者phase_rad = wrap(angle(y1_h) - angle(y2_h));.这种方法的主要限制是您的信号需要是单声道的,这意味着您感兴趣的信号必须支配您的录音.因此,您可能必须过滤掉可能存在的任何实质性干扰.


And*_*ner 6

对于两个正弦信号,复相关系数的相位可以满足您的需求。我只能给你一个 python 示例(使用 scipy),因为我没有 matlab 来测试它。

x1 = sin( 0.1*arange(1024) )
x2 = sin( 0.1*arange(1024) + 0.456)
x1h = hilbert(x1)
x2h = hilbert(x2)
c = inner( x1h, conj(x2h) ) / sqrt( inner(x1h,conj(x1h)) * inner(x2h,conj(x2h)) )
phase_diff = angle(c)
Run Code Online (Sandbox Code Playgroud)

matlab中有一个函数corrcoeff,也应该可以工作(Python的函数丢弃了虚部)。即 c = corrcoeff(x1h,x2h) 应该在 matlab 中工作。

  • 我已经寻找了很长时间,这个隐藏的小答案非常适合我的 Python 脚本。不过有一些注意事项!`hilbert` 需要 `from scipy import signal` 使其成为 `signal.hilbert`;`inner`、`conj` 和 `angle` 需要 `import numpy` 来使它们成为 `numpy.inner`、`numpy.conj` 和 `numpy.angle`;`sqrt` 需要 `import math` 才能使其成为 `math.sqrt`。这些对某些人来说可能是显而易见的,但需要澄清。感谢你的回答! (3认同)