简介:这是一份可直接运行的MATLAB源程序,面向信号处理初学者、通信与振动分析领域的研究者,解决如何用希尔伯特变换求取信号包络谱的核心问题。希尔伯特变换通过构造解析信号来提取瞬时包络,在设备故障诊断、调幅信号解调、语音分析等场景中非常实用;程序围绕这一原理设计了完整流程:生成或导入原始信号,调用hilbert()得到解析信号,对变换结果取绝对值获得包络,并绘制原始波形、包络线及频谱图。代码模块化程度高,便于替换信号源、调整采样频率、增加滤波平滑步骤,从而深入理解各环节对包络谱结果的影响。压缩包内仅1个m文件,整体仅888B,文件精简却覆盖了从变换到可视化的关键代码,适合快速测试算法或作为教学模板。目前已有741人学习下载,尤其适合希望结合实例掌握包络谱分析的MATLAB学习者。
1. 希尔伯特变换求包络谱,为什么“可直接运行”值钱
滚动轴承外圈出现局部剥落时,加速度计采到的信号往往是一串被高频共振反复调制的复杂波形:直接对它做 FFT,能看到的只有共振频带里一团凸起,真正与转速强相关的故障特征频率被埋在底下。改用希尔伯特变换求出包络后再做频谱,故障特征频率就会以明显谱峰的形式暴露出来,这就是包络谱分析。标题里这组“可直接运行”的 MATLAB 源码,本质就是把带通滤波、希尔伯特变换、包络谱绘制按固定流程串起来,解压后喂进振动数据就能复现一整套特征提取链路。
这类代码包的价值不在“能跑”,而在参数是否按实际数据调过。对做设备状态监测的工程师和刚接触包络谱的信号方向研究生来说,与其从零拼装脚本,不如先把带通范围、频率分辨率、去直流这几个环节的默认值弄清楚,再替换成自己的数据。接下来按理论、最小可运行工程、必调参数、验证技巧四层把它讲透。
2. 解析信号与包络谱原理:hilbert 函数在做什么
2.1 从实信号到解析信号:hilbert 的频谱操作
MATLAB 的hilbert函数名字容易骗人。x_analytic = hilbert(x)返回的不是“变换后的实信号”,而是复解析信号:实部就是原始信号x,虚部才是x的希尔伯特变换结果H{x}。MATLAB 内部并不在时域做 1/(πt) 卷积,而是对x做 FFT、把负频率谱线置 0、再做 IFFT,得到一个单边频谱的复信号。因此:
envelope = abs(hilbert(x)); % 瞬时幅值包络 phase = angle(hilbert(x)); % 瞬时相位abs(hilbert(x))就是解析信号的模,也就是包络。这里有个初学者常踩的坑:hilbert(x)的实部是原信号,不是变换结果;想要希尔伯特变换后的实信号,应该取imag(hilbert(x))。直接对hilbert(x)取实部再算包络,等于对原信号做包络,什么都提不出来。
2.2 包络与瞬时频率:两个容易混淆的输出
解析信号同时给出两个信息:瞬时幅值A(t)和瞬时相位φ(t)。包络是A(t),反映了信号幅值随时间的缓变规律;瞬时频率是dφ/dt,反映信号频率的瞬态变化。包络谱分析只用前者,对A(t)再做 FFT 得到包络频谱。
实际振动数据里瞬时频率对噪声极敏感,差分后往往变成一片毛刺,不适合直接做故障诊断。包络则不同,它对载波频段内的共振成分做了解调,保留了调制源的低频信息,统计上稳定得多。这就是为什么滚动轴承故障诊断普遍用包络谱,而不是直接看原始幅值谱或瞬时频率曲线。
2.3 调制边带实验:为什么包络谱能暴露故障特征
调幅信号的频谱结构可以很直观地说明包络谱的价值。一个载波sin(2π·fc·t)被低频fm调制后,频谱上不是只有fc,而是fc与fc±fm两个边带。故障冲击相当于周期性调幅信号,边带幅度往往很小,在噪声里看不出来。包络运算把载波中心对齐到零频,再做频谱,fm本身就会变成低频段的独立谱峰。
用一小段代码验证这个现象:
%% 调制信号频谱与包络谱对照 fs = 10000; T = 1; t = (0:fs*T-1)/fs; fc = 1000; % 载波频率,模拟系统共振 fm = 50; % 调制频率,模拟故障特征频率 y = (1 + 0.8*sin(2*pi*fm*t)) .* sin(2*pi*fc*t); N = length(y); f = (0:N-1)*fs/N; Y_raw = abs(fft(y))/N; % 原始幅值谱 E_raw = abs(fft(abs(hilbert(y))))/N; % 包络谱 figure; stem(f(1:200), Y_raw(1:200), 'BaseValue', 0, 'LineWidth', 0.5); xlabel('频率 (Hz)'); ylabel('幅值'); title('原始信号频谱局部'); figure; stem(f(1:200), E_raw(1:200), 'BaseValue', 0, 'LineWidth', 0.5); xlabel('频率 (Hz)'); ylabel('幅值'); title('包络谱局部');原始频谱里 950Hz、1000Hz、1050Hz 三根谱线相邻出现,其中两根边带幅度很低;包络谱里 50Hz 处出现突出尖峰,边带信息被集中到低频段。对比之后就能理解,包络谱是“先解调、再谱分析”的流程,解调靠的就是hilbert产生的解析信号。
3. 可直接运行的 MATLAB 最小工程:从原始信号到包络谱
3.1 主脚本结构与完整代码
拿到“可直接运行”的包络谱工程,第一步不是看代码,而是确认三条基本路径:主脚本入口、数据文件位置、输出图保存位置。常见做法是把主脚本和数据放同一级目录,用相对路径读取,避免换机器后cd串了。下面的脚本是一个自包含的示例,替换数据文件即可用于真实信号:
%% 可直接运行的包络谱计算示例:滚动轴承外圈故障模拟 clear; clc; close all; rng(0); % 采集参数 fs = 51200; % 采样率 51.2 kHz,按传感器量程选择 T = 2; % 记录时长 2 s,频率分辨率 0.5 Hz N = fs * T; t = (0:N-1)/fs; % 模拟信号:共振载波被外圈故障特征频率调制 fr = 25; % 转频,约 1500 rpm BPFO = 95.5; % 外圈特征频率,Z=9、d/D≈0.15 时约 3.82 倍转频 f_reso = 2100; % 系统共振中心频率 y = (1 + 0.85*sin(2*pi*BPFO*t)) .* sin(2*pi*f_reso*t); y = y + 0.5 * sin(2*pi*2*fr*t + pi/4); % 二倍转频干扰 y = y + 0.05 * randn(size(t)); % 传感器噪声 % 第 1 步:带通滤波,只保留共振带内的调制成分 y_filt = bandpass(y, [1200 3000], fs, 'ImpulseResponse', 'iir'); % 第 2 步:希尔伯特变换求包络 env = abs(hilbert(y_filt)); % 第 3 步:包络去直流后再做 FFT env_ac = env - mean(env); N_fft = length(env_ac); Y_env = fft(env_ac); freq = (0:N_fft-1) * fs / N_fft; half = 1:floor(N_fft/2); env_spec = abs(Y_env(half)) * 2 / N_fft; % 单边幅值谱 freq_half = freq(half); % 第 4 步:谱峰搜索与绘图 [pks, locs] = findpeaks(env_spec, 'MinPeakProminence', max(env_spec)*0.1); figure; plot(freq_half, env_spec, 'LineWidth', 0.8); xline(95.5, '--r'); xline(191, '--r'); xlim([0 1000]); xlabel('频率 (Hz)'); ylabel('包络谱幅值'); hold on; plot(freq_half(locs), pks, 'v'); for i = 1:length(locs) text(freq_half(locs(i)) + 8, pks(i), num2str(round(freq_half(locs(i)), 1))); end脚本里rng(0)保证模拟数据可复现;实际工程数据不需要也不应该固定随机种子。bandpass属于信号处理工具箱,老版本没有这个函数时,可改用designfilt手动设计带通滤波器,效果等价但代码多几行。
3.2 关键函数参数说明
上面的流程里,真正影响包络谱质量的参数集中在三处:
| 参数 | 示例值 | 作用与调整方向 |
|---|---|---|
fs | 51200 Hz | 决定可分析频率上限,低于信号最高频率的 2.56 倍会出现混叠 |
T记录时长 | 2 s | 频率分辨率 =1/T,想分辨 0.5 Hz 的谱峰间隔,时长至少 2 s |
bandpass通带 | [1200 3000] | 需包住系统共振峰及调制边带,选窄了削边带,选宽了抬噪声 |
ImpulseResponse | 'iir' | 阶数低、过渡带窄;要求线性相位时改'fir',但执行更慢 |
MinPeakProminence | max(env_spec)*0.1 | 谱峰筛选阈值,现场数据噪声高时按最大谱峰的百分比调 |
bandpass(y, [f1 f2], fs, 'ImpulseResponse', 'iir')是 r2023b 及以上版本都稳定支持的调用方式。选 IIR 是因为共振带窄、过渡带要求高,IIR 在相同阶数下滚降特性更好;代价是非线性相位会改变瞬时频率,但包络谱只关心幅值,对相位失真不敏感。
3.3 运行预期与结果判读
脚本运行后,95.5 Hz 处应出现明显主峰,191 Hz 附近出现二倍频峰,两处都被红色虚线标注。主峰幅值显著高于噪声基底,这是因为带通滤波把二倍转频 50 Hz 干扰和宽带噪声都滤掉了,包络里只剩故障冲击调制的周期成分。
判读时注意三点:一是包络谱的横轴单位始终是 Hz,纵轴是包络的幅值,不是原始振动加速度的幅值;二是如果主峰不在 95.5 Hz 而在 50 Hz 附近,说明带通下限设低了,二倍转频成分漏了进来;三是findpeaks标注出的第一个峰若出现在 0 Hz 附近,通常不是故障特征,而是包络未去干净直流。
4. 包络谱的 3 个必调参数与现场排错
4.1 采样率与记录时长:先定频率分辨率再定数据量
频率分辨率直接决定包络谱能把多近的谱峰分开,公式是Δf = fs / N = 1 / T。想分辨 0.5 Hz,记录时长就至少 2 s;想分辨 0.1 Hz,就要 10 s。提高采样率不能提高分辨率,只会增加点数、拉长计算时间。先按目标分辨率确定T,再按目标分析频率上限确定fs,顺序不能反。
现场常见的误用是把采样率开得很高,记录时长却只有零点几秒,导致包络谱分辨率超过 1 Hz。滚动轴承故障特征频率往往和转频靠得很近,分辨率不足时特征峰和转频峰叠在一起,无法区分。遇到谱峰成片、宽度超过两三个频率格的情况,优先怀疑分辨率不足或转速波动,而不是滤波参数。
4.2 带通范围:[f1 f2] 的选取方法
带通范围选错是包络谱失效的头号原因。hilbert本身不挑频段,但包络谱要提取的是“被故障频率调制的共振成分”。共振带外的信号,尤其是转频、齿轮啮合频率和随机干扰,只会抬高噪声基底。
选范围的标准做法是:先对原始信号做一幅平均功率谱,找到共振峰所在频带,再取该峰半功率带宽的 1.5 到 2 倍作为带通区间。
% 用平均功率谱找共振带中心 [Pxx, F] = pspectrum(y, fs); plot(F, 10*log10(Pxx)); xlabel('频率 (Hz)'); ylabel('功率谱 (dB)');在功率谱上能看到 2100 Hz 附近的驼峰,那是系统共振带。带通下限取 1200 Hz、上限取 3000 Hz,就是把共振峰完整包住,同时滤掉 50 Hz 工频及其谐波。如果共振峰不明显,说明激励不足或传感器安装位置不当,续做包络谱的意义有限。
4.3 去直流、单边乘 2 与补零误区
包络信号是正实信号,频谱在 0 Hz 附近有一个很大的直流分量。直接对它做 FFT,低频段的谱峰会被直流的泄漏斜坡淹没。第 3 章脚本里的env - mean(env)就是在干这件事。漏掉这一步的人,包络谱里最常见的就是 0 Hz 处一根冲向顶部的尖峰,所有 100 Hz 以下的特征全部看不出来。
单边谱的幅值还原则是另一个高频问题。fft的结果对称分布在正负频率上,只取正半轴时,除了直流分量,每条谱线都要乘2/N才等于真实幅值。如果忘了乘2,所有峰都会低一半;如果对直流也乘2,0 Hz 峰会比其他峰高一倍,容易被误判成故障频率。
补零在这里经常被误解。对包络序列末尾补零再 FFT,只能让谱线变密,画出来的图形更平滑,并不能提高物理分辨率。真实分辨率只由记录时长决定,补零无法把相距 0.8 Hz 的两个真实分量拆开。现场排错时遇到“补零后出现新谱峰”,基本可以认定是插值产生的旁瓣,不是真实特征。
5. 包络谱峰值归属验证:3 个不需要再采集的检查技巧
5.1 合成信号自检
把第 3 章脚本里的y换成一组无故障周期的合成信号,先确认流程本身不出错:
%% 用已知调制频率自检包络谱流程 fa = 95.5; ya = (1 + 0.9*sin(2*pi*fa*t)) .* sin(2*pi*2100*t); ya = ya + 0.05*randn(size(t)); % 复用上一章的 bandpass、hilbert、fft 流程 ya_filt = bandpass(ya, [1200 3000], fs, 'ImpulseResponse', 'iir'); env_a = abs(hilbert(ya_filt)); [~, idx_a] = max(abs(fft(env_a - mean(env_a)))); fprintf('自检主峰频率:%.2f Hz\n', (idx_a-1)*fs/length(ya));如果自检主峰不在 95.5 Hz 附近,说明流程里的滤波或去直流环节有误,这时候不应该急着处理真实数据。
5.2 转频整数倍与残差核对
拿到真实数据的包络谱后,先画一条转频的整数倍竖线。正常情况下包络谱只在fr、2fr等整数倍位置有确定的峰。若旁边出现一个非整数倍的新峰,比如转频 25 Hz 时出现 95.5 Hz 的峰,比值 3.82,不等于任何整数,就要用轴承几何参数核对理论特征频率。外圈固定的滚动轴承,BPFO ≈ 0.5·Z·(1 - d/D·cosα)·fr。Z=9、d/D≈0.15、接触角接近 0 时,理论值约 3.82 倍转频,和实测峰完全对应。
残差检查的标准是:实测峰频率与理论特征频率之差要小于半个频率分辨率格,即|f_measured - f_theory| < 0.5·Δf。记录时长 2 s 时Δf=0.5 Hz,允许偏差 0.25 Hz。超出这个范围,优先怀疑转速波动,而不是故障类型判断错了。
5.3 边带差频核对
包络谱里成对出现的谱峰,往往不是两个独立故障,而是同一调制源产生的边带。检查方法很直接:对候选峰做差频运算,看差值是否落在转频或工频等已知基准上。比如 95.5 Hz 和 145.5 Hz 同时出现,差频 50 Hz,正好是工频,说明 145.5 Hz 很可能是 95.5 Hz 的调制边带,而不是独立的第二处故障。这个检查在齿轮箱和电机轴承复合故障场景下尤其有效,能避免把边带峰误判成新故障源。把这三个步骤按顺序做完,包络谱里每个显著峰都能落到对应的转频关系上,计算结果才算闭环。
本文还有配套的精品资源,点击获取