快速傅利叶变换FFT怎么做?小白也能懂的MATLAB方法
靓仔/仙女你好,如果说高数中有一个知识你听过很多次却又不怎么懂,更不知道怎么用,那傅里叶变换必定榜上有名。大多数初次尝试的人都会隐隐觉得傅利叶变换复杂不好上手,实际上并非如此,本篇博客将会用短短一两页纸的篇幅,让你快速明白傅利叶变换的原理以及应用,让你能够从小白出发也能迅速上手,掌握这个数学神器。
1. 基本知识
大多数学生到了研究生阶段,多多少少会碰到需要做频谱分析的时候。然后查看书本,翻出了下面这个公式:
其中\(x(t)\)是一个随时间变换的量,被称为时域信号,例如一段随时间变化的电子信号。\(X(\omega)\)是被变换到频域的信号幅值,\(\omega\)就是频率。例如一个时域信号为\(x(t)=a\sin(kx)=0.5\sin(4\pi t)\),该信号实际上就是一个幅值为0.5,频率为\(\frac{k}{2\pi}=\frac{4\pi}{2\pi}=2\)的信号。所以\(X(\omega)\)只在\(\omega=2\)时为0.5,其他都为0。
然而,实际数值计算中,物理问题都是被离散的,因此产生的信号也是一个向量。那么上面公式中傅利叶变换就可以写成一个离散傅利叶变换矩阵\(F\)乘以一个离散时域信号,再除以采样个数。即:
具体关于\(F\)的线性代数的知识就不再这里介绍了,只需要知道这是个矩阵就可以了。接下来就来说说怎么用,这里用MATLAB来应用。
2. 具体应用
直接看源代码,这个例子也是我从MATLAB官方帮助文档复写下来的,很有说明性。
Fs=100; % 采样频率
L=150; % 采样个数
t=(0:L-1)/Fs; % 时间
S = 0.7*sin(2*pi*20*t)+sin(2*pi*40*t); % 时域信号
X = S + 1*randn(size(t)); % 添加随机噪动,也可以不加,下面给出二者对比图
subplot(2,1,1);
plot(t,X,'b.-'); % 画出时域信号
title("Siginal in time domain");
xlabel('t');
ylabel('X');
hold on;
% FFT 变换
Y = fft(X);
% fft()之后的频域信号的幅值还需要做一点处理才可以完全对应时域信号的幅值
P1=abs(Y);
P2=P1(1:L/2+1);
P2=P2/L;
P2(2:end-1)=P2(2:end-1)*2;
f = Fs*(0:L/2)/L;
subplot(2,1,2);
% 画出频域信号
plot(f,P2,'r.-');
title('Amplitude Spectrum of X');
xlabel('f (Hz)');
ylabel('|P2(f)|');
这段代码的含义是:将一个包含幅值等于0.7的频率为20的信号,与另一个幅值为1频率为40的信号叠加后形成的信号做离散傅利叶变换。我分别给出是否添加噪声扰动后的频域结果。没有添加噪声的信号时域和频域图:
![](https://img2022.cnblogs.com/blog/2849013/202204/2849013-20220428010048728-1171008861.png)
![](https://img2022.cnblogs.com/blog/2849013/202204/2849013-20220428010056411-341347363.png)
代码中稍微不好理解的是对时域信号做DFT变换后的处理:取频域信号的一半,并且做了缩比。这个不需要理解,我大概告诉你做么做就可以。
语句P1=abs(Y);
获得fft变换后中间量的长度。由于采样频率Fs
最多只能分辨出Fs/2
的频率,所以进行P2=P1(1:L/2+1);
操作。为了将变换后的信号幅值与时域信号幅值对应,还需要对信号做缩比,首尾信号除以离散信号采样个数L
,中间信号除以L/2
,得到最后结果。
靓仔,仙女,到了这里,离散傅利叶变换大致明白怎么使用了吧。不明白没关系,评论区交流~