FFT的那些细节

用MATLAB进行谱分析时注意:
例:

N=8;
n=0:N-1;
xn=[4 3 2 6 7 8 9 0];
Xk=fft(xn)


Xk =

39.0000 -10.7782 + 6.2929i 0 - 5.0000i 4.7782 - 7.7071i 5.0000 4.7782 + 7.7071i 0 + 5.0000i -10.7782 - 6.2929i

(1)Xk与xn的维数相同,共有8个元素。Xk的第一个数对应于直流分量,即频率值为0。
(2)对周期信号做FFT分析时,幅值大小与FFT选择的点数有关,但不影响分析结果。在IFFT时已经做了处理。要得到真实的振幅值的大小,只要将得到的变换后结果乘以2除以N即可。这里指的是单边谱,如果是双边谱则是除以N。
(3)对非周期信号做FFT分析时,如果是双边边谱求得fft后/N是傅里叶级数,在傅里叶变换的频谱上体现是极小量,所以傅里叶变换的频谱指的是频谱密度,需要再除以f0=fs/N=1/NTs,所以是fft后/N再除以f0,最终是fft结果乘以Ts采样间隔。attention N是信号点数

例1:x=0.5sin(2pi15t)+2sin(2pi40t)。采样频率fs=100Hz,分别绘制N=128、1024点幅频图。

clf;
Ts=0.01;N=128;   %采样频率和数据点数
fs=1/Ts;
n=0:N-1;t=n*Ts;   %时间序列
x=0.5*sin(2*pi*15*t)+2*sin(2*pi*40*t); %信号
y=fft(x,N);    %对信号进行N点快速Fourier变换(这里的Nfft是等于Ndata的,Nfft<Ndata就是截断,>就是补零)
mag=abs(y);     %求得Fourier变换后的振幅
f=n*fs/N;    %频率序列 单位为Hz 
subplot(2,2,1),plot(f,mag);   %绘出双边谱随频率变化的振幅
axis([0 100 0 150]);
xlabel('频率/Hz');
ylabel('振幅');title('N=128');grid on;
subplot(2,2,2),plot(f(1:N/2),2/N*mag(1:N/2)); %绘出Nyquist频率之前随频率变化的振幅,单边谱,看真实幅值
axis([0 60 0 2]);
xlabel('频率/Hz');
ylabel('振幅');title('N=128');grid on;
%对信号采样数据为1024点的处理
Ts=0.01;N=1024;n=0:N-1;t=n*Ts;fs=1/Ts;
x=0.5*sin(2*pi*15*t)+2*sin(2*pi*40*t); %信号
y=fft(x,N);   %对信号进行快速Fourier变换
mag=abs(y);   %求取Fourier变换的振幅
f=n*fs/N;
subplot(2,2,3),plot(f,mag); %绘出随频率变化的振幅
xlabel('频率/Hz');
ylabel('振幅');title('N=1024');grid on;
subplot(2,2,4)
plot(f(1:N/2),2/N*mag(1:N/2)); %绘出Nyquist频率之前随频率变化的振幅
axis([0 60 0 2]);
xlabel('频率/Hz');
ylabel('振幅');title('N=1024');grid on;

在这里插入图片描述
fs=100Hz,Nyquist频率为fs/2=50Hz。整个频谱图是以Nyquist频率为对称轴的。并且可以明显识别出信号中含有两种频率成分:15Hz和40Hz。由此可以知道FFT变换数据的对称性。因此用FFT对信号做谱分析,只需考察0到Nyquist频率范围内的幅频特性,若没有给出采样频率和采样间隔,则分析通常对归一化频率0到1。
另外,振幅的大小与所用采样点数有关,采用128点和1024点的相同频率的振幅是有不同的表现值,但在同一幅图中,40Hz与15Hz振动幅值之比均为4:1,与真实振幅0.5:2是一致的。为了与真实振幅对应,需要将变换后结果乘以2除以N(单边谱)。变换之后40Hz小于2,15Hz小于0.5的原因是频谱泄漏。不是整周期截断,可看我的另一CSDN关于补零与频谱泄漏。
补零与频谱泄漏栅栏效应频谱分辨率

例2:x=0.5sin(2pi15t)+2sin(2pi40t),fs=100Hz,绘制:
(1)数据个数N=32,FFT所用的采样点数NFFT=32;
(2)N=32,NFFT=128;
(3)N=136,NFFT=128;
(4)N=136,NFFT=512。


clf;fs=100; %采样频率
Ndata=32; %数据长度
N=32; %FFT的数据长度
n=0:Ndata-1;t=n/fs;   %数据对应的时间序列
x=0.5*sin(2*pi*15*t)+2*sin(2*pi*40*t);   %时间域信号
y=fft(x,N);   %信号的Fourier变换
mag=abs(y);    %求取振幅
f=(0:N-1)*fs/N; %真实频率
subplot(2,2,1),plot(f(1:N/2),mag(1:N/2)*2/Ndata); %绘出Nyquist频率之前的振幅(真实单边谱)
xlabel('频率/Hz');ylabel('振幅');
title('Ndata=32 Nfft=32');grid on;

Ndata=32;   %数据个数
N=128;     %FFT采用的数据长度
n=0:Ndata-1;t=n/fs;   %时间序列
x=0.5*sin(2*pi*15*t)+2*sin(2*pi*40*t);
y=fft(x,N);
mag=abs(y);
f=(0:N-1)*fs/N; %真实频率
subplot(2,2,2),plot(f(1:N/2),mag(1:N/2)*2/Ndata); %绘出Nyquist频率之前的振幅
xlabel('频率/Hz');ylabel('振幅');
title('Ndata=32 Nfft=128');grid on;

Ndata=136;   %数据个数
N=128;     %FFT采用的数据个数
n=0:Ndata-1;t=n/fs; %时间序列
x=0.5*sin(2*pi*15*t)+2*sin(2*pi*40*t);
y=fft(x,N);
mag=abs(y);
f=(0:N-1)*fs/N;   %真实频率
subplot(2,2,3),plot(f(1:N/2),mag(1:N/2)*2/Ndata); %绘出Nyquist频率之前的振幅
xlabel('频率/Hz');ylabel('振幅');
title('Ndata=136 Nfft=128');grid on;

Ndata=136;    %数据个数
N=512;    %FFT所用的数据个数
n=0:Ndata-1;t=n/fs; %时间序列
x=0.5*sin(2*pi*15*t)+2*sin(2*pi*40*t);
y=fft(x,N);
mag=abs(y);
f=(0:N-1)*fs/N;   %真实频率
subplot(2,2,4),plot(f(1:N/2),mag(1:N/2)*2/Ndata); %绘出Nyquist频率之前的振幅
xlabel('频率/Hz');ylabel('振幅');
title('Ndata=136 Nfft=512');grid on;


(1)当数据个数和FFT采用的数据个数均为32时,频率分辨率较低,但没有由于添零而导致的其他频率成分。
(2)由于在时间域内信号加零,致使振幅谱中出现很多其他成分,这是加零造成的。其振幅由于加了多个零而明显减小,谱更细致,泄露的更多,所以真正想要的40 15Hz的幅值小于实际。
(3)FFT程序将数据截断,这时分辨率较高,本身的数据点也多。只要是fft肯定避免不了时域截断,所以避免不了频域频谱泄漏,这种误差可以通过加合适的窗函数或延长时间窗得以改善,对于周期信号,可以整周期截断从源头上遏制频谱泄漏。
(4)也是在数据的末尾补零,但由于含有信号的数据个数足够多,FFT振幅谱也基本不受影响。
对信号进行频谱分析时,数据样本应有足够的长度,一般FFT程序中所用数据点数与原含有信号数据点数相同,这样的频谱图具有较高的质量,可减小因补零或截断而产生的影响

例3:x=cos(2pi0.24n)+cos(2pi0.26n)

clf;fs=1; %采样频率
Ndata=10; %数据长度
N=10; %FFT的数据长度
n=0:Ndata-1;t=n/fs;   %数据对应的时间序列
x=cos(2*pi*0.24*t)+cos(2*pi*0.26*t);   %时间域信号
subplot(2,3,1),stem(t,x);
y=fft(x,N);   %信号的Fourier变换
mag=abs(y);    %求取振幅
f=(0:N-1)*fs/N; %真实频率
subplot(2,3,4),plot(f(1:N/2),mag(1:N/2)*2/Ndata); %绘出Nyquist频率之前的振幅(真实单边谱)
axis([0 0.5 0 1.5]);
xlabel('频率/Hz');ylabel('振幅');
title('Ndata=32 Nfft=32');grid on;

Ndata=10;   %数据个数
N=100;     %FFT采用的数据长度
n=0:Ndata-1;t=n/fs;   %时间序列
x1=cos(2*pi*0.24*t)+cos(2*pi*0.26*t);
x=zeros(1,N);
x(1:Ndata)=x1;
n=0:N-1;t=n/fs;   %时间序列
subplot(2,3,2),stem(t,x);
y=fft(x,N);
mag=abs(y);
f=(0:N-1)*fs/N; %真实频率
subplot(2,3,5),plot(f(1:N/2),mag(1:N/2)*2/Ndata); %绘出Nyquist频率之前的振幅
axis([0 0.5 0 2]);
xlabel('频率/Hz');ylabel('振幅');
title('Ndata=32 Nfft=128');grid on;

Ndata=100;   %数据个数
N=100;     %FFT采用的数据个数
n=0:Ndata-1;t=n/fs; %时间序列
x=cos(2*pi*0.24*t)+cos(2*pi*0.26*t);
subplot(2,3,3),stem(t,x);
y=fft(x,N);
mag=abs(y);
f=(0:N-1)*fs/N;   %真实频率
subplot(2,3,6),plot(f(1:N/2),mag(1:N/2)*2/Ndata); %绘出Nyquist频率之前的振幅
axis([0 0.5 0 1.5]);
xlabel('频率/Hz');ylabel('振幅');
title('Ndata=136 Nfft=128');grid on;

在这里插入图片描述
(1)数据点过少,几乎无法看出有关信号频谱的详细信息;
(2)中间的图是将x(n)补90个零,幅度频谱的数据相当密,称为高密度频谱图。但从图中很难看出信号的频谱成分。
(3)信号的有效数据很长,可以清楚地看出信号的频率成分,一个是0.24Hz,一个是0.26Hz,称为高分辨率频谱。
可见,采样数据过少,运用FFT变换不能分辨出其中的频率成分。添加零后可增加频谱中的数据个数,谱的密度增高了,但仍不能分辨其中的频率成分,即谱的分辨率没有提高。只有数据点数足够多时才能分辨其中的频率成分。

  • 2
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值