4. 频域分析:傅里叶变换基础、频谱图绘制、功率谱密度估计
聊到海豚声波信号处理,频域分析是绕不开的核心。说白了,时域信号就像一段录音,你能听到声音大小变化,但很难直接看出里面藏着哪些频率成分。而频域分析,就是帮我们把信号「拆开」,看看海豚到底发出了哪些频率的声音。
我个人习惯把频域分析比作「声音的指纹提取」。海豚的叫声、回声定位信号,在时域里看着乱糟糟的,一转到频域,特征就清清楚楚了。好,咱们直接进入正题。
4.1 傅里叶变换基础
傅里叶变换,简单说就是把时域信号变成频域信号。数学公式长这样:
X(f) = ∫ x(t) · e^(-j2πft) dt
别被公式吓到。你只要记住:每个信号都可以分解成不同频率的正弦波之和。海豚发出的咔嗒声,其实是由很多频率成分叠加而成的。
在实际项目中,我们处理的是离散采样信号,所以要用离散傅里叶变换(DFT)。Python里最常用的是FFT(快速傅里叶变换),它是DFT的高效算法实现。
核心要点:
- 采样率决定了你能分析的最高频率(奈奎斯特频率 = 采样率/2)
- FFT点数决定了频率分辨率(Δf = 采样率 / FFT点数)
- 海豚声波频率范围通常在1kHz到150kHz之间,采样率至少300kHz起步
我记得刚入行时,有一次采集海豚回声定位信号,采样率设了200kHz。结果分析时发现高频部分有混叠,后来才意识到海豚的咔嗒声能到120kHz以上。嗯,从那以后我采样率都至少设300kHz。
4.2 频谱图绘制
频谱图就是把FFT结果画出来。横轴是频率,纵轴是幅度(或功率)。看频谱图,你能直观知道信号里哪些频率能量强。
咱们直接上代码。假设你有一段海豚声波信号 signal,采样率 fs:
import numpy as np
import matplotlib.pyplot as plt
def plot_spectrum(signal, fs):
"""
绘制单边幅度频谱
signal: 输入信号数组
fs: 采样率 (Hz)
"""
N = len(signal)
# 做FFT
fft_vals = np.fft.fft(signal)
# 取单边频谱(正频率部分)
fft_vals = fft_vals[:N//2] * 2 / N
# 频率轴
freqs = np.fft.fftfreq(N, 1/fs)[:N//2]
plt.figure(figsize=(10, 5))
plt.plot(freqs/1000, np.abs(fft_vals))
plt.xlabel('频率 (kHz)')
plt.ylabel('幅度')
plt.title('海豚声波频谱图')
plt.grid(True, alpha=0.3)
plt.show()
# 使用示例
# plot_spectrum(dolphin_signal, fs=320000)
实用技巧:
绘制频谱时,我建议用np.abs()取幅度,然后转成dB单位:20 * np.log10(amplitude)。这样能更好显示微弱信号。海豚的某些谐波成分可能比主频低40dB,线性坐标下根本看不见。
你想想看,海豚的叫声通常包含基频和多次谐波。基频可能在5-20kHz,谐波能延伸到100kHz以上。频谱图上一眼就能看出这些结构。
4.3 功率谱密度估计
功率谱密度(PSD)和频谱图不太一样。频谱图显示的是每个频率成分的幅度,而PSD显示的是单位频率上的功率分布。说白了,PSD告诉你信号的能量在频率轴上是怎么分配的。
实际项目中,我更常用PSD来分析海豚声波。为什么?因为海豚信号往往是非平稳的,PSD能给出更稳定的统计特性。
Python里做PSD估计,我推荐两种方法:
| 方法 | 特点 | 适用场景 |
|---|---|---|
| Welch法 | 分段平均,方差小,谱线平滑 | 连续叫声、背景噪声分析 |
| 周期图法 | 直接FFT,分辨率高但方差大 | 短时咔嗒声、瞬态信号 |
Welch法是我用得最多的。它把信号分成多段,每段加窗,然后做FFT再平均。这样能有效降低噪声引起的谱估计波动。
from scipy import signal
def estimate_psd_welch(signal, fs):
"""
使用Welch法估计功率谱密度
"""
# 分段参数:每段1024点,重叠50%,用汉宁窗
f, Pxx = signal.welch(
signal,
fs=fs,
nperseg=1024,
noverlap=512,
window='hann'
)
plt.figure(figsize=(10, 5))
plt.semilogy(f/1000, Pxx)
plt.xlabel('频率 (kHz)')
plt.ylabel('功率谱密度 (dB/Hz)')
plt.title('海豚声波功率谱密度 (Welch法)')
plt.grid(True, alpha=0.3)
plt.show()
return f, Pxx
# 使用示例
# f, Pxx = estimate_psd_welch(dolphin_signal, fs=320000)
避坑指南:
我曾经在分析一段海豚回声定位信号时,直接用周期图法做PSD,结果谱线抖动得厉害,根本看不出主频。后来改用Welch法,分段数设了8段,谱线一下就清晰了。记住:分段数越多,谱估计越稳定,但频率分辨率会下降。需要根据信号长度和需求做权衡。
4.4 知识体系梳理
为了让你更直观理解本章的知识结构,我画了一张流程图:
这张图把本章的三个核心内容串起来了。从时域信号出发,经过FFT变换,你可以选择做频谱图看幅度分布,也可以做PSD看能量分布。实际项目中,我通常两种都做——频谱图看细节,PSD看整体趋势。
实战建议:
处理海豚声波时,先画频谱图快速浏览频率范围,再用Welch法做PSD提取稳定特征。如果发现某个频段能量异常,可能就是海豚在发特定信号了。
好了,频域分析的基础就这些。记住:FFT是工具,频谱图和PSD是表达方式。关键是要理解海豚声波在频域里长什么样,这样才能做后续的识别和分类。
公众号:蓝海资料掘金营,微信deep3321