我不了解计算瞬时频率的原理,并且提出了很多问题。您可以在本文末尾的项目符号列表中找到它们。请原谅,这段文字可能会有点长,但是我真的想自己解决这个问题。
因此,我对实值信号x (t )的瞬时频率感兴趣。计算是借助解析信号z (t )= x (t )+ j y (t )进行的,其中y (t )是x (。
为了根据分析信号计算瞬时频率,我遵循以下论文:
Arthur E. Barns从1992年开始计算瞬时频率和瞬时带宽。在本文中,他介绍了多种计算瞬时频率的方法。我写下了他提出的所有公式(我曾经使用过)。
为了进行“学习”,我在MATLAB中试用了一个非常简单的信号,以及两个稍微复杂的信号,并希望获得它们的瞬时频率。
Fs = 1000; % sampling-rate = 1kHz
t = 0:1/Fs:10-1/Fs; % 10s 'Timevector'
chirp_signal = chirp(t,0,1,2); % 10s long chirp-signal, signal 1
added_sinusoid = chirp_signal + sin(2*pi*t*10); % chirp + sin(10Hz), signal 2
modulated_sinusoid = chirp_signal .* sin(2*pi*t*10); % chirp * sin(10Hz), signal 3
这三个信号的时域图如下所示:
在应用本文中的所有方法之后,我得到的所有瞬时频率图如下:
纯线性调频信号的 瞬时频率:添加正弦波的线性调频信号的瞬时频率: 瞬时频率:调制线性调频信号的瞬时频率: 请注意,在所有三个图像中,图3和图4的y轴都放大了,因此它们的幅度信号很小!
function [instantaneous_frequency] = f2(analytic_signal,Fs)
factor = Fs/(2*pi);
instantaneous_frequency = factor * diff(unwrap(angle(analytic_signal)));
% Insert leading 0 in return-vector to maintain size
instantaneous_frequency = [0 instantaneous_frequency];
end
在本文中,Barns现在建议(或更确切地说说是编译)从解析信号中计算瞬时频率的其他四种方法。他还提到了上式,但认为由于该阶段的歧义,因此不切实际。我猜想,他不知道该unwrap()
方法,或更确切地说,它背后的数学方法也不是。(我自己今天在查看其他有关瞬时频率的源代码时确实了解了该方法)
在他的论文中,该公式的标签为数字(2),因此,我为f(t)赋予了索引2。所有其他索引均以相同的方式与本文中的数字对应。
由于阶段性模棱两可,他宁愿建议:
function [instantaneous_frequency] = f3(analytic_signal,Fs,T)
x = real(analytic_signal);
y = imag(analytic_signal);
diff_x = diff(x);
diff_y = diff(y);
factor = Fs/(2*pi);
a = x(2:end).*diff_y;
b = y(2:end).*diff_x;
c = x(2:end).^2;
d = y(2:end).^2;
instantaneous_frequency = factor * ((a-b)./(c+d));
% Insert leading 0 in return-vector to maintain size
instantaneous_frequency = [0 instantaneous_frequency];
end
function[instantaneous_frequency] = f9(analytic_signal, Fs, T)
x = real(analytic_signal);
y = imag(analytic_signal);
factor = Fs/(2*pi*T);
a = x(1:end-T).*y(1+T:end);
b = x(1+T:end).*y(1:end-T);
c = x(1:end-T).*x(1+T:end);
d = y(1:end-T).*y(1+T:end);
instantaneous_frequency = factor.*atan((a-b)./(c+d));
% Append 0 to return-vector to maintain size
instantaneous_frequency = [instantaneous_frequency zeros(1,T)];
end
function [instantaneous_frequency] = f11(analytic_signal, Fs, T)
x = real(analytic_signal);
y = imag(analytic_signal);
factor = Fs/(4*pi*T);
a = x(1:end-2*T).*y(1+2*T:end);
b = x(1+2*T:end).*y(1:end-2*T);
c = x(1:end-2*T).*x(1+2*T:end);
d = y(1:end-2*T).*y(1+2*T:end);
instantaneous_frequency = factor.*atan((a-b)./(c+d));
% Append and insert 0s to maintain size
instantaneous_frequency = [zeros(1,T) instantaneous_frequency zeros(1,T)];
end
function [instantaneous_frequency] = formula14(analytic_signal, Fs, T);
x = real(analytic_signal);
y = imag(analytic_signal);
factor = 2*Fs/(pi*T);
a = x(1:end-T).*y(1+T:end);
b = x(1+T:end).*y(1:end-T);
c = (x(1:end-T)+x(1+T:end)).^2;
d = (y(1:end-T)+y(1+T:end)).^2;
instantaneous_frequency = factor * ((a-b)./(c+d));
% Append and insert 0s to maintain size
instantaneous_frequency = [instantaneous_frequency zeros(1,T)];
end
如本文所建议,在所有3个近似公式中,T均设置为Fs(T = Fs = 1000 = 1s)。
现在我的问题是:
- 对于纯线性调频信号,公式f2和f3返回相同的结果。我认为这很好,因为他们的计算方法相同。三种近似方法不会返回相同的结果,甚至不会返回近似值!为什么会这样?(我希望这不只是一个编程错误...)
- 尽管他们返回了相同的结果,尤其是在情节结束时,他们还是开始“摆动” 很多。对此有什么解释?我首先想到了混叠之类的东西,但是与信号的频率相比,我的采样频率很高,因此我认为可以将其排除在外。
至少f2和f3似乎适用于纯线性调频信号,但是当涉及信号中的多个频率时,包括f2和f3在内的所有方法似乎都失败了。实际上,在信号中通常具有多个频率。那么如何获得(或多或少)正确的瞬时频率呢?
- 当信号中存在多个频率时,我什至不知道会发生什么。该计算返回给定时间点的一个数字,那么当出现更多频率时,该怎么办?返回所有频率的平均值或类似的值?
我可能最重要的问题是,如何在真实而精致的软件中处理该问题?假设我想知道在1.75 s处的调制信号的瞬时频率,并且选择了方法f2,那么我可以很“幸运”并获得接近6 [Hz]的数字,这很可能是正确的答案,或者挑选我的结果旁边的几个样本,突然间我得到了一些连线,达到了很高的结果,因为不幸的是我在峰值中选择了一个值。如何处理?通过使用均值甚至更好的中值滤波器对其进行后处理?我认为即使如此,也可能会变得非常困难,尤其是在许多峰值彼此相邻的区域。
最后一个不是那么重要的问题,为什么我发现有关瞬时频率的大多数论文都来自地理领域,尤其是在计算地震等地震事件时。巴恩的论文也以此为例。瞬时频率在很多地方不是很有趣吗?
到目前为止,就我的每一个答复,我都非常感谢,尤其是当有人给我有关如何在实际软件项目中实现它的提示时;)
亲切的问候,帕特里克