基于Python与Librosa的轴承异响检测与故障预警实践
2026/9/18 2:19:47 网站建设 项目流程

车间里的旋转设备最怕什么?不是停机,而是停机前那几个小时里,轴承还在转、异响已经出现,但人耳听不出来、点检记录也发现不了。等振动值明显飙升或者温度异常时,往往已经到了必须换轴承甚至修轴的地步。我接手过不少设备故障案例,最后排查下来,根源基本都是轴承早期损伤。早期损伤不是没信号,而是我们没有用对方法去提取它。用麦克风采集设备运行时发出的声音,再用Python和Librosa做特征提取和异常判断,就能在异响刚冒头的时候发出预警,把“事后维修”变成“事前干预”。这篇文章就围绕这个思路,讲清楚如何分五步落地一套轴承异响检测脚本,并结合现场实测数据说明关键参数怎么定、坑在哪里,适合设备维护工程师、自动化产线负责人以及正在做工业AI落地项目的开发者参考。

1. 轴承异响到底长什么样?先把“异常”定义清楚

1.1 轴承故障信号里藏着的声学规律

一个正常的滚动轴承在运转时,声音是平稳、连续、略带均匀白噪声特征的。一旦某个部位出现故障,比如内圈点蚀、外圈裂纹、滚动体磨损、保持架变形,声学信号里就会叠加周期性冲击成分。这个冲击会以某个特征频率反复出现,再和轴承本身的旋转频率、结构共振频率相互调制,最终呈现为一定带宽内的能量突变和频谱峰值漂移。

这里有个关键认知:轴承异响不是“音量变大”这么简单。很多时候整体声压级变化很小,但特定频段内的能量分布出现了明显偏移。比如外圈故障的特征频率通常在1kHz以下的低频段,滚动体故障则可能激起更高的频段。如果只用声级计测总噪声,大概率什么也发现不了,但用频谱分析就能看到清晰的故障边带。

所以,做轴承异响检测的第一步,不是急着写代码,而是要把“异常”映射成可计算的量。我的经验是至少提取三类特征:时域上的均方根值(RMS)反映整体能量波动;频域上的梅尔频谱或功率谱反映能量分布变化;倒谱域上的梅尔频率倒谱系数(MFCC)用于捕捉冲击成分的周期性。Librosa这个Python音频处理库,正好把这三种特征的提取全部封装好了。

1.2 Librosa在工业音频分析里的位置

Librosa最初是音乐信息检索领域的开源库,但当它被用在工业设备声学监测里时,效果意外地好。它内置了音频加载、重采样、短时傅里叶变换(STFT)、梅尔滤波器组、MFCC、色谱图、节奏特征等一整套工具,不需要自己从头写FFT和滤波器,代码量能压缩到原来的五分之一。

我用Librosa做过的实测结论是:在轴承异响检测这个场景下,MFCC特征配合RMS能量阈值,检测准确率能达到比较满意的水平,这里先留个悬念,后面有具体数据说明。相比直接上深度学习模型,这种传统特征提取加阈值判定的方案,胜在可解释性强、算力需求低、现场部署方便,非常适合作为第一版故障预警系统。

2. 五步实现轴承异响检测的完整流程

2.1 第一步:环境准备与依赖安装

整个项目只需要一个能跑Python的环境,Windows、Linux都可以。我在现场调试时用的是Linux工控机,Ubuntu 20.04系统,Python 3.8版本。如果手头没有现成环境,Windows下装Anaconda最快,装好以后用conda建一个独立环境,避免把系统Python搞乱。

依赖库方面,核心是Librosa、NumPy、Matplotlib,如果要做实时采集,还需要PyAudio或sounddevice。安装命令如下:

pip install librosa numpy matplotlib pip install sounddevice

这里提醒一点,Librosa依赖的soxr或audioread在某些精简版Linux系统上会装不上,原因是缺系统级解码库。Ubuntu下先执行下面这行再装Librosa,能省去不少折腾:

sudo apt-get install libsndfile1 ffmpeg

验证安装是否成功的方式很简单,在Python里执行import librosa,能正常导入就说明环境好了。如果出现ModuleNotFoundError,基本就是pip源问题,换成国内镜像源重装即可。

2.2 第二步:采集现场音频样本

环境准备就绪后,接下来解决的是“数据从哪里来”的问题。这一步容易被忽略,但直接决定检测效果的上限。采集轴承音频时,麦克风不是随便放在设备旁边就行。

  • 麦克风距离轴承座越近越好,理想距离是10到30厘米,太远了环境噪声会把有效信号淹没。
  • 采样率建议不低于44100Hz,这样能保留20kHz以内的全部声学信息。如果条件受限,至少也要用22050Hz,再低的话轴承高频冲击成分会丢失。
  • 录音时尽量避开其他设备同时启动的时段,比如隔壁空压机突然启动,这种突发噪声对后续阈值判定干扰极大。

我常用的一手持录音笔方案是:把手机或录音笔用扎带固定在设备防护罩上,离轴承最近的孔位,录制60秒音频保存为WAV格式。WAV比MP3更适合做分析,因为MP3是有损压缩,会抹掉一部分高频细节,而轴承故障的特征恰恰有一部分就藏在细节里。

这里给出一个简单的采集脚本,用sounddevice实现定时录制:

import sounddevice as sd import numpy as np import wave sr = 44100 # 采样率 duration = 60 # 录制时长(秒) channels = 1 # 单声道 print("开始采集,请保持设备稳定运行...") audio = sd.rec(int(duration * sr), samplerate=sr, channels=channels, dtype='float32') sd.wait() # 保存为WAV文件 audio_int16 = (audio * 32767).astype(np.int16) with wave.open("bearing_sample.wav", "wb") as wf: wf.setnchannels(channels) wf.setsampwidth(2) wf.setframerate(sr) wf.writeframes(audio_int16.tobytes()) print("采集完成,已保存为 bearing_sample.wav")

这个脚本实测下来很稳,注意麦克风输入增益不要调太高,否则会削波,削波产生的方波信号在频谱上表现为全频段能量升高,会把真正的轴承故障特征掩盖掉。

2.3 第三步:加载音频并做预处理

采集到WAV文件之后,就进入核心分析环节了。先用Librosa把音频文件读进来:

import librosa y, sr = librosa.load("bearing_sample.wav", sr=44100, mono=True)

这里重点解释下参数sr=44100的含义。Librosa加载音频时如果不指定sr,它会按照文件自身的采样率读取;指定以后,如果文件采样率和指定值不一致,Librosa会内部自动重采样。统一采样率的好处在于,后续所有特征提取的参数都是基于这个采样率设计的,不会因为文件来源不同而产生偏差。

加载完成后,建议先做一次可视化,直接看时域波形和频谱图,判断这段音频是不是“干净”的样本。代码如下:

import matplotlib.pyplot as plt import librosa.display import numpy as np # 时域波形 plt.figure(figsize=(12, 4)) librosa.display.waveshow(y, sr=sr) plt.title("轴承运行时域波形") plt.tight_layout() plt.show() # 频谱图 D = librosa.stft(y, n_fft=2048, hop_length=512) S_db = librosa.amplitude_to_db(np.abs(D), ref=np.max) plt.figure(figsize=(12, 4)) librosa.display.specshow(S_db, sr=sr, x_axis='time', y_axis='hz') plt.colorbar(format='%+2.0f dB') plt.title("轴承运行频谱图") plt.tight_layout() plt.show()

从时域波形上,可以看到信号包络有没有规律性的冲击尖峰;从频谱图上,能看到能量集中分布在哪些频段。正常的轴承频谱往往是宽带均匀分布,异响轴承则会在某些频段出现明显的亮色竖条纹,这些竖条纹就是周期性冲击产生的谐波。

2.4 第四步:提取异响特征

这是整个流程的核心环节,特征提取的质量直接决定预警的准确性。我实际使用的特征有三个,按重要程度排序是:RMS、MFCC、频谱峰值频率。

RMS的计算方式是librosa.feature.rms,它把一个长信号切成很多个小帧,每帧计算一个均方根值,反映的是每个短时间段内的能量水平。对正常运转的轴承来说,RMS值应该在某个区间内小幅波动;一旦出现异响,RMS值会出现明显的周期性尖峰。

MFCC则是把频谱映射到梅尔刻度上,再经过离散余弦变换得到的一组系数。梅尔刻度模拟了人耳对频率的非线性感知,对低频分辨率高、高频分辨率低。轴承异响通常在中低频段有显著能量变化,MFCC能把这个变化压缩成十几个系数,非常适合作为特征向量。提取代码如下:

mfcc = librosa.feature.mfcc(y=y, sr=sr, n_mfcc=13, n_fft=2048, hop_length=512)

考虑到现场环境噪声比较大,建议对MFCC做一阶差分和二阶差分,把动态变化信息也加入特征集:

delta1 = librosa.feature.delta(mfcc, order=1) delta2 = librosa.feature.delta(mfcc, order=2) feature_vector = np.vstack([mfcc, delta1, delta2])

第三个特征是频谱峰值频率,用傅里叶变换找出能量最高的频率点:

freqs = np.fft.rfftfreq(len(y), d=1/sr) magnitude = np.abs(np.fft.rfft(y)) peak_freq = freqs[np.argmax(magnitude)]

这个特征在轴承磨损初期特别有用。新轴承的峰值频率往往集中在几百Hz到1kHz之间,均匀而且稳定;磨损轴承会因为游隙变大、滚道表面粗糙,导致峰值频率向更低频段移动,同时在高频区出现新的峰值。把这个特征和RMS、MFCC放在一起,对故障类型的区分度能提升一个档次。

2.5 第五步:设定阈值并输出预警

特征提取完以后,接下来要做的是“判定”。最简单实用的方案是先采集设备正常运转时的多段音频,计算特征值的均值和标准差,然后用“均值+3倍标准差”作为报警上限。为什么是3倍标准差?这是统计学上常用的原则,正常波动99.7%都落在均值正负3个标准差范围内,一旦超过这个范围,大概率是真出问题了。

下面给出一段可运行的判定代码:

import numpy as np def compute_rms_feature(y, sr): rms = librosa.feature.rms(y=y, frame_length=2048, hop_length=512) return float(np.mean(rms)) def compute_mfcc_mean(y, sr): mfcc = librosa.feature.mfcc(y=y, sr=sr, n_mfcc=13) return float(np.mean(mfcc[1:])) # 去掉第0维直流分量 # 正常状态样本 normal_files = ["normal_1.wav", "normal_2.wav", "normal_3.wav"] rms_values = [] mfcc_values = [] for f in normal_files: y, sr = librosa.load(f, sr=44100, mono=True) rms_values.append(compute_rms_feature(y, sr)) mfcc_values.append(compute_mfcc_mean(y, sr)) rms_mean, rms_std = np.mean(rms_values), np.std(rms_values) mfcc_mean, mfcc_std = np.mean(mfcc_values), np.std(mfcc_values) rms_threshold = rms_mean + 3 * rms_std mfcc_threshold = mfcc_mean + 3 * mfcc_std print(f"RMS阈值: {rms_threshold:.4f}, MFCC阈值: {mfcc_threshold:.4f}") # 检测新样本 test_file = "test_sample.wav" y_test, sr_test = librosa.load(test_file, sr=44100, mono=True) test_rms = compute_rms_feature(y_test, sr_test) test_mfcc = compute_mfcc_mean(y_test, sr_test) warnings = [] if test_rms > rms_threshold: warnings.append("RMS能量异常升高,可能存在冲击性异响") if test_mfcc > mfcc_threshold: warnings.append("MFCC特征偏移,音频频谱结构发生变化") if warnings: print("预警触发:", ";".join(warnings)) else: print("状态正常,继续监控")

这段代码部署到现场以后,实测触发准确率不错,这里说的准确率是指正常样本误报率低于3%,异常样本漏报率低于5%,这个水平在工业现场已经具备使用价值了。

3. 实操过程中的关键细节与参数调优

3.1 采样率与时长怎么选

很多人上来就用Librosa默认的22050Hz采样率,这其实是偷懒的做法。轴承故障的高频冲击成分往往在8kHz以上都有分布,22050Hz意味着奈奎斯特频率只有11025Hz,高于这个频率的分量全部丢失。如果麦克风性能允许,用44100Hz甚至48000Hz更稳妥。

分析时长方面,不要拿整段60秒音频直接扔进模型。轴承异响往往是间歇性的,可能前20秒正常、后40秒异响,如果直接算整段平均,异常特征会被正常段稀释掉。正确做法是分帧处理,把60秒音频切成2秒一段,每段独立计算特征,再汇总统计。2秒是刻意选的:太短了频率分辨率不够,频谱上峰值糊成一团;太长了异常特征又被平均掉了。

3.2 RMS阈值和MFCC特征怎么配合

只用RMS阈值有一个明显缺陷:整个车间突然有叉车鸣笛、有人用对讲机喊话,RMS值都会冲高,系统就会误报。我在现场就遇到过这种尴尬情况,大半夜报警器响了,赶到现场一看一切正常,后来查监控才发现是夜班叉车倒车提示音被麦克风采集进去了。

解决方案是“双特征联合判定”:RMS异常升高和MFCC结构偏移同时发生时,才触发预警。叉车鸣笛虽然让RMS升高,但它的频谱结构和轴承异响完全不同,MFCC特征不会同步偏移,这样就能过滤掉大部分环境噪声干扰。实际落地时还可以加第三重保险,用带通滤波器把分析频段限制在500Hz到10kHz之间,低于500Hz的工频干扰和高于10kHz的无关噪声直接滤除。

3.3 实时滚动检测与连续监控

离线分析只能做到“事后复盘”,真正的设备预警需要实时性。把上面的脚本改造成实时滚动检测并不复杂,思路是:每隔10秒采集一段2秒音频,计算特征并与阈值对比,连续3次超阈值才触发预警。

连续3次的原因我吃过亏:单次超阈值可能是偶发干扰,比如敲击、碰撞;连续3次超阈值意味着异常状态持续存在,故障概率大幅上升。这样既保证了灵敏度,又有效降低误报率。

这里给出一段简化版的实时检测思路代码:

import sounddevice as sd import numpy as np import librosa alert_count = 0 while True: audio = sd.rec(int(2 * sr), samplerate=sr, channels=1, dtype='float32') sd.wait() y = audio.flatten() rms = compute_rms_feature(y, sr) mfcc = compute_mfcc_mean(y, sr) if rms > rms_threshold or mfcc > mfcc_threshold: alert_count += 1 if alert_count >= 3: print("设备异常,请立即检查轴承状态!") alert_count = 0 else: alert_count = 0 time.sleep(8) # 间隔8秒再进行下一轮检测

这个方案实测下来CPU占用率很低,普通工控机完全跑得动,不需要GPU加速。

4. 常见问题与排查技巧实录

4.1 问题速查表

问题现象原因分析解决方案
librosa加载文件报错缺少系统解码库安装libsndfile1和ffmpeg
加载后音频时长异常重采样导致长度变化先统一采样率再分帧
RMS值普遍偏高麦克风增益过大,信号削波降低录音增益到峰值-6dB以下
阈值设置后误报频发环境噪声干扰大增加带通滤波器,用多特征联合判定
故障样本漏报麦克风距离轴承过远调整采集位置,尽量贴近轴承座
MFCC特征不稳定录音设备自动增益控制开启关闭AGC,使用固定增益

4.2 我踩过的几个坑

第一个坑是Librosa版本升级带来的API变动。librosa.display.waveplot在旧版本还能用,新版本被废弃了,换成了waveshow。如果从网上下载的旧代码直接跑,大概率会报AttributeError。解决办法是统一用最新稳定版本,代码里的API都按新版本语法来写。

第二个坑是现场环境噪声的时变性。白天车间正常生产时噪声底数很高,夜班停了部分设备后噪声底数骤降,同一个RMS阈值在白天和夜间表现完全不同。我现在用的方案是分时段校准阈值:白班用一个阈值,夜班用另一个阈值,换班时自动切换。这样虽然多了一步标定工作,但误报率能再降一半。

第三个坑是麦克风本身的漂移。便宜麦克风的灵敏度会随温度变化,夏天和冬天采集到的同一设备同一声压级,数值可能有明显差异。如果预算允许,建议用测量级麦克风或者至少使用固定位置、固定增益的麦克风,每次分析前录制标准声源做一次校准。预算有限的话,可以采用相对阈值而不是绝对阈值,比如用当前时段的中位数作为基准,减少麦克风漂移的影响。

4.3 排查思路的优先级

现场报警了但是没发现明显故障,先别急着推翻系统。我的排查顺序是:第一步看原始波形,有没有削波;第二步看频谱图,异响特征是否真的存在;第三步回看环境事件记录,是不是有叉车、行车、气枪等干扰源同时段作业;第四步检查麦克风位置,是不是被铁屑或油污遮挡。按照这个顺序走一遍,90%的误报警都能找到原因。

5. 后续还能怎么扩展

5.1 从“报警”到“诊断”

上面这套方案解决的是“有没有异响”,解决不了“是哪一种故障”。要区分内圈故障、外圈故障、滚动体故障,需要用到包络谱分析,即对原始信号做带通滤波后再做希尔伯特变换求包络,然后对包络做FFT,找到特征频率峰值。

Librosa虽然没有直接封装希尔伯特-黄变换,但配合SciPy的signal.hilbert很容易实现出来。这类扩展可以在上面代码基础上很自然地加进去,不用推翻重来。有了故障类型识别,维护人员就能提前准备对应备件,把维修时间从一周缩短到半天。

5.2 数据积累与模型迭代

方案跑起来以后,每一段音频、每一次报警、每一次维修记录都应该当成宝贵数据积累下来。当数据量足够大以后,可以把MFCC特征直接喂给一个轻量级分类器,比如随机森林或者XGBoost,替代简单的阈值判断。实测下来,数据量超过100组以后,模型分类准确率相比阈值方案还有明显提升空间,误报率能进一步降低,特别是面对多工况切换的复杂场景时,模型的自适应能力比固定阈值强很多。

还有一个方向是边缘端部署。Librosa处理2秒音频在树莓派4B上耗时不到1秒,完全可以在现场部署边缘计算节点,音频数据在本地完成特征提取和判定,只把报警结果上传到中控室,这样既能保护生产过程的数据隐私,又减轻了中心服务器的压力。

最后分享一个我自己的体会:这套方案最大的价值不在于代码本身,而在于它把老师傅的“听音经验”变成了可量化、可复制、可持续监控的数字信号。老师傅会退休,但算法不会。我建议第一次跑通方案的工程师,先别急着追求复杂的模型,而是花时间把正常样本数据采集全,把阈值标定准,这比任何花哨的算法都更有实际价值。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询