频域增强这个词,刚入行的朋友听起来容易觉得玄乎,其实它解决的是一个特别朴素的问题:有些信息在原始信号里被噪声盖住了,或者被低频漂移压住了,你在时域上怎么调都别扭,但换到频域一看,问题一目了然。傅里叶变换就是那把把时间轴换成频率轴的钥匙,高频增强和低频降噪则是拿到频谱之后最常用的两把刀。这篇内容我打算从工程落地的角度,把傅里叶变换的基础、FFT的实操细节、高频增强和低频降噪的具体做法,以及我在实际项目里踩过的坑,完整地捋一遍。适合已经有一点信号处理基础、想把频域方法真正用起来的读者,也适合刚接触FFT、被公式绕晕想找个接地气解释的朋友。
1. 从时域到频域:傅里叶变换到底在做什么
1.1 一个生活化的理解方式
很多人第一次看傅里叶变换公式,脑子里全是积分符号,完全抓不住重点。我习惯用一个类比来解释:你把一杯混合果汁倒进一个分液漏斗,经过层层分离,最后得到糖、水、果酸、色素各自的含量。傅里叶变换干的就是这件事,只不过它分离的不是化学成分,而是信号里不同频率成分的“含量”。
时域信号告诉你“某个时刻信号幅值是多少”,频域信号告诉你“整个信号里,频率为f的分量有多强、相位是多少”。这两个视角描述的是同一个东西,只是坐标系不同。你在时域上看到一条上下抖动的曲线,换到频域可能就变成几根干净的谱线,噪声和有用信号各占一块地盘,处理起来思路立刻清晰。
这里有个关键点必须说清楚:傅里叶变换的前提是信号可以分解为一系列正弦波的叠加。这个假设对绝大多数工程信号都成立,包括音频、振动、电流、雷达回波等等。所以它不是数学家的玩具,而是工程上真正能用的工具。
1.2 连续傅里叶变换与离散傅里叶变换的分工
连续傅里叶变换处理的是连续时间信号,公式里是积分。但实际工程中,我们拿到的是采样后的离散数据,用的是离散傅里叶变换,也就是DFT。DFT的公式是求和,不是积分,这一点对写代码的人特别重要,因为求和意味着可以直接在计算机上算。
DFT的定义是这样的:对于长度为N的序列x[n],它的DFT为X[k] = Σ x[n] * exp(-j2πkn/N),其中n从0到N-1,k也从0到N-1。这个公式看起来复杂,但拆开看就是:把每个采样点和一组旋转因子相乘再累加。旋转因子exp(-j2πkn/N)本质上是在复平面上转圈,不同的k对应不同的转速,转速快的对应高频,转速慢的对应低频。
这里有个容易混淆的地方:DFT的输出X[k]是复数,它的模值|X[k]|代表该频率分量的幅度,角度arg(X[k])代表相位。很多人只看幅度谱,忽略相位谱,这在做滤波时问题不大,但如果你要做信号重构或者相位相关的分析,相位信息绝对不能丢。
1.3 为什么工程上几乎都用FFT而不是直接算DFT
直接按DFT公式算,复杂度是O(N²)。N等于1024时,大概要算一百万次复数乘法;N等于4096时,就是一千六百万次。这个量级在实时系统里根本扛不住。FFT,也就是快速傅里叶变换,通过分治策略把复杂度降到O(N log N)。同样是N等于4096,FFT只需要大概五万次运算,差了三百多倍。
FFT的核心思想是:一个长度为N的DFT可以拆成两个长度为N/2的DFT,一个处理偶数索引,一个处理奇数索引,然后通过蝶形运算合并。这个拆分可以递归进行,直到长度为2。所以FFT要求N通常是2的幂,比如256、512、1024、2048、4096。如果你的数据长度不是2的幂,可以补零到最近的2的幂,或者用混合基FFT算法。
补零这件事有个细节要注意:补零不会提高频率分辨率,它只是让频谱的采样点更密,看起来更平滑。真正的频率分辨率取决于实际采样时长,也就是N乘以采样间隔。这个坑我在后面还会展开讲。
2. FFT实操中的关键参数与常见陷阱
2.1 采样率、点数与频率分辨率的三角关系
做频域分析,有三个参数你必须先确定:采样率fs、采样点数N、频率分辨率Δf。它们的关系是Δf = fs / N。这个公式看起来简单,但实际选参数时经常顾此失彼。
举个例子,你要分析一段音频,关心的频率范围是0到4000Hz,那采样率至少要8000Hz,按奈奎斯特准则实际会取略高一点,比如8192Hz。如果你想要1Hz的频率分辨率,那N至少要8192点,对应的时间长度是1秒。如果你只有0.5秒的数据,N等于4096,分辨率就是2Hz。这时候你硬要1Hz分辨率,只能补零到8192,但补零后的频谱只是插值,真实的频率分辨能力还是2Hz。
我在实际项目里见过有人补零到很大点数,然后指着频谱上两个很近的峰说“你看分辨出来了”,其实那两个峰在真实分辨率下是糊在一起的。判断方法很简单:看主瓣宽度。矩形窗的主瓣宽度大约是2*fs/N,补零不改变主瓣宽度,只改变采样密度。
2.2 频谱泄露的成因与窗函数的取舍
频谱泄露是FFT实操中最常见的问题。它的根源是:DFT默认信号是周期延拓的,如果你截取的信号片段首尾不连续,延拓后就会在连接处产生突变,这个突变在频域表现为能量向周围频率扩散,也就是泄露。
解决泄露的标准做法是加窗。窗函数的作用是让信号两端平滑衰减到零,减少截断处的突变。常用的窗有矩形窗、汉宁窗、汉明窗、布莱克曼窗、平顶窗等。选择窗函数时要在主瓣宽度和旁瓣衰减之间做权衡。
| 窗类型 | 主瓣宽度 | 旁瓣衰减 | 适用场景 |
|---|---|---|---|
| 矩形窗 | 最窄 | 最差 | 瞬态信号、需要最高频率分辨率 |
| 汉宁窗 | 中等 | 较好 | 通用频谱分析、连续信号 |
| 汉明窗 | 中等 | 好 | 语音信号、需要低旁瓣 |
| 布莱克曼窗 | 宽 | 很好 | 强干扰下的弱信号检测 |
| 平顶窗 | 最宽 | 好 | 幅度精度要求高的校准场景 |
我个人的经验是:如果你只是看个大概的频谱趋势,汉宁窗基本够用;如果你要精确测量某个频率分量的幅度,平顶窗更合适,因为它的幅度平坦度好;如果你分析的是冲击信号,矩形窗反而更合适,因为加窗会把冲击的瞬态特性抹掉。
加窗还有一个副作用:它会改变信号的幅度。所以做完FFT后,如果需要绝对幅度,要乘以窗函数的相干增益或非相干增益进行补偿。这个细节很多教程不讲,但实际做测量时不做补偿,幅度会差好几个百分点。
2.3 栅栏效应与频谱插值
DFT的输出是离散的谱线,频率间隔是Δf。如果信号的真实频率刚好落在两条谱线之间,你看到的峰值就会偏低,这就是栅栏效应。解决方法是频谱插值,常用的有比值插值法、相位差法、能量重心法。
比值插值法的思路是:找到峰值谱线及其左右相邻谱线,用它们的幅度比值来估算真实频率偏移。这个方法实现简单,精度也不错,适合大多数工程场景。相位差法需要两次不同长度的FFT,精度更高但计算量翻倍。能量重心法对多根谱线做加权,抗噪性能好。
我在做电机振动分析时,用比值插值把频率估计精度从±1Hz提升到了±0.1Hz,代价只是多算几行代码。如果你的应用对频率精度要求高,这个投入非常值得。
3. 高频增强:让细节和边缘重新浮现
3.1 高频增强的本质是什么
高频增强,说白了就是让频谱中高频部分的幅度变大,低频部分相对不变或减小。在图像处理里,这对应锐化;在音频处理里,这对应提升清晰度;在振动分析里,这对应突出冲击成分。
为什么高频对应细节?因为信号中的快速变化、突变、边缘,在频域上都表现为高频分量。一个平滑的低频信号,频谱能量集中在低频;一个包含大量细节的信号,高频部分会有明显能量。所以增强高频,本质上是在放大信号中的快速变化成分。
但这里有个度的问题。高频增强过头,噪声也会被同步放大,因为噪声通常分布在整个频段,高频部分尤其明显。所以高频增强往往要和降噪配合使用,先压住噪声,再提高频,顺序反了效果会差很多。
3.2 频域高频增强的实现步骤
具体操作上,高频增强的流程可以拆成这几步:
- 对信号做FFT,得到复数频谱X[k]。
- 设计一个高频增强滤波器H[k],它在低频段增益接近1或略小于1,在高频段增益大于1。
- 将X[k]与H[k]逐点相乘,得到增强后的频谱Y[k]。
- 对Y[k]做逆FFT,得到时域增强信号。
高频增强滤波器最简单的形式是H[k] = 1 + α * (f[k] / f_max),其中α控制增强强度,f[k]是对应频率。这个滤波器从低频的1线性增长到高频的1+α。α取0.5到2之间比较常见,具体看信号和噪声水平。
更精细的做法是用分段增益:比如0到0.2倍奈奎斯特频率增益为1,0.2到0.5倍增益线性上升到1.5,0.5倍以上增益保持1.5但加一个上限防止噪声爆炸。这种分段设计在实际项目中比单一公式更可控。
3.3 高频增强的副作用与补偿手段
高频增强最明显的副作用是噪声放大和振铃效应。噪声放大前面说了,振铃效应是因为频域的陡峭过渡对应时域的振荡,增强越猛,振铃越明显。
补偿手段有几个:一是限制最大增益,比如不超过3倍;二是在高频增强后加一个轻度平滑,把振铃压一压;三是用重叠分段处理,每段加窗后做增强再重叠相加,减少段间不连续。
我在处理一段机械冲击信号时,直接对全段做高频增强,结果冲击前后出现了明显的“预振”和“余振”,后来改成重叠分段加汉宁窗,振铃基本消失。这个经验告诉我,频域处理不能只看频谱好不好看,一定要回到时域验证。
4. 低频降噪:去掉漂移和基线干扰
4.1 低频噪声的典型来源
低频噪声在工程信号里太常见了。传感器温漂、电源纹波、机械结构的低频共振、环境振动,都会在频谱的低频段堆出一大块能量。这块能量如果不处理,会严重影响后续的特征提取,比如你算RMS、做节拍检测、找峰值,都会被低频漂移带偏。
低频降噪的目标很明确:把低频段的增益压下去,让有用信号的中高频部分不受影响。但难点在于,有用信号本身也可能包含低频成分,比如心电信号的ST段、地震信号的长周期成分。所以低频降噪不是一刀切,要根据具体应用确定截止频率和过渡带宽度。
4.2 高通滤波器的设计要点
低频降噪最直接的工具是高通滤波器。在频域实现高通,就是把低频段的频谱乘以一个小于1的系数,中高频段乘以1。但直接这样做的过渡带会很陡,时域振铃严重。更好的做法是设计一个平滑的过渡带,比如用巴特沃斯响应或者高斯响应。
巴特沃斯高通滤波器的幅度响应是|H(f)| = 1 / sqrt(1 + (fc/f)^(2n)),其中fc是截止频率,n是阶数。n越大,过渡带越陡,但相位非线性越严重。对于离线处理,可以用零相位滤波,也就是正向滤一遍再反向滤一遍,消除相位失真。对于实时处理,就要考虑滤波器的群延迟。
我在做可穿戴设备的心率信号处理时,低频降噪的截止频率设在0.5Hz,阶数用2阶,配合零相位滤波,效果很稳。截止频率再低,运动伪影压不住;再高,心率信号的低频成分会受损。
4.3 低频降噪与趋势项去除的区别
这里要区分两个概念:低频降噪和趋势项去除。低频降噪是保留低频段以外的所有成分,趋势项去除是直接把低频趋势减掉。前者用高通滤波器,后者用多项式拟合或者移动平均。
趋势项去除适合处理缓慢漂移,比如温度引起的基线偏移。做法是用低阶多项式拟合信号趋势,然后从原信号中减去。多项式阶数一般取1到3,阶数太高会把有用低频也减掉。
低频降噪适合处理持续的低频干扰,比如50Hz工频的谐波、机械共振。做法是用高通滤波器把截止频率以下的成分压掉。两者的选择取决于干扰的性质:漂移用趋势项去除,振荡用低频降噪。
我见过有人把趋势项去除当成低频降噪用,结果把信号的低频调制成分也减没了,特征完全丢失。这个坑要特别注意。
5. 高频增强与低频降噪的联合使用策略
5.1 处理顺序为什么重要
高频增强和低频降噪一起用时,顺序很关键。我的经验是:先降噪,再增强。原因很简单,如果你先增强高频,噪声也被放大了,再降噪时滤波器要处理的是一个噪声已经被放大的信号,效果会打折扣。反过来,先降噪把噪声压下去,再增强高频,有用信号的高频成分被提上来,噪声基数低,最终信噪比更好。
这个顺序在图像处理里也是类似的:先做去噪,再做锐化。先锐化再去噪,噪声会被锐化算法强化,去噪难度大增。
5.2 一个完整的频域增强流程
把前面的内容串起来,一个完整的频域增强流程是这样的:
- 读取信号,确定采样率和分析频段。
- 如果信号有趋势项,先用多项式拟合去除。
- 分段加窗,段长根据频率分辨率要求确定,重叠率50%到75%。
- 对每段做FFT。
- 设计联合滤波器:低频段增益小于1,中频段增益为1,高频段增益大于1。
- 频谱与滤波器相乘。
- 逆FFT,重叠相加,得到增强信号。
- 如果需要,做一次时域平滑,压制振铃。
这个流程看起来步骤多,但每一步都有明确目的。分段加窗是为了减少泄露,重叠相加是为了避免段间不连续,联合滤波器是为了同时处理低频和高频问题。
5.3 参数调优的实操经验
参数调优没有万能公式,但有几个经验法则可以参考:
- 截止频率:低频降噪的截止频率设在有用信号最低频率的0.5到0.8倍。比如心电信号最低有用频率约0.5Hz,截止频率可以设在0.3到0.4Hz。
- 增强强度:高频增强的最大增益从1.5倍开始试,逐步加到2倍、3倍,同时观察时域波形是否出现明显振铃。
- 分段长度:段长至少包含2到3个最低频率周期的信号。比如最低频率1Hz,段长至少2到3秒。
- 重叠率:50%是底线,75%更稳,但计算量翻倍。
我一般会先用一段典型数据做参数扫描,把不同参数下的时域波形和频谱都画出来,肉眼对比后再定。这个过程花不了多少时间,但能避免后面大批量处理时返工。
6. 从FFT到工程落地:几个真实场景的拆解
6.1 音频降噪与清晰度提升
音频场景里,低频降噪主要对付空调噪声、风噪、桌面振动,截止频率一般设在80到120Hz。高频增强用来提升齿音和乐器泛音,增强频段从3kHz开始,最大增益1.5到2倍。处理时用短时傅里叶变换,帧长20到40毫秒,帧移10毫秒,汉宁窗。
这里有个细节:音频的相位对听感影响很大,所以逆变换后要做相位重建。如果只是简单地把频谱乘滤波器再逆变换,相位会失真,听起来会有金属感。解决办法是用原始相位,只修改幅度谱,然后逆变换。这个方法叫幅度谱修改法,在语音增强里很常用。
6.2 振动信号的冲击特征提取
振动信号里,低频降噪用来去掉机械结构的低频共振和传感器漂移,截止频率根据设备转速确定,一般是转频的0.5倍以下。高频增强用来突出轴承故障的冲击成分,增强频段从2kHz到10kHz,增益2到3倍。
这个场景下,包络分析比直接频谱更有效。做法是:先带通滤波到高频段,然后做希尔伯特变换取包络,再对包络做FFT,看故障特征频率。高频增强在这里的作用是让包络更清晰,特征频率的谱峰更突出。
6.3 节拍检测中的频域预处理
节拍检测是FFT的一个经典应用。流程是:对音频做FFT,找低频段的周期性峰值,对应鼓点的节拍。低频降噪在这里用来去掉低频漂移,高频增强用来突出打击乐的瞬态。
但节拍检测有个特殊之处:它更关心时间信息而不是频率精度。所以帧长不能太长,一般20到30毫秒,否则节拍的时间定位会模糊。同时,FFT之后通常还要做半波整流和差分,增强节拍的起音点。
我在做节拍检测时发现,低频降噪的截止频率如果设得太高,底鼓的基频会被削弱,节拍检测反而变差。后来把截止频率降到40Hz,底鼓能量保住了,节拍准确率明显提升。这个例子说明,参数不能照搬,要结合具体信号特点调。
7. 硬件实现与实时性考量
7.1 FPGA做FFT的适用场景
有些场景对实时性要求极高,比如雷达、声呐、高速振动监测,这时候用CPU或GPU做FFT可能跟不上,需要上FPGA。FPGA做FFT的优势是并行度高、延迟低、功耗可控。常见的做法是用FFT IP核,配置点数、数据位宽、流水线级数,然后自己写控制逻辑。
但FPGA做频域增强有个限制:滤波器系数要预先算好,存在ROM里,运行时查表相乘。如果滤波器需要动态调整,逻辑会复杂很多。所以FPGA方案适合滤波器固定的场景,比如固定频段的振动监测。
7.2 定点数与浮点数的取舍
FPGA里做FFT,数据格式是个关键选择。定点数省资源、速度快,但动态范围有限,容易溢出。浮点数动态范围大,但资源消耗高,时序难收敛。
我的经验是:如果信号动态范围不超过60dB,用16位或18位定点数就够了,配合块浮点或者缩放策略防止溢出。如果动态范围超过80dB,比如雷达回波,那就老老实实用浮点,或者用自定义的浮点格式。
定点FFT的溢出处理有个技巧:每级蝶形运算后右移一位,相当于除以2。这样虽然损失了低位精度,但保证了不溢出。对于大多数工程信号,这个精度损失可以接受。
7.3 实时处理中的延迟与吞吐平衡
实时频域增强的延迟主要来自三部分:分段缓冲、FFT计算、逆FFT和重叠相加。分段缓冲的延迟等于段长,FFT计算的延迟取决于实现方式,重叠相加的延迟等于段长减帧移。
如果段长是1024点,采样率是48kHz,段长对应21毫秒,重叠相加再引入约10毫秒延迟,总延迟大概30到40毫秒。这个延迟在音频通话里可以接受,但在主动降噪里就太大了,因为主动降噪要求延迟小于1毫秒。
所以主动降噪一般不用频域方法,而是用自适应滤波器在时域做。频域增强更适合离线分析或者对延迟不敏感的实时监测。
8. 我踩过的几个坑和对应的解法
8.1 补零导致的频率分辨率误判
前面提过补零不提高分辨率,但我自己就犯过这个错。有一次做电机故障诊断,数据只有0.2秒,我补零到8192点,频谱上看到两个很近的峰,以为是两个不同的故障频率。后来用同样数据不做补零,只做4096点FFT,发现那两个峰其实是一个峰,补零只是把它插值成了两个。
解法很简单:看主瓣宽度。如果两个峰之间的距离小于主瓣宽度,它们就是不可分辨的。主瓣宽度用矩形窗时约等于2fs/N,用汉宁窗时约等于4fs/N。这个判据比看峰的数量可靠得多。
8.2 窗函数选错导致的幅度误差
还有一次做声压级测量,用汉宁窗做FFT,算出来的声压级比标准声级计低了3dB。查了半天才发现,汉宁窗的相干增益是0.5,也就是幅度要乘以2才恢复。我没做补偿,所以幅度少了一半,对应-6dB,但实际只差了3dB,因为还有别的因素。
这个坑的教训是:加窗之后一定要做增益补偿。矩形窗相干增益为1,汉宁窗为0.5,汉明窗为0.54,布莱克曼窗为0.42。做绝对幅度测量时,这些系数必须乘回去。
8.3 高频增强过度导致的噪声淹没
高频增强的增益我一开始设得比较激进,用了3倍。结果处理后的信号里,噪声被放得很大,有用信号的细节反而被噪声盖住了。后来把增益降到1.5倍,配合低频降噪,信噪比才上来。
这个经验说明:高频增强不是越强越好,它和降噪是一对平衡。降噪做得越好,高频增强的空间越大。如果降噪不充分,高频增强的增益就要保守。
8.4 忽略相位导致的信号失真
做音频处理时,我一开始只改幅度谱,相位用原始相位,结果逆变换后声音发闷。后来发现是因为滤波器在低频段的相位响应不是线性的,只改幅度不改相位,会导致群延迟不一致,低频和高频成分的时间关系错乱。
解法是用零相位滤波,或者设计线性相位滤波器。零相位滤波的做法是正向滤一遍再反向滤一遍,相位完全抵消。线性相位滤波器的系数对称,群延迟恒定。这两种方法都能避免相位失真。
9. 工具链与代码实现建议
9.1 Python生态下的FFT工具选择
Python里做FFT,numpy.fft和scipy.fft是首选。numpy.fft接口简单,适合快速验证;scipy.fft功能更全,支持多种FFT变体,性能也更好。如果要做实时处理,可以考虑pyfftw,它封装了FFTW库,速度比numpy快好几倍。
滤波器设计用scipy.signal,里面butter、cheby1、firwin这些函数都很成熟。频谱分析用scipy.signal.spectrogram或者stft,直接输出时频矩阵,省得自己写分段加窗。
9.2 一个可复用的频域增强函数框架
下面这个框架是我自己常用的,把FFT、滤波、逆FFT、重叠相加都封装好了,改改参数就能用:
import numpy as np from scipy.fft import rfft, irfft, rfftfreq def freq_enhance(x, fs, low_cut, high_boost_start, high_boost_gain, frame_len, overlap): hop = int(frame_len * (1 - overlap)) window = np.hanning(frame_len) # 设计频域滤波器 freqs = rfftfreq(frame_len, 1/fs) H = np.ones_like(freqs) # 低频降噪:低于low_cut的增益线性降到0 low_mask = freqs < low_cut H[low_mask] = freqs[low_mask] / low_cut # 高频增强:高于high_boost_start的增益线性升到high_boost_gain high_mask = freqs > high_boost_start H[high_mask] = 1 + (high_boost_gain - 1) * (freqs[high_mask] - high_boost_start) / (fs/2 - high_boost_start) # 分段处理 n_frames = (len(x) - frame_len) // hop + 1 y = np.zeros(len(x)) win_sum = np.zeros(len(x)) for i in range(n_frames): start = i * hop seg = x[start:start+frame_len] * window X = rfft(seg) Y = X * H seg_out = irfft(Y, n=frame_len) * window y[start:start+frame_len] += seg_out win_sum[start:start+frame_len] += window ** 2 # 归一化 win_sum[win_sum < 1e-10] = 1e-10 y = y / win_sum return y这个函数里,低频降噪用的是线性过渡,高频增强也是线性过渡。实际用时可以把线性改成巴特沃斯或者高斯过渡,过渡更平滑。窗函数用的是汉宁窗,重叠率建议0.5到0.75。
9.3 验证与调试的实用技巧
频域增强做完后,怎么验证效果?我一般看三个东西:
一是时域波形对比。增强后的信号应该保留原始信号的形状,但细节更清晰,低频漂移被压掉。如果波形出现明显变形或者振铃,说明参数有问题。
二是频谱对比。增强后的频谱应该在低频段被压低,高频段被抬高,中频段基本不变。如果某个频段出现异常尖峰,可能是滤波器设计有问题。
三是听感或特征指标。音频场景直接听,振动场景看特征频率的谱峰高度,通信场景看误码率。这些指标比单纯的频谱图更有说服力。
调试时建议先用一小段数据做参数扫描,把不同参数的结果都存下来对比。不要一上来就处理全量数据,那样调参效率太低。
10. 一些容易被忽略的边界问题
10.1 直流分量的处理
FFT输出的第一个点对应直流分量,也就是信号的平均值。如果信号有较大的直流偏置,这个点会很大,做低频降噪时如果直接把它压掉,信号的基线会归零,后续处理可能出问题。
我的做法是:先单独把直流分量减掉,再做FFT。这样频谱里直流点接近零,低频降噪滤波器在直流附近的增益怎么设都不会影响基线。如果应用需要保留直流信息,处理完后再加回去。
10.2 奈奎斯特频率附近的处理
奈奎斯特频率是采样率的一半,对应FFT输出的最后一个点。这个点附近的频谱容易受混叠影响,做高频增强时如果增益加得太大,会把混叠成分也放大。
解法是在高频增强的滤波器里,在奈奎斯特频率附近做一个衰减,比如从0.9倍奈奎斯特频率开始,增益逐渐降到1。这样既增强了有用高频,又抑制了混叠。
10.3 非平稳信号的分段长度选择
傅里叶变换假设信号在分析窗内是平稳的。如果信号是非平稳的,比如语音、音乐、冲击信号,分段长度不能太长,否则窗内的信号特性变化太大,频谱会模糊。
分段长度的经验法则是:窗内信号的特征变化不超过可接受范围。对于语音,20到40毫秒是标准;对于音乐,50到100毫秒;对于机械冲击,根据冲击持续时间定,一般不超过冲击持续时间的2倍。
如果信号非平稳性很强,可以考虑用短时傅里叶变换或者小波变换,后者在时频分辨率上更灵活。但小波变换的参数选择比FFT复杂,工程上FFT加分段仍然是主流。
10.4 复数频谱的对称性利用
实信号的FFT输出是共轭对称的,也就是X[k]和X[N-k]互为共轭。这意味着你只需要计算和存储一半的频谱,另一半可以推导出来。numpy的rfft就是利用这个性质,只返回正频率部分,计算量和存储量都减半。
做频域增强时,如果你用的是rfft,滤波器也只需要设计正频率部分,逆变换用irfft自动处理对称性。这个细节能省不少计算资源,尤其是在嵌入式设备上。
11. 从项目角度看待频域增强的投入产出
频域增强这套方法,学起来有一定门槛,但一旦掌握,能解决的问题范围很广。音频、振动、通信、雷达、生物医学信号,底层逻辑都是相通的。我在不同项目里反复用这套方法,每次只需要调整参数和滤波器形状,核心流程基本不变。
投入产出比最高的地方在于:它能解决时域方法很难处理的问题。比如低频漂移和高频噪声同时存在时,时域滤波器要么阶数很高,要么相位失真严重,而频域方法可以独立设计每个频段的增益,灵活得多。
但也要清醒认识到它的局限:频域方法假设信号在窗内平稳,对非平稳信号的瞬态定位不如时域方法精确;频域滤波的延迟通常比时域滤波大,不适合超低延迟场景;FFT的计算量虽然比DFT小,但在极低功耗设备上仍然是不小的负担。
所以我的建议是:先把时域方法用熟,遇到时域解决不好或者解决起来很别扭的问题,再上频域。频域增强不是万能药,但它是工具箱里一件非常趁手的工具。你如果正在做信号处理相关的项目,不妨拿一段实际数据,按这篇里的流程走一遍,看看频域视角能不能给你带来新的发现。