ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

小波变换信号降噪原理与MATLAB仿真调参实战

小波变换信号降噪原理与MATLAB仿真调参实战 先讲一个背景。设备状态监测和工业信号处理里信号降噪是最基础、也最容易翻车的一步。以前我拿到数据第一反应就是低通滤波或者做一次 FFT 再甩掉高频后来发现这套方法对付平稳信号还行一遇到非平稳信号要么削了真实突变要么留了一堆毛刺。改用小波变换之后我才真正理解了“分析尺度”这几个字的含金量。这篇文章从原理、参数到 MATLAB 仿真完整记录一遍我进行信号降噪处理和方案选型的过程希望能帮你少走几天弯路。1. 为什么小波变换在降噪里比单纯滤波更靠谱先说一个最容易让人困惑的问题既然低通滤波和傅里叶变换都能去掉噪声为什么还要用小波变换低通滤波器的思路很直接噪声一般是高频成分我把超过某个截止频率的分量全部压掉。这个方案对平稳信号确实有效但有一个很致命的代价有用信号里的突变、尖峰、阶跃本质上也是高频成分。尤其是设备振动信号里的轴承故障冲击、心电信号里的 QRS 波群、语音信号里的辅音起始点这些关键特征一旦被低通滤波器处理就直接糊掉了。傅里叶变换的问题类似。FFT 把整段信号分解成不同频率的正弦波叠加你能知道信号里有哪些频率成分却不知道这些频率成分具体出现在哪个时间段。一个频率为 100 Hz 的局部冲击和一个持续整段时间的 100 Hz 正弦分量在频谱上可能长得差不多但你完全分不清它们的时间位置。对降噪来说这意味着你无法区分“高频噪声”和“高频有用特征”。小波变换的核心优势在于“时频局部化”。它用一族可以伸缩和平移的小波基函数去匹配信号的局部特征。低频部分用较长的时间窗频率分辨率高高频部分用较短的时间窗时间分辨率高。这就相当于同时戴了两副眼镜一副看全局趋势一副看局部细节。另一个实际层面的原因小波变换是可逆的。也就是说我先把信号分解到不同尺度上把噪声所在的尺度系数做处理再用逆变换重构信号整个过程信息损失可控。相比之下有些非线性滤波方法比如中值滤波或者滑动平均虽然也能去噪但很难做到无损重构而且滤波窗口一大了就容易产生相位偏移。我个人的体感是小波变换不是要替代所有传统方法它适合的信号类型非常明确就是“非平稳、含有瞬态突变、噪声与信号频带有重叠”的场景。如果你的信号本身就是平稳正弦波噪声也是宽白噪声那低通滤波表现可能也并不差。但工程现场采集到的信号很少有这么理想的时候。2. 小波降噪的底层原理搞懂这几个概念就不懵很多教材一上来就堆一堆公式其实容易把人劝退。我换个方式讲把小波降噪想象成“用多把筛子筛东西”。大尺度筛子筛出信号的整体轮廓小尺度筛子筛出信号的尖峰细节。噪声则混杂在各个尺度里需要我们用一套规则把它们挑出去。2.1 分解和重构到底在做什么连续小波变换的定义是把信号和一个经过伸缩平移的小波函数做内积得到一组小波系数。但实际工程中我们几乎不用连续小波变换因为计算量太大而且信息冗余。真正落地的是离散小波变换最常用的是 Mallat 算法。Mallat 算法的思路也简单信号先通过一个低通滤波器得到一个近似系数序列同时通过一个高通滤波器得到一个细节系数序列。然后每次只对近似系数继续分解一层一层往下走。这个过程可以理解为第一层分解后得到近似分量 A1 和细节分量 D1第二层分解时对 A1 继续拆分得到 A2 和 D2每多拆一层频率范围就往低频方向挪一档。降噪时真正的噪声能量主要集中在细节分量里。近似分量往往保留了信号的主要能量和趋势。所以常见的做法是只对细节系数做阈值处理保留近似系数不处理然后再通过逆小波变换重构信号。我建议刚开始接触的同学不要死磕二维小波或者复杂的小波包先从一维离散小波变换入手把 C、L 这两个矩阵结构看明白后面的路会顺很多。2.2 阈值怎么选硬阈值、软阈值与几种常用规则阈值法的逻辑在小波降噪里是核心中的核心。信号经过小波分解后真实信号对应的小波系数幅值通常比较大而噪声对应的小波系数幅值比较小而且分布相对均匀。所以我们设一个阈值把小于阈值的系数置零或者做一定压缩就能把大部分噪声干掉。阈值处理有两种最经典的策略硬阈值绝对值大于阈值的系数保留原值小于阈值的全部置零。优点是不压缩有效信号幅度缺点是系数在阈值附近会发生跳变重构出来的波形容易有抖动和振铃。软阈值绝对值大于阈值的系数向零方向收缩一个阈值量小于阈值的置零。优点是连续性好重构波形平滑缺点是会把真实信号的幅度也压小一点导致信号变“矮”。实际使用中软阈值用得更多因为它稳定。但如果你特别在意波形的幅值比如要分析冲击特征的能量大小就要考虑半软阈值或者改进型阈值函数后面我会专门讲。阈值本身的取值有几种常用规则通用阈值也叫 VisuShrink公式是 lambda sigma * sqrt(2*log(N))sigma 是噪声标准差N 是信号长度。这个阈值对高斯白噪声效果好但信号较长时阈值容易偏大导致过度平滑。rigrsure 规则基于 Stein 无偏风险估计阈值选得更“聪明”适合信噪比不低、细节丰富的情况。heursure 是通用阈值和 rigrsure 的折中信号信噪比低时倾向用通用阈值信噪比高时倾向用 rigrsure。minimaxi 规则阈值相对保守能保留更多细节但噪声滤除率也会低一些。实际项目里我一般先跑通用阈值看整体效果再用 rigrsure 微调找出保留细节和滤除噪声的平衡点。2.3 除了阈值小波基和层数为什么重要阈值只是其中一个环节小波基函数和分解层数同样直接决定效果。小波基函数的核心指标有正交性、紧支性、消失矩和对称性。消失矩越高小波能匹配信号的平滑部分就越强对应的高频分量也就越敏感。但代价是支撑长度变长计算量变大边界失真也更明显。所以并不是消失矩越高越好。分解层数的作用也很关键。层数太少噪声没有被充分分离去噪不彻底层数太多信号的有用低频成分也可能被当作噪声处理重构后波形失真严重。这俩参数和阈值规则是相互耦合的调参的时候不能单独看某一个。3. 用 MATLAB 复现一次小波降噪仿真前面把理论过了一遍下面直接进仿真。我用的是带噪声的多频叠加信号模拟工程中常见的混合信号情境。整套流程在 MATLAB R2020 之后都能直接跑。3.1 构造带噪信号为了能评价去噪效果我们先用一个已知干净的原始信号再叠加高斯白噪声。这样处理后可以计算信噪比和均方根误差。clear; close all; clc; rng(42); fs 1000; % 采样率 1000 Hz t (0:fs-1)/fs; % 1 秒 % 原始有用信号三个不同频率分量的叠加 x 5*sin(2*pi*50*t) 2*cos(2*pi*120*t) 0.8*sin(2*pi*260*t); % 高斯白噪声标准差 1.5 noise 1.5*randn(size(t)); % 含噪信号 s x noise;这里把三个频率分量放在 50 Hz、120 Hz 和 260 Hz模拟一种宽频带混合信号。噪声标准差设为 1.5得到的输入信噪比大约是SNR_in 10*log10(sum(x.^2)/sum(noise.^2));算下来大概在 8 dB 左右是比较典型的低信噪比工程场景。3.2 核心去噪代码我推荐先自己写一遍分解、阈值处理、重构的完整流程而不是直接无脑调 wdenoise。这样你对数据在每个环节的变化会有更直观的感觉。level 5; % 分解层数 wname sym8; % 小波基函数 % 小波分解 [C, L] wavedec(s, level, wname); % 提取第一层细节系数用于估计噪声标准差 D1 detcoef(C, L, 1); sigma median(abs(D1)) / 0.6745; % 通用阈值 lambda sigma * sqrt(2*log(length(s))); % 保留低频近似系数对其他系数做软阈值处理 start_idx L(1) 1; C_new C; C_new(start_idx:end) wthresh(C(start_idx:end), s, lambda); % 重构 x_den waverec(C_new, L, wname);这里有个细节要注意sigma的估计使用了第一层细节系数。因为白噪声经过一次高通滤波后能量最高、分布最接近高斯分布的往往就是第一层细节系数。用这个中位数绝对偏差公式估计噪声标准差是 Donoho 和 Johnstone 的经典做法比直接对原始数据求标准差要稳。如果你觉得手动流程太啰嗦也可以直接用 MATLAB 自带的封装函数x_den2 wdenoise(s, level, Wavelet, wname, ... DenoisingMethod, SURE, ThresholdRule, Soft);不过我现在还是更习惯手动流程因为可以随时修改阈值规则也方便把中间系数导出来看效果。3.3 结果评估指标去噪效果好不好不能只用眼睛看要有量化指标。我最常用的三个指标是% 信噪比 SNR单位 dB SNR (x, xd) 10*log10(sum(x.^2) / sum((x - xd).^2)); % 均方根误差 RMSE RMSE (x, xd) sqrt(mean((x - xd).^2)); % 相关系数 R corrcoef(x, x_den); CC R(1, 2);运行后你会得到三组数输入 SNR 大概在 8 dB 左右去噪后 SNR 一般能提升到 14 dB 到 18 dB 这个区间具体取决于参数RMSE 从 1.5 左右降到 0.4 到 0.7 之间相关系数能到 0.95 以上说明重构波形和原始信号的相似度很高。绘图部分我用两张图对比figure; subplot(3,1,1); plot(t, x); title(原始信号); subplot(3,1,2); plot(t, s); title(含噪信号); subplot(3,1,3); plot(t, x_den); title(小波去噪后信号);看图形时重点看两个位置一是信号的拐点和峰值有没有被削平二是去噪后的曲线是否还残留高频抖动。4. 参数怎么调小波基、层数、阈值规则的取舍小白最容易卡在“参数调不对”这一步。同一份数据换个小波基或者层数结果可能完全不同。这一节我把调参思路梳理一遍相当于给一个可复用的经验模板。4.1 小波基选择与效果对比先说结论没有最好的小波基只有最适合当前信号的小波基。我根据自己的经验整理了一张选型参考表小波基特点适用场景haar结构最简单适合阶跃和突变数字信号、分段常数信号db2/db4正交、紧支性好经典生物电信号、振动信号sym4/sym8近似对称相位失真小工程混合信号通用性好coif4/coif5消失矩较高平滑性好变化缓慢的连续信号bior3.5/bior4.4双正交对称性好图像信号、需要保留相位我自己的习惯是优先试 sym8。因为它在支撑长度和消失矩之间比较均衡对称性也比 db 系列好不容易造成明显的相位偏移。如果去噪后波形两端出现奇怪的抖动再换成 coif4 或者 bior。一个小技巧如果你处理的信号本身就有比较明显的周期冲击成分比如齿轮箱故障信号可以优先考虑消失矩高一些的小波基比如 sym10 或者 db8这样能更准确地刻画冲击特征。4.2 分解层数的影响分解层数是另一个容易翻车的参数。理论上层数越多频率划分越细但实际工程里不是越大越好。层数太少时噪声和信号在最高频的细节分量里还没充分分开阈值处理会把噪声留下。层数太多时信号的一个重要低频成分也可能被分解到很深的细节层里被阈值误杀。我总结的经验是采样率 1000 Hz 左右的数据一般设 4 到 6 层采样率 4000 Hz 以上时可以适当加大到 7 到 8 层。但不要盲目超过 8 层因为每次分解都会引入边界效应层数越多边界效应积累越严重。如果实在拿不准可以写个循环分别用 level 3 到 8 跑一遍去噪对比 SNR 和 RMSE。我通常选 SNR 最高、RMSE 最小的那组但还要扫一眼波形确保没有明显失真。4.3 改进阈值函数半软阈值和自适应阈值硬阈值和软阈值各有缺陷工程实践里我更推荐半软阈值函数也叫软硬折中阈值。它通过一个调节系数把硬阈值和软阈值结合起来既能保持幅值又能让曲线连续。表达式如下对每个小波系数 w当 |w| lambda 时处理结果 sign(w) * (|w| - alpha * lambda)当 |w| lambda 时处理结果 0。当 alpha 取 0 时等价于硬阈值取 1 时等价于软阈值。实际中 alpha 一般取 0.5 到 0.8 之间可以在幅度保持和平滑性之间取得平衡。MATLAB 里没有现成的半软阈值函数但我一般直接写function w_new soft_hard_threshold(w, lambda, alpha) w_new zeros(size(w)); idx abs(w) lambda; w_new(idx) sign(w(idx)) .* (abs(w(idx)) - alpha*lambda); end然后在主循环里替换wthreshC_new(start_idx:end) soft_hard_threshold(C(start_idx:end), lambda, 0.6);用这种方式处理后我发现对冲击型信号的幅度保持能力明显好于纯软阈值同时波形比纯硬阈值更顺滑。5. 帮踩过的坑信号被削尖、振铃和过平滑任何滤波方法都不是万能的。我在做小波降噪的过程中踩过不少坑有些问题在教科书里很少专门提醒但在实际仿真和项目里大概率会遇到。5.1 波形失真与过平滑的常见原因最典型的坑是“去噪后信号变圆了”。波形看起来特别光滑但和原始信号一比尖峰没了幅值也跟着缩水。这种情况十有八九是分解层数太多或者阈值选得太大。比如我用 260 Hz 这个分量模拟的局部波形突变如果分解层数设到 8 层sym8 的支撑长度又长阈值一大重构回去基本就变成一个平滑正弦波了。真实的冲击故障特征被完全抹掉这种去噪是失败的。还有一种情况是阈值处理时把近似系数也一起压了。近似系数代表信号的主要低频能量它不应该被阈值处理。如果你看到重构后的信号整体幅值明显下降先检查一下代码里start_idx有没有写对也就是有没有把低频近似系数误伤。5.2 边界效应与振铃信号的首尾一段区域在做小波分解和重构时经常会出现明显的抖动或震荡这就是边界效应。原因是信号在边界处不满足周期延拓的假设滤波器在边缘卷积时会“够不着”完整的数据出现假成分。分解层数越多边界效应影响的范围越大。处理办法有几个使用wavedec的时候指定边界延拓方式比如周期延拓或者对称延拓在信号处理之前做延拓处理完再裁掉延拓段如果边界处本身没有重要特征直接不评估边界区域。我在实际项目里比较喜欢对称延拓因为对振动信号来说对称延拓比零延拓更符合物理规律。5.3 典型异常排查速查表我整理了一张问题排查表基本都是我自己踩过或者帮同事调参时遇到过的现象可能原因排查和解决去噪后波形过平滑层数太多或阈值过大减小层数改用 rigrsure 规则仍有明显毛刺阈值太小或小波基不合适加大阈值换消失矩更高的小波基两端出现震荡边界延拓方式不对改用对称延拓或处理后再裁掉边界段信号整体幅值下降阈值函数压缩太狠换成半软阈值或减小 alpha局部突变被抹平小波基支撑长度太长换短一些的 db4、sym4重构波形相位偏移小波基不完全对称优先用 sym 或 bior 系列这套速查表的价值在于遇到问题时你有明确的排查方向而不是无脑换参数。6. 从一维到更多扩展图像、小波包和场景建议小波降噪不只能处理一维信号扩展到二维就是图像去噪。原理本质上一样区别在于二维小波分解会得到水平、垂直和对角三个方向的细节子带。工程上做工业图像或者医学影像预处理时这个能力很实用。MATLAB 里二维小波去噪可以直接用ddencmp配合wdencmp2不过我更推荐先跑一遍二维小波分解看看每个子带里的噪声分布再决定阈值策略。另外一个重要扩展方向是小波包。普通小波变换只对低频近似部分继续分解高频部分就不再拆了。小波包变换会把高频部分也继续分解对某些同时包含高频段噪声和低频段噪声的信号来说小波包能更精细地区分它们。代价是计算量变大、参数更多调参难度也更高。如果信号的中高频段同时包含有用信息和噪声而且它们的频带很近我建议直接尝试小波包去噪有时的效果会比小波变换好一个量级。最后说几个我的个人使用建议第一降噪前一定先看清楚信号里到底有什么。先画时域波形再画频谱搞清楚噪声是白噪声、脉冲噪声还是窄带干扰不同噪声类型用的小波策略完全不一样。第二把所有参数都做对比实验时不要只看 SNR 一个指标。SNR 提高不代表波形质量好有时 SNR 很高局部特征却被抹了。要结合 RMSE、相关系数和时域波形一起判断。第三小波降噪不是万能的。如果噪声频带和信号频带重叠得非常严重小波变换也救不回来。这种时候可能需要考虑多通道采集、盲源分离或者深度学习方法。我在实际项目里用过小波变换处理机泵振动信号、用过小波包处理超声检测数据也用过二维小波去噪处理工业相机的表面缺陷图像。这套方法论的通用性很强但每个场景都需要重新调参千万不要指望一个固定参数能打天下。先理解原理再结合信号特征反复试验才能把它的潜力真正发挥出来。
返回列表