我生成了三个相同的波,每个波都有相移。例如:
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)
我现在想使用一种方法来检测波之间的这种相移。这样做的目的是让我最终可以将该方法应用于实际数据并识别信号之间的相移。
到目前为止,我一直在考虑计算每个波与第一个波之间的交叉光谱(即没有相移):
for i = 1:3;
[Pxy,Freq] = cpsd(YY(:,1),YY(:,i));
coP = real(Pxy);
quadP = imag(Pxy);
phase(:,i) = atan2(coP,quadP);
end
但我不确定这是否有意义。
有没有人做过类似的事情?期望的结果应该显示第 2 波和第 3 波的相移分别为 10 和 15。
如有任何建议,我们将不胜感激。
最佳答案
您可以通过多种方式测量信号之间的相移。在您的回复、您回复下方的评论和其他答案之间,您已经获得了大部分选项。技术的具体选择通常基于以下问题:
- 嘈杂还是干净:您的信号中是否有噪音?
- 多分量或单分量:您的录音中是否有不止一种类型的信号(多个频率的多个音调向不同方向移动)?或者,是否只有一个信号,就像在您的正弦波示例中一样?
- 瞬时或平均:您是要寻找整个录音的平均相位滞后,还是要跟踪整个录音中相位的变化?
根据您对这些问题的回答,您可以考虑以下技术:
Cross-Correlation:使用像
[c,lag]=xcorr(y1,y2);
这样的命令来获得两个信号。这适用于原始时域信号。您寻找c
最大的索引 ([maxC,I]=max(c);
),然后您得到以样本为单位的滞后值滞后=滞后(我);
。这种方法为您提供了整个录音的平均相位滞后。它要求您在录音中感兴趣的信号比录音中的任何其他信号都强……换句话说,它对噪音和其他干扰很敏感。频域:在这里您可以将信号转换为频域(使用
fft
或cpsd
或其他)。然后,您会找到与您关心的频率相对应的 bin,并获得两个信号之间的角度。因此,例如,如果 bin #18 对应于您的信号频率,您将通过phase_rad = angle(fft_y1(18)/fft_y2(18));
获得以弧度为单位的相位滞后。如果您的信号具有恒定频率,这是一种极好的方法,因为它自然会拒绝其他频率的所有噪声和干扰。你可以在一个频率上有非常强的干扰,但你仍然可以在另一个频率上干净地得到你的信号。对于在 fft 分析窗口期间改变频率的信号,此技术不是最佳方法。Hilbert 变换:经常被忽视的第三种技术是通过 Hilbert 变换将时域信号转换为解析信号:
y1_h = hilbert(y1);
。一旦你这样做了,你的信号就是一个复数向量。在时域中包含一个简单正弦波的矢量现在将是一个复数矢量,其幅度恒定且相位与原始正弦波同步变化。这种技术允许您获得两个信号之间的瞬时相位滞后......它很强大:phase_rad = angle(y1_h ./y2_h);
或phase_rad = wrap(angle(y1_h) - angle (y2_h));
。这种方法的主要限制是您的信号必须是单分量信号,这意味着您感兴趣的信号必须主导您的录音。因此,您可能必须过滤掉可能存在的任何实质性干扰。
关于matlab - 识别信号之间的相移,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27545171/