离散傅里叶变换时数字信号处理中最重要的工具。三种常用用法:首先,计算信号频谱。频域表示了分量正弦波的幅度相位和频率信息。其次,根据系统的脉冲响应通过DFT可以得到系统频率响应,反之亦可。最后,DFT是某些精巧信号处理步骤中的中间步骤,例如FFT 卷积,比传统方法快很多的算法。

信号谱分析

将信息编码到正弦波中形成信号是一种常见的方法,无论是自然界中发生的信号或者是人工产生的信号。例如声音信号是人类声带振动产生的。在这种信号中时域波形并不重要,关键信息在分量正弦波的幅度,相位和频率中。可以用DFT来抽取这些信息。

假设我们想要呀就通过海洋传播的声音信号。首先将将麦克风放入水中并将得到的电信号放大到一定水平,例如几伏特。一个模拟低通滤波器用来移除所有高于80Hz的频率。因此信号可以用160Hz采样率进行数字化。当获取并存储了几千个采样点后接下来的处理呢?

首先要观察数据,下图显示实验中的256个采样点。可以看到很少的信号淹没在噪声中。下一步是用一个汉明窗乘以这个信号做平滑。这样做得到256个采样点在边沿出幅度被削减。

做DFT,并将结果转换为极坐标形式,不行的是看起来仍是噪声为主的信号,这是由于在原始的256信号采样点没有包含足够的信息,用更长的DFT并无助于问题解决。例如用2048点的DFT,频域变成了1025个采样点长。尽管初始的2048点包含更多信息,频谱更多采样点以相同因子稀释了信息。更长的DFT提供更好的频率分辨率但是相同的噪声水平。

Python中离散傅立叶变换 离散傅里叶变换结果 离散傅里叶变换的用途_频域

答案是用更多原始数据不增加频域样点,如将原始数据分成很多256点采样点段数据,每个数据段乘以汉明窗,经过256点DFT并且转换为极坐标表示形式。得到的频谱进行的平均形成了一个129点的频谱。只有频域的幅度用这种方式平均,相位一般被丢弃因为他们不包含有用信息。随机噪声一数据段数目的平方根成正比减少。

当然还有另外的方法较少频谱噪声。通过采用非常长的DFT,如16384点。得到的频谱分辨率很高,但是噪声分量也非常多。通过一个低通滤波器来平滑频谱则通过降低分辨率来减少了噪声。

我们应该用哪种方法?第一种方法更简单,因为不需要数字滤波器,第二种方法可能有更好的性能,因为数字滤波器可以在噪声和分辨率之间达到平衡。然而,改善性能的尝试得不偿失。因为通过用更多数据既可以降低噪声也可以增加分辨率。

Python中离散傅立叶变换 离散傅里叶变换结果 离散傅里叶变换的用途_时域_02

如上图显示了海底麦克风得到信号的频谱,图中展示了频谱中包含的分量。10~70Hz间平坦区域的信号包含白噪声。白噪声在各频率分量大小相同。并且在时域上噪声分量每个采样点是不相关的。高于70Hz白噪声分量迅速下降,这是由于抗混叠滤波器滤除了那些频率分量。低于10Hz噪声迅速增加是由于1/f噪声。60Hz是商业用电频率带来的噪声。25-40kHz是开关电源带来的噪声。

假设有得峰值相隔非常近,有两个因素限制频域分辨率。第一个是DFT得长度。信号做N点DFT得到的频谱包括N/2+1个采样点均匀分布在0~1/2采样频率处。为了将两个相隔很近频率分开,采样间隔必须小于两个峰值之间得间隔。例如512点DFT可以将峰值分开,而128点不可以。

Python中离散傅立叶变换 离散傅里叶变换结果 离散傅里叶变换的用途_时域_03

限制分辨率得第二个因素比较微妙。假设通过将两个只有些许不同的正弦波相加得到新的信号。在比较短得时间段内得到的信号看起来像只有一个正弦波。频率越相近,需要更多的周期才能看出来两个频率分量。换句话说,信号长度限制了频率分辨率。这个和第一个因素是不同的,因为输入信号长度不必和DFT长度相同。例如256点信号可以通过加零到2048点长度然后做2048点的DFT。加0不会改变频谱的形状,只是在频域提供了更多的采样点。尽管采样间隔变小了,但分离相隔较近峰值的能力却相比于256点DFT有一点点的改善。当DFT长度和输入性信号长度相同时,分辨率受这两个因素制约。

下一个问题,如果输入信号包含两个基函数频率之间的频率分量会如何?下图给出了答案。下图显示两个正弦波的频谱,其中一个正弦波频率与基函数相同,另一个正弦波频率在两个基函数频率之间。第一个正弦波频域用一个点表示,另外一个峰值比较难以理解,因为他不能用一个点来表示,他变成了带有拖尾的峰值扩展到相当远的距离。

解决方法是将信号乘以汉明窗然后再进行DFT。下图右边显示了结果。这样带来的结果是首先两个峰值更相似了,这是好的。其次拖尾大大减少,这也是好的。第三,窗函数通过扩展峰值宽度减小了频谱的分辨率,这是坏处。在DSP当中,常函数提供了分辨率(峰值宽度)和频谱泄露(拖尾幅度)的折中。

为了探究这些的理论基础,假设以0.1采样速率采样一个无限长离散正弦波。则频谱是无限窄的峰值。当然这在实际中无法实现。

为了处理这种情况,首先我们将信号截断,即乘以一个窗函数。例如256点的矩形窗使256个点保持原来值其他值都为0。窗函数如何影响频域呢,我们知道时域相乘对应于频域卷积。由于原始频谱是无限窄的峰值,加窗后信号频谱是窗函数的频谱移位到峰值的位置。

Python中离散傅立叶变换 离散傅里叶变换结果 离散傅里叶变换的用途_时域_04

如图中所示,这些窗函数都对原始频谱产生影响通过展开峰值并且在托韦处增加无数正弦波旁瓣分量。这是只用一部分原始时域信号带来的不可避免的结果。不同窗函数的效果是不同的。Blackman床有最宽的旁瓣,但是拖尾幅度最小。矩形窗有最窄的主瓣但是最大的拖尾。汉明窗介于两者之间。

在上图中频谱是连续曲线不是离散采样。加窗后时域信号同样是无限长的,即使大多数采样点是0。这意味着频谱在0-0.5频域处包括∞/2+1个采样点。

这带来了如何修改时域信号使其能够在计算机中表示,从信号中选择N点。N点数据必须包含所有非零点,但也可能包含任意个数的0。这有采样频谱连续波的作用。例如如果N选择1024,频谱的连续波将在0-0.5范围内采样513次。如果N选择的数值比窗长度更大,频域采样点间隔很近所以会保留尽可能多的信息。

这就引入了平顶窗,在一些应用中频谱峰值的幅度必须准确测量。由于DFT的频谱由采样点形成,无法保证峰值顶点正好在采样点上。更可能的是最近的采样点可能偏离中央。解决方法是用一个平顶窗来产生谱峰。这样的代价是主瓣非常宽,降低了频域分辨率。平顶窗的形状和滤波器核形状是相同的。

系统频率响应

系统时域分析时采用卷积,类似的分析在频域也可以进行。用傅里叶变换每个输入喜好可以表示为一组余弦波的分量,每个分量有特定的幅度和相移。类似的,DFT可以用相似的方法来代表每个输出信号。这意味着任何线性系统可以通过他的余弦分量幅度和相位如何改变来完全的描述。这种信息叫做系统的频率响应。由于脉冲响应和频率响应包含系统所有信息,两者由对应的一对一的关系。系统频率响应时脉冲响应的傅里叶变换。

Python中离散傅立叶变换 离散傅里叶变换结果 离散傅里叶变换的用途_频域_05

下图显示了用DFT将系统脉冲响应转换为频率响应的例子。脉冲响应可能不会有直观的感觉系统的作用,但转换为频率响应就可以轻易看出系统的作用。图b由于采样数较少不够平滑,通过在DFT前在脉冲响应中加0来改善这种情况。如图c和d所示。

频率响应可以获得多少的分辨率?答案是无穷高,如果脉冲响应加上无穷多个0即可。换句话说,除了DFT的长度没有其他因素限制频率分辨率。这带来一个重要概念。即使脉冲响应是离散信号,对应的频率响应也可能是连续的。

Python中离散傅立叶变换 离散傅里叶变换结果 离散傅里叶变换的用途_频域_06


要记得频率响应代表什么:余弦波通过系统的幅度和相位改变。由于输入信号可能包含0-0.5之间任意频率,系统的频率响应在这个范围内必须是连续曲线。

这可以通过引入DTFT来更好地理解。N采样点信号通过N点DFT产生N/2+1个采样点频域值。DFT将时域信号认为是无限长和周期性的。即N点信号从负无穷一直重复到正无穷。考虑当我们一开始将时域加很多0的情况。加0时域周期边长,同时使频域采样更紧密。

如果时域加上无穷多个0,这将产生不同的情况在两个方面。首先,时域信号变成了非周期信号。其次,频域采样点间隔变得无限小。即变成了连续信号。就是DTFT的过程将时域离散非周期信号变为频域连续信号。在数学中,DTFT将系统脉冲响应转换为频率响应。实际应用中用DFT来获取真实频率响应的采样。这就是计算机中的应用DFT与数学方程DTFT的差别。

频域卷积

假设你不喜欢用卷积。如果给定输入信号和脉冲响应如何得到输出信号?得以将两个信号转换为频域进行相乘人啊后再转换回时域。尽管中间步骤比较繁琐,但输出结果和直接卷积使相同的。

由于两个原因我们尽量避免卷积,首先卷积在数学上难以处理。例如,给定系统脉冲响应和输出信号如何得到输入信号?可以通过做反卷积,但是这实在是难以理解。但是在频域简单的除法就可以达到相同的结果。频域变得有吸引力是傅里叶变换大大减小了复杂度。第二个原因是计算速度。标准卷积算法速度很慢是由于大量的乘加运算。而傅里叶变换可以通过FFT来加快速度。

Python中离散傅立叶变换 离散傅里叶变换结果 离散傅里叶变换的用途_卷积_07

X[f]*H[f]=Y[f]

在极坐标表示中,输出信号幅度等于输入信号幅度乘以频率响应,而输出信号相位等于输入信号相位加上频率响应相位。

N点信号和M点脉冲响应的卷积的到N+M-1点输出信号。在上图中我们将输入信号后面加0来扩展到N+M-1点输出。

Python中离散傅立叶变换 离散傅里叶变换结果 离散傅里叶变换的用途_时域_08

上图中256点输入信号,51个非零点的脉冲响应。这两个信号的卷积有306个采样点长。问题是如果频域相乘输入和脉冲响应都是256点DFT结果也是256点。则结果进行逆DFT后得到输出信号是256点的。我们如何从这种频域算法得到的256点中得到306点的信息呢?答案是不可以。这256点的结果是正确版本的畸变输出。这个过程叫做循环卷积。这种情况要避免。

N点DFT是将时域信号看作每个周期N点的无限多周期信号。上图的d显示了频域卷积结果试图将306点正确结果放到256点的一个周期内。这将导致49个样点被推到了下一个相邻的周期。这些重叠的地方导致相加。

一旦循环卷积的特性了解了,就容易避免这种情况。简单的将要卷积的信号加入足够多的0值即可。

之前我们提过将DFT时域看作N点非周期信号或者周期信号是否有区别,现在可以给出答案是是的。如果时域信号是周期的,循环卷积的畸变可以理解为一个周期信号扩展到另一个周期。作为对比,如果只考虑时域的N个采样点,频域卷积的作用就像一个环卷起来采样点0和采样点N-1相邻。