4. 频域特征提取:FFT与功率谱密度分析
聊到风机故障诊断,时域信号看多了,你会发现一个规律——很多故障特征在时间轴上根本看不出来。比如早期轴承磨损,时域波形可能只是毛刺多了点,但转到频域一看,特征频率清清楚楚。这就是我为什么总跟团队说:时域是表象,频域才是本质。
这一章,咱们就聊聊频域分析里最核心的两个工具:FFT和功率谱密度。说白了,就是把振动信号从时间轴掰到频率轴,看看不同频率成分的能量分布。
4.1 为什么非要做频域分析?
你想想看,风机转一圈,会产生多少种振动?
- 转子不平衡——转频振动
- 轴承故障——高频冲击
- 齿轮啮合——啮合频率
- 松动——倍频成分
这些信号混在一起,时域上就是一锅粥。但转到频域,每个故障都有自己对应的频率位置。就像听交响乐,你不可能从总音量里分辨出小提琴在拉哪个音,但频谱图一出来,清清楚楚。
核心思想:频域分析的本质是能量分解。把总振动能量按频率拆开,看哪个频率段出了问题。
4.2 FFT——频域分析的基石
FFT(快速傅里叶变换)不是什么新东西,上世纪60年代就有了。但直到今天,它依然是风机故障诊断的标配工具。我个人习惯,拿到一组振动数据,第一件事就是做FFT看看频谱长什么样。
4.2.1 FFT的基本原理
数学上,FFT是把时域信号x(t)变换到频域X(f):
X(f) = ∫ x(t) · e^(-j2πft) dt
嗯,公式看着有点吓人。但实际用起来,你只需要知道几个关键参数:
| 参数 | 含义 | 我的建议 |
|---|---|---|
| 采样率fs | 每秒采集的点数 | 至少是最高分析频率的2.56倍 |
| 采样点数N | 一次FFT用多少数据 | 1024或2048,太少分辨率不够 |
| 频率分辨率Δf | 频谱上相邻两根谱线的间隔 | Δf = fs / N,越小越好 |
我在项目中遇到过一个问题:采样率设得太低,导致高频故障特征被混叠到低频段,误判成别的故障。所以记住——采样率宁高勿低。
4.2.2 FFT的Python实现
代码其实很简单,几行就搞定:
import numpy as np
import matplotlib.pyplot as plt
# 生成模拟信号:50Hz + 120Hz + 噪声
fs = 1000 # 采样率1000Hz
t = np.arange(0, 1, 1/fs)
x = 0.7*np.sin(2*np.pi*50*t) + 1.2*np.sin(2*np.pi*120*t) + 0.5*np.random.randn(len(t))
# FFT计算
N = len(x)
X = np.fft.fft(x)
freq = np.fft.fftfreq(N, 1/fs)
# 只取正频率部分
X_mag = np.abs(X[:N//2]) * 2 / N
freq_pos = freq[:N//2]
# 画图
plt.figure(figsize=(10, 4))
plt.plot(freq_pos, X_mag)
plt.xlabel('频率 (Hz)')
plt.ylabel('幅值')
plt.title('FFT频谱')
plt.grid(True)
plt.show()
小技巧:做FFT之前,最好先对信号做去直流处理(减去均值)。不然0Hz处会有一个大尖峰,把其他频率成分都压下去了。
4.3 功率谱密度——更稳定的频域表达
FFT有个问题:如果信号有随机噪声,单次FFT的结果会抖动得很厉害。这时候,功率谱密度(PSD)就派上用场了。
PSD描述的是信号功率在频率上的分布。说白了,它比FFT更平滑、更稳定,特别适合分析风机这种有背景噪声的工况。
4.3.1 两种常用方法
实际工程中,我主要用这两种方法:
- Welch法:把数据分段,每段做FFT,然后取平均。这是最常用的方法,抗噪能力强。
- 周期图法:直接对整段数据做FFT然后平方。简单但方差大。
我个人习惯用Welch法。为什么?因为风机现场噪声大,单次FFT的结果经常忽高忽低,平均一下才靠谱。
4.3.2 PSD的Python实现
from scipy import signal
# 使用Welch法计算PSD
f, Pxx = signal.welch(x, fs, nperseg=256, noverlap=128)
# 画图
plt.figure(figsize=(10, 4))
plt.semilogy(f, Pxx) # 对数坐标更清晰
plt.xlabel('频率 (Hz)')
plt.ylabel('功率谱密度 (V²/Hz)')
plt.title('功率谱密度 (Welch法)')
plt.grid(True)
plt.show()
注意:PSD的单位和FFT不同。FFT的纵轴是幅值,PSD的纵轴是功率密度。两者不能直接比较数值大小,要看趋势。
4.4 频域特征提取实战
好了,理论讲完了,咱们来点实际的。在风机故障诊断中,我通常从频谱里提取以下几类特征:
4.4.1 特征频率识别
每种故障都有对应的特征频率:
| 故障类型 | 特征频率 | 计算公式 |
|---|---|---|
| 转子不平衡 | 1×转频 | f_r = RPM / 60 |
| 轴弯曲 | 1×转频 + 2×转频 | 倍频成分明显 |
| 轴承外圈故障 | BPFO | 取决于轴承参数 |
| 齿轮啮合 | GMF | 齿数 × 转频 |
我曾经遇到一个案例:频谱上1×转频的幅值很高,但2×转频也异常大。一开始以为是简单的不平衡,后来发现是轴有轻微弯曲。所以看频谱不能只看最高峰,倍频关系往往藏着关键信息。
4.4.2 频段能量特征
除了找特征频率,我还经常计算特定频段的能量:
# 计算低频段(0-100Hz)的能量
idx_low = (f >= 0) & (f <= 100)
energy_low = np.trapz(Pxx[idx_low], f[idx_low])
# 计算中频段(100-500Hz)的能量
idx_mid = (f > 100) & (f <= 500)
energy_mid = np.trapz(Pxx[idx_mid], f[idx_mid])
# 计算高频段(500Hz以上)的能量
idx_high = (f > 500)
energy_high = np.trapz(Pxx[idx_high], f[idx_high])
print(f'低频能量: {energy_low:.3f}')
print(f'中频能量: {energy_mid:.3f}')
print(f'高频能量: {energy_high:.3f}')
这个特征在轴承故障诊断中特别好用。轴承早期故障时,高频段能量会明显上升,而低频段变化不大。通过监测频段能量的变化趋势,可以提前发现故障。
4.5 避坑指南
做频域分析这么多年,踩过的坑不少。分享几个最常见的:
- 频谱泄露:信号不是整周期截断时,能量会泄漏到相邻频率。解决办法是加窗函数(汉宁窗、海明窗)。
- 频率混叠:采样率不够高,高频信号伪装成低频信号。记住奈奎斯特定理,采样率至少是最高频率的2倍。
- 栅栏效应:特征频率正好落在两根谱线之间,幅值被低估。增加采样点数可以提高频率分辨率。
我的经验:做频域分析,不要只看幅值大小,要看频率位置和相对关系。故障诊断的本质是找异常,不是找最大值。
4.6 本章知识体系
为了让你更直观地理解本章内容,我画了一张结构图:
这张图把本章的核心逻辑串起来了:从时域信号出发,经过FFT或PSD处理,结合关键参数设置,最终提取出可用于故障诊断的频域特征。
好了,频域特征提取就聊到这儿。记住一句话:时域看趋势,频域看成分。下一章咱们聊聊时频域分析,看看那些既随时间变化、又随频率变化的信号该怎么处理。