离散傅里叶变换的应用之一——用FFT分析信号频谱
题目如下:
欲解此题,关键掌握以下几点:
第一,分清“截取数据长度”(即窗函数长度)与“DFT点数”二者的不同;
第二,能够根据模拟频率推断出DFT谱峰处对应的序号k的数值,方法如下:
首先,由模拟频率转换为数字域频率:
图1
然后,数字域频率对应到DFT的序号k
图2
综合以上两式,得到:
图3
【题目分析与解答】
我们按照DFT分析信号频谱的三个步骤来分别求解:
第一步:采样。所以首先,我们写出采样后离散时间信号的表达式:
其周期为10。
第二步:时域加窗(即截取)
截取10点长,相当于将该周期信号x(n)与10点长的矩形窗相乘,得到v(n),所以我们求v(n)的DTFT。
图4
图5
注意,上图中只画出了[-Π,Π] 区间的图形,实际上DTFT是以2Π为周期的(所以吓人的公式中有西格玛求和符号)。
第三步:频域抽样,也就是对V(e^jw)在 [0,2Π] 区间抽取N个点(N为DFT点数,而非第二步中截取的长度)
再次把狐假虎威的公式摆出来(因为有些同学有强迫症,非要看看公式长什么样,注意,要先把图4中的V(e^jw)的西格玛求和符号去掉,只取0~2Π区间的,所以,后面一项是w-2Π/5+2Π,也就是w+8Π/5,然后再把w变成2Πk/N)(在4月28日发的文章中,下面这个公式写错了,没有人给我提出来。看来你们都没仔细看公式。)
图6
其实V(k) 就是下图中的红点点啦。
图7
好了,那么最后的问题就是,N取不同值时(也就是做不同点数的DFT)这些红点点显然也不同。对于此题来说,这三种N的取值(10、20、128)得到的结果到底是什么呢?
你看到或者听到这里的话,暂停一下,自己算算呗。
我直接把matlab画图的结果给出来。
用前面的公式算一下:f=kfs/N,最后那个128点DFT的图,最高的谱峰序号k是多少?
图8
最后附上matlab程序。
clc;clear all;
f0=1;fs=5;%单位:Hz
n=0:1000;L=10;
xn=cos(2*pi*f0*n/fs);%时域离散时间信号
Xk1=fft(xn(1:L),10);
Xk2=fft(xn(1:L),20);
Xk3=fft(xn(1:L),128);
subplot(311);stem((0:length(Xk1)-1),abs(Xk1));title('10点DFT');
subplot(312);stem((0:length(Xk2)-1),abs(Xk2));title('20点DFT');
subplot(313);stem((0:length(Xk3)-1),abs(Xk3));title('128点DFT');
下面分析一下:
首先看N=10时,此时的结果看似最为干净清爽,只有干干净净两根线。但有的同学要问了,单频信号,只有一个频率成分,应该只有一根谱线呀?为什么会有两根?
我们先看第一根,k=2那个谱线,对应频率为2*fs/10=2*5/10=1Hz,与题设cos(2Πt)完全吻合。k=8那根谱线是怎么一回事呢?是负频率周期延拓过去的,本来在-2,-2+10就等于8了。所以,(敲黑板,以下结论很重要)
对实信号做N点DFT,我们只需要看前N/2根谱线就行了,不用关注N/2~N-1之间的。
再看N=20和N=128的DFT结果,怎么出来那么多根谱线呢?
回过头去看一看,做DFT之前的截取L点长的序列cos(2Πn/5)的频谱到底是什么样子呢?是图7中的虚线所示。而N点DFT,是对V(e^jw)在 [0,2Π] 区间抽取N个点。相当于把连续的频谱图(V(e^jw),如图7中的虚线所示),用一张不透明的纸盖住,纸上以2Π/N为间隔开了一些缝,露出来的点才是我们得到的DFT的结果。这就是频域抽样产生的”栅栏效应“。
所以,不管是10点DFT干干净净的两根线,还是128点DFT密密麻麻的那么多根线,背后隐藏的,都是连续的频谱函数。之所以10点DFT的结果看起来更顺眼,无非是因为因为2Π/N也恰好是旁瓣的宽度(因为信号的周期和截取长度也是10)
在DFT谱分析中,当DFT点数N大于数据本身的实际点数L时,相当于在数据后面补上了L-N个0再做DFT,称为“补零DFT“。补零经常是必要的,补零相当于对信号频谱以更小的间隔采样,得到更多的频谱的信息。而且有时数据长度不是2的整数次幂,如果我们想采用基2FFT算法,就必须进行补零。
此题以单频周期信号为例,展示了不同点数DFT时结果的不同。给人一种错觉:补零,似乎没带来任何好处,反倒是点数最少的10点DFT的结果最好看。
是不是这样呢?当然了,如果你知道这个周期信号的周期是多少,毫无疑问,就截取一个周期的数据,做同样点数的DFT,结果最好看。但在分析实际问题时,要么信号根本没有周期性;要么虽然有周期性,但你不知道;而且实际信号也不会是简单的单频信号,会包含多个频率分量。这个时候,在系统性能、实时性、存储量等等容许的范围内,截取尽量长的数据(即获取更多的信息,得到更高的频率分辨率,下一篇会专门讲频率分辨率),做尽量多点数的DFT(即对频谱进行更为精细的采样)。
而且,实际应用中,由于DFT的点数一般都比较大,我们一般不会以离散的形式画频谱图,而是直接将频谱图化成连续的曲线。例如,上例中,我们截取128点长的数据,做128点DFT,用连续曲线形式画图(matlab中为plot函数),并且只画出前一半(即0~N/2-1)的点,并且把横轴直接转换为Hz,如下图所示:
Matlab代码如下:
上图中,横轴单位为:Hz。采用如下公式,将序号k转换为模拟频率Hz:
DFT分析信号频谱,是实际中应用最广泛的数字信号处理算法,还有很多种题目可以出。还是那句话,题目无穷无尽,而原理就那么多,大家只有掌握了其真正含义,才能以不变应万变。
全部0条评论
快来发表一下你的评论吧 !