简介:这份资源面向机械故障诊断、信号处理方向的研究生与工程技术人员,围绕凯斯西储大学(CWRU)轴承故障数据集展开时频分析实践,帮助读者掌握从原始振动信号到故障特征识别的完整思路。内容涵盖数据集实验台构成与驱动端、风扇端、基座三路振动信号的物理含义,并重点对比短时傅里叶变换与连续小波变换两类方法:STFT部分讨论重叠比例与尺度16、32、64的取舍,最终选定尺度32;CWT部分比较morl、cmor1-1、cmor1.5-2、cgau8等小波函数,确定cmor1.5-2并分析尺度32至256对高低频特征的影响。资源包为1个docx文档,约1.05MB,内含完整分析流程与配套代码片段,便于直接复现与二次修改。目前已有1582人学习,适合作为故障诊断入门与论文实验参考。
1. 轴承故障诊断的起点:为什么时域波形看不出门道
拿到一段轴承振动信号,第一反应往往是直接画波形图。正常信号和故障信号的时域波形摆在一起,肉眼能看出差异——故障冲击让波形出现了周期性尖峰。但再往下问一步:内圈故障和滚珠故障的波形有什么区别?冲击间隔差多少?对应的特征频率在哪?时域图给不出答案。
这就是时频分析要解决的问题。轴承故障的本质是局部缺陷在旋转过程中反复撞击接触面,产生周期性的冲击脉冲。不同故障位置对应不同的特征频率,而这些频率成分在时域上被淹没在宽带噪声里。短时傅里叶变换和连续小波变换做的事情,就是把一维时间序列映射到二维的时频平面,让藏在时间轴里的频率结构显形。这份资源围绕一个经典数据集,用 STFT 和 CWT 两条路线做了完整的时频分析对比,从窗口尺度选择到小波函数选型都有可复现的代码和判断依据。搞懂它,等于搞懂了旋转机械故障诊断里最核心的一步信号处理逻辑。
2. 数据集结构:三个加速度计位置到底在测什么
2.1 驱动端、风扇端、基座的物理含义
这个数据集来自一台 1.5KW 电机驱动的旋转机械实验台,结构上分三段:左侧电机、中间扭矩传感器/译码器、右侧功率测试计。加速度计布置在三个位置——电机壳体的驱动端、风扇端和基座。三个位置测的都是振动,但物理含义完全不同。
驱动端的振动信号主要来自电机转子和传动系统的激励,轴承故障、齿轮啮合异常在这里体现得最直接。风扇端的信号受风扇叶片旋转和风扇系统激励影响,适合检测叶片失衡和风扇轴承问题。基座测的是整个电机系统的综合振动,电机不平衡、底座松动这类全局性问题在这里更明显。同一个故障在不同位置的信噪比和特征清晰度可能差很多,这也是为什么做故障诊断时不能只取一路信号就下结论。
2.2 数据文件的组织方式与读取逻辑
数据以 MAT 格式存储,每个文件对应一种工况和故障类型。用scipy.io.loadmat读进来是一个字典,键名如X097_DE_time、X209_DE_time等,其中DE表示驱动端(Drive End),time表示时域序列。不同文件的键名不同,需要根据文件名和文档对照找到对应的键。
from scipy.io import loadmat import numpy as np # 读取四种状态的驱动端数据 data_normal = loadmat('0_0.mat') # 正常 data_inner = loadmat('21_1.mat') # 0.021英寸内圈故障 data_ball = loadmat('21_2.mat') # 0.021英寸滚珠故障 data_outer = loadmat('21_3.mat') # 0.021英寸外圈故障 # 提取驱动端时域序列并展平为一维 sig_normal = data_normal['X097_DE_time'].reshape(-1) sig_inner = data_inner['X209_DE_time'].reshape(-1) sig_ball = data_ball['X222_DE_time'].reshape(-1) sig_outer = data_outer['X234_DE_time'].reshape(-1) # 截取前1024个采样点做分析 sig_normal = sig_normal[:1024] sig_inner = sig_inner[:1024] sig_ball = sig_ball[:1024] sig_outer = sig_outer[:1024]reshape(-1)的作用是把 MAT 文件里可能存在的二维数组压成一维,避免后续 STFT 或 CWT 函数因为维度不匹配报错。截取 1024 个点是一个经验做法——采样频率固定时,1024 点对应的时长足够覆盖多个冲击周期,同时计算量可控。窗口再短可能截不到完整的冲击间隔,再长则时频图上的时间分辨率会下降。
3. STFT 的窗口尺度:时间分辨率和频率分辨率为什么不能兼得
3.1 滑窗傅里叶变换的底层逻辑
STFT 的做法是在时间轴上滑动一个窗函数,对窗内的信号做傅里叶变换。窗长决定了频率分辨率——窗越长,频率轴上能分辨的两个频率越近;但窗越长,时间轴上定位冲击发生时刻的能力越差。这就是海森堡不确定性原理在信号处理里的体现:时间和频率的分辨率乘积有下界,不可能同时做到无限好。
代码里用scipy.signal.stft实现,关键参数是nperseg(窗长)和noverlap(重叠样本数)。重叠比例设为 0.5 是一个折中——重叠太少,时频图在时间轴上会出现明显的块状伪影;重叠太多,计算量成倍增加但信息增量有限。
from scipy.signal import stft # 以窗长32为例,重叠50% window_size = 32 overlap_samples = int(window_size * 0.5) frequencies, times, magnitude = stft( sig_inner, nperseg=window_size, noverlap=overlap_samples ) # magnitude 是复数矩阵,取绝对值得到幅度谱 amp = np.abs(magnitude)nperseg=32时,频率分辨率约为采样率除以 32;nperseg=256时频率分辨率提高 8 倍,但时间轴上的每个点覆盖了 256 个采样周期,冲击的起始时刻变得模糊。资源里对比了 16、32、64、128 四个尺度,最终选 32,原因是在这个数据集上 32 点窗既能分辨出故障特征频率的边带结构,又不会把冲击时刻糊成一片。
3.2 尺度选择的判断依据
判断尺度是否合适,不能只看时频图好不好看。具体做法是:在时频图上找到故障特征频率及其谐波,看这些频率成分是否形成清晰的水平条纹;再看时间轴上是否有周期性的能量团,能量团之间的间隔是否对应理论上的故障冲击周期。如果频率条纹糊在一起,说明频率分辨率不够,需要加大窗长;如果时间轴上的能量团边界模糊,说明时间分辨率不够,需要减小窗长。
注意:STFT 的窗长一旦选定,整个时频图的时间分辨率和频率分辨率就固定了。这是 STFT 的固有局限——它用固定的窗去分析所有时间段,无法对低频成分用长窗、对高频成分用短窗。CWT 正是为了解决这个问题而引入的。
4. 连续小波变换:用可变尺度替代固定窗口
4.1 小波变换的尺度与频率对应关系
CWT 的核心思想是用一组尺度不同的小波基函数去匹配信号。尺度小的时候,小波在时间轴上压缩,对应高频成分,时间分辨率高;尺度大的时候,小波在时间轴上拉伸,对应低频成分,频率分辨率高。这种自适应特性让 CWT 在分析轴承冲击信号时比 STFT 更有优势——冲击的高频瞬态和低频调制成分可以同时被捕捉到。
代码里用pywt.cwt实现,关键参数是scales序列和wavename。scales的构造方式直接影响时频图的频率轴映射:
import pywt import numpy as np sampling_rate = 1024 totalscal = 128 wavename = 'cmor1.5-2' # 计算小波中心频率 fc = pywt.central_frequency(wavename) # 构造尺度序列 cparam = 2 * fc * totalscal scales = cparam / np.arange(totalscal, 0, -1) # 执行连续小波变换 coefficients, frequencies = pywt.cwt( sig_inner, scales, wavename, sampling_period=1.0/sampling_rate )cparam = 2 * fc * totalscal这个公式的作用是把尺度序列映射到实际的频率范围。np.arange(totalscal, 0, -1)生成从 128 到 1 的递减序列,除以它之后scales变成递增序列,对应从高频到低频的排列。sampling_period参数告诉 CWT 函数采样间隔,这样返回的frequencies数组才是真实的物理频率而不是归一化频率。
4.2 小波函数选型:morl、cmor、cgau 的差异
资源里对比了四种小波:morl、cmor1-1、cmor1.5-2、cgau8。它们的区别在于时频局部化能力和形状匹配度。
morl是实 Morlet 小波,时频局部化好,但只有实部,无法区分相位信息。cmor是复数 Morlet,带虚部,能同时提取幅度和相位。cmor1.5-2里的 1.5 是带宽参数,2 是中心频率参数——带宽越大,频率域上的窗口越宽,频率分辨率越低但时间分辨率越高。cgau8是 8 阶复数高斯小波,对高斯型冲击的匹配度最高,但计算量也最大。
从对比结果看,cgau8和cmor1.5-2对不同故障的辨识度都较高。最终选cmor1.5-2是因为它在频率分辨率和时间分辨率之间取得了更好的平衡——cgau8的频率分辨率偏高但时间轴上冲击边界略糊,cmor1.5-2的时频图在两类分辨率上都够用。
4.3 尺度序列对低频特征的放大效应
用cmor1.5-2分别取尺度 32、64、128、256 做对比,可以看到一个规律:尺度越大,时频图底部低频区域的细节越丰富。这是因为大尺度对应低频,小波基在时间轴上拉长后,对低频成分的频率分辨率提高。反过来,小尺度对应高频,冲击瞬态的时间定位更准。
这个现象印证了小波变换的双尺度性质:关注高频特征选小尺度,关注低频特征选大尺度。实际做故障诊断时,如果故障特征频率落在低频段,就应该用较大的尺度序列;如果关注的是冲击瞬态的高频包络,小尺度更合适。资源里最终选 128 作为分析尺度,是因为在这个数据集上 128 尺度能同时覆盖故障特征频率和其谐波成分。
5. 避坑与排查:时频分析里容易翻车的几个地方
5.1 时频图全黑或全白
现象:plt.pcolormesh或plt.contourf画出来的图要么一片黑要么一片白,看不到任何结构。
原因:幅度矩阵的动态范围太大,线性色标下弱信号被强信号淹没。轴承冲击信号的幅度可能跨越几个数量级,直接用np.abs(coefficients)画图,弱频率成分完全不可见。
解决:对幅度取对数再画图,用np.log1p(np.abs(coefficients))或者20*np.log10(np.abs(coefficients)+1e-12)。取对数后动态范围被压缩,弱信号和强信号能同时显示。
5.2 频率轴数值不对
现象:时频图的纵轴频率范围明显不合理,比如显示到几千 Hz 但实际信号带宽只有几百 Hz。
原因:pywt.cwt的sampling_period参数没设或设错。默认情况下返回的是归一化频率,不是物理频率。如果采样率是 1024 Hz,sampling_period应该设为1.0/1024。
解决:确认sampling_period=1.0/sampling_rate,并且检查frequencies数组的最大值是否接近奈奎斯特频率(采样率的一半)。
5.3 尺度序列构造后频率轴反向
现象:时频图上低频成分出现在顶部,高频在底部,和预期相反。
原因:scales序列的排列顺序和frequencies的映射关系搞反了。np.arange(totalscal, 0, -1)生成递减序列,除以它之后scales递增,对应频率递减。如果直接用np.arange(1, totalscal+1),尺度递增但频率映射会反过来。
解决:画图前检查frequencies数组是否单调。如果单调性不对,用frequencies[::-1]和coefficients[::-1, :]同时翻转。
5.4 STFT 重叠比例设置不当导致时间轴伪影
现象:时频图在时间轴上出现等间距的竖直条纹,不是信号本身的特征。
原因:noverlap设得太小,窗与窗之间的衔接不连续,傅里叶变换的边界效应在时频图上表现为伪影。
解决:重叠比例至少设为 50%,通常 75% 效果更好但计算量增加。如果伪影仍然明显,可以加窗函数(如 Hann 窗)来平滑边界。
5.5 小波函数名称拼写错误导致静默失败
现象:代码运行不报错,但时频图完全不对,或者pywt.cwt返回的系数全为零。
原因:pywt对小波名称的拼写敏感,cmor1.5-2写成cmor1.5_2或cmor1-5-2可能不会抛出异常,但会返回错误结果。
解决:用pywt.wavelist()查看所有可用小波名称,确认拼写完全一致。cmor系列的命名规则是cmor+ 带宽 +-+ 中心频率,中间用连字符不是下划线。
6. 从时频图到诊断结论:参数选择背后的取舍逻辑
STFT 和 CWT 在这个数据集上的表现差异,本质上反映了两种时频分析哲学的分歧。STFT 用固定窗长换取计算效率和实现简单,适合信号频率成分变化不剧烈的场景。CWT 用可变尺度换取自适应分辨率,适合轴承冲击这类宽频瞬态信号。资源里最终在 STFT 上选尺度 32、在 CWT 上选cmor1.5-2加尺度 128,这两个选择不是拍脑袋定的,而是基于同一个判断标准:故障特征频率及其谐波在时频图上是否形成可区分的条纹结构。
如果让我给一个可操作的验证方法,我会这么做:先算出轴承的理论故障特征频率(内圈、外圈、滚珠各有对应公式,取决于轴承几何参数和转速),然后在时频图上叠加这些频率的水平参考线。如果参考线位置和时频图上的能量条纹对齐,说明参数选对了;如果条纹偏离参考线或者糊成一片,说明频率分辨率不够,需要加大窗长或尺度。这个方法比单纯看图说话靠谱得多。
还有一个容易被忽略的点:时频图的分辨率不是越高越好。分辨率提高意味着计算量增加,而且过高的分辨率可能把噪声也放大成看起来像故障特征的条纹。我一般会先用中等分辨率快速扫一遍,确认故障特征的大致频率范围,再针对那个范围做高分辨率细化。这样既省时间,又避免被噪声误导。
从那以后我每次做时频分析,都强制走一遍「理论频率计算 → 中等分辨率扫描 → 高分辨率细化 → 参考线对齐验证」的流程,不再凭感觉调参数。希望帮到你。
本文还有配套的精品资源,点击获取