4. 傅里叶变换与频谱分析
声呐接收到的回波是随时间变化的电压序列,我们真正关心的信息——目标的多普勒频移、螺旋桨调制谱、窄带线谱、宽带能量分布——却藏在频率维度里。傅里叶变换就是把“时间波形”翻译成“频率成分”的数学工具。本节从离散傅里叶变换(DFT)的定义出发,说明它为什么能完成这种翻译,再讨论工程上如何用 FFT 高效实现,最后落到两个最容易出问题的参数:频谱分辨率与频谱泄漏。
一、DFT 在做什么
设有一段长度为 N 的离散采样序列 x[n],采样率为 fs。DFT 把它映射为同样长度为 N 的复数序列 X[k]:
X[k] = Σ(n=0..N-1) x[n] · exp(-j·2π·k·n/N), k = 0,1,...,N-1
每个 X[k] 可以理解为:用一根频率为 k·fs/N、长度为 N 的复正弦“探针”去和信号做内积。内积大,说明信号里含有这个频率的成分;内积小,说明没有。因此 DFT 的输出是一组离散频点上的复幅度,其模值 |X[k]| 构成幅度谱,相位 arg(X[k]) 构成相位谱。第 k 个频点对应的物理频率是:
f_k = k · fs / N (k = 0,1,...,N/2 对应 0 ~ fs/2)
由于实信号的频谱共轭对称,工程上通常只看前 N/2+1 个点,即 0 到奈奎斯特频率 fs/2。这一点在声呐中很关键:如果采样率是 48 kHz,那么可分析的频率上限就是 24 kHz,任何高于它的成分都会折叠回来形成混叠,DFT 本身无法区分。
二、FFT:让 DFT 可用的算法
直接按定义计算 DFT 需要 N² 次复数乘加。当 N = 65536 时,这个量级在实时声呐处理中是不可接受的。快速傅里叶变换(FFT)利用旋转因子 exp(-j2πkn/N) 的周期性和对称性,把长序列分解为短序列的蝶形运算,将复杂度降到 N·log₂N。同样是 65536 点,运算量下降约三个数量级,这才使“每帧都做频谱分析”成为可能。
在 Python 中,numpy.fft.rfft 是处理实信号的首选,它只返回正频率部分,长度自动为 N/2+1,既省内存又避免重复。一个典型的声呐频谱分析片段如下:
import numpy as np
fs = 48000 # 采样率 Hz
N = 4096 # 每帧点数
t = np.arange(N) / fs
x = 0.8*np.sin(2*np.pi*1500*t) + 0.3*np.sin(2*np.pi*3200*t)
win = np.hanning(N) # 加窗抑制泄漏
X = np.fft.rfft(x * win)
f = np.fft.rfftfreq(N, d=1/fs)
mag = np.abs(X) / (win.sum()/2) # 幅度归一化(近似)
peak_idx = np.argmax(mag)
print(f"峰值频率 {f[peak_idx]:.1f} Hz, 幅度 {mag[peak_idx]:.3f}")
这段代码里有两个容易被忽略但直接影响结果正确性的细节:加窗与归一化。加窗是为了抑制泄漏(下一节展开),而归一化除以 win.sum()/2 是为了让正弦分量的谱峰幅度回到其真实幅值附近,否则不同窗函数会给出不同的幅度读数,无法横向比较。
三、频谱分辨率:能分开多近的两根谱线
DFT 的频率轴是离散的,相邻频点间隔为 Δf = fs/N。这个间隔就是名义分辨率。它等价地等于观测时长的倒数:Δf = 1/T,其中 T = N/fs 是这一帧信号的时间长度。这个关系给出了一个非常实用的工程直觉:想看多细的谱,就必须观察多长时间。要分辨间隔 10 Hz 的两根线谱,至少需要 0.1 s 的数据;要分辨 1 Hz,就需要 1 s。
需要区分两个概念:补零可以提高频点密度,让谱线看起来更“平滑”,但补零并没有增加真实观测时长,因此不能提高真正可分辨的频率间隔。补零只是对已有频谱做插值,无法把原本糊在一起的两根谱线分开。判断分辨率是否够用,应看 fs/N 与目标最小频率间隔的关系,而不是看图上点数多少。
四、频谱泄漏:截断带来的副作用
DFT 隐含假设所分析的 N 点序列是周期信号的一个完整周期。实际信号被矩形截断后,若截断处不连续,能量就会从真实谱线“漏”到邻近频点,形成旁瓣,这就是泄漏。泄漏会让弱信号淹没在强信号的旁瓣里——在声呐中,这可能导致靠近强干扰的弱目标线谱完全不可见。
抑制泄漏的标准手段是加窗:用两端平滑衰减到零的窗函数(汉宁、汉明、布莱克曼等)替代矩形窗,压低旁瓣。代价是主瓣变宽,频率分辨率下降。因此窗函数的选择本质上是“旁瓣抑制”与“分辨率”之间的权衡:汉宁窗旁瓣约 -31 dB、主瓣较窄,适合一般线谱检测;布莱克曼窗旁瓣更低但主瓣更宽,适合强干扰背景下找弱线谱。
五、把参数落到一次实际分析中
假设某被动声呐以 48 kHz 采样,目标是检测一台转速约 1800 r/min 的螺旋桨产生的轴频线谱及其谐波。轴频约为 30 Hz,谐波间隔也是 30 Hz。若取 N = 4096,则 Δf ≈ 11.7 Hz,小于 30 Hz 的谐波间隔,理论上可以分开相邻谐波,但主瓣宽度会占用数个频点,弱谐波仍可能被强谐波的主瓣掩盖。若把 N 提高到 16384,Δf ≈ 2.9 Hz,谐波分离明显改善,代价是每帧时长增加到约 341 ms,对快速机动目标的时变跟踪变慢。这就是声呐频谱分析中“频率分辨率”与“时间分辨率”之间无法回避的折中。
实际操作时,建议按以下顺序确定参数:先由目标最小可分辨频率间隔反推所需观测时长 T ≥ 1/Δf_min,再由 N = T·fs 取 2 的整数次幂以便 FFT;然后根据干扰强度选择窗函数,强干扰下优先低旁瓣窗;最后用已知频率的校准信号(例如注入一个 1 kHz 单音)验证谱峰位置与幅度读数是否正确。若校准单音的谱峰偏离预期频点超过一个 Δf,应检查采样率设置或数据长度是否与假设一致。
总结起来,DFT 提供了从时域到频域的离散映射,FFT 让这一映射在工程上可行,而分辨率与泄漏则是决定频谱“看得清不清”的两个核心参数。它们不是软件里的默认选项,而是需要根据目标特性、干扰环境和实时性要求主动设计的分析参数。