简介:本资源是一份面向电力系统高年级本科生、研究生及绝缘检测工程师的局部放电(PD)信号小波去噪实践方案,聚焦高压设备绝缘状态评估中的关键信号处理难题。采用Daubechies 5(db5)小波进行5层多尺度分解,结合阈值法实现噪声抑制与特征增强,显著提升微弱放电信号的可辨识度。压缩包共2个文件:12.87MB的PDF论文《基于小波变换的局部放电信号消噪研究》系统阐述原理、算法流程与实验结果;配套MATLAB脚本(.m文件)完整实现小波分解、系数阈值处理与信号重构全过程,便于复现与二次开发。目前已有265人学习下载,读者可直接获取从理论建模、代码实现到结果分析的闭环技术路径,掌握db5小波在非平稳脉冲信号处理中的典型应用范式,为电力设备在线监测与故障预警提供可落地的技术支撑。 在电力设备状态检测这行干的时间长了,你会发现一个很有意思的现象:检测局部放电的仪器可以千差万别,但最终决定你和别人水平差距的,往往不是传感器有多贵,而是信号处理这一步能不能把藏在噪声里的真实放电脉冲捞出来。最近我在整理一个内部项目,代号就叫xiaobo_xiaobo,翻译过来就是“小波小波”。听起来像绕口令,实际上项目主线非常聚焦:用一系列小波变换方法,做局部放电信号的去噪、特征提取,最后把结果喂给后续模式识别环节。这篇博客不打算写那种教科书式的理论综述,而是想把手里的项目细节拆开,说说为什么选小波、怎么选参数、代码怎么写、现场会遇到什么坑,希望给正在做局部放电检测或者同样跟瞬态信号打交道的朋友一点实在的参考。
1. 项目背景:为什么现场检测离不开小波
1.1 局部放电信号的特点
先用一段大白话交代一下信号本身。局部放电指的是绝缘介质里局部区域发生放电但尚未形成贯穿性击穿的现象,通常发生在气隙、绝缘子表面毛刺、电缆半导电层破损这些位置。它的电流脉冲持续时间极短,从几纳秒到几百纳秒不等,经过传输路径和传感器耦合之后,在示波器上看到的典型特征就是一段很短的高频振荡。所以这种信号在数学上被归为瞬态信号或非平稳信号:你不知道脉冲什么时候出现,不一定是周期性的,能量在时间轴上的分布极不均匀。
正因为这种特性,处理局部放电信号的核心矛盾一直是信噪比。现场传感器(高频电流互感器HFCT、特高频UHF天线、超声波传感器)采集到的原始波形里,放电脉冲常常只有毫伏甚至是微伏级别,旁边的背景噪声却可能比它高一个数量级。这就导致无论是做幅值统计、相位统计还是趋势判断,都得先把真正的脉冲从噪声里分离出来,这一步做不好,后面所有分析都是空中楼阁。
1.2 为什么FFT对瞬态信号无能为力
很多人一开始会习惯性地上FFT,觉得频谱分析能区分信号和噪声。这个思路对窄带干扰是有效的,比如某个固定频率的载波干扰,在频谱上是一条谱线,用陷波器就能滤掉。但局部放电面对的主要是宽带白噪声和随机脉冲干扰,频谱上铺得很开,没有明显的分离特征,FFT给出的是一整段时间窗内的平均频谱,脉冲能量被时间平均之后很容易淹没在噪声频谱里,更麻烦的是它完全丢失了时间位置信息。
用一个通俗的类比:FFT像是在黑夜里拍一张长曝光照片,所有亮点都会堆在同一个画面里,你很难判断路灯和流星谁先亮;小波变换则更像一段带慢放的视频,能把某一个瞬间单独拎出来看。局部放电要的就是这个“瞬间”信息——脉冲在工频周期的哪个相位出现、持续多久、高频分量集中在哪里,这些信息对小波变换来说都是顺手的事,对FFT来说则要很费力才能间接得到。
2. 小波变换的精髓:把信号“拆开”到尺度与时间两个维度
2.1 连续小波变换与离散小波变换
小波变换的基本思路并不难理解。它拿一个有限长的波形模板,也就是小波基函数,在时间轴上平移、在频率尺度上缩放,然后不断和原始信号做内积。每做一次内积,翻译成大白话就是:这个小波模板在当前这个时间段、当前这个尺度上和信号像不像。连续小波变换(CWT)的公式写作:
[ W(a,b) = \frac{1}{\sqrt{|a|}} \int x(t) \psi^*\left(\frac{t-b}{a}\right) dt ]
式子里 (a) 是尺度因子,(b) 是平移因子,(\psi) 是小波母函数。(a) 越小,小波被压缩得越厉害,对应高频细节,时间分辨率高;(a) 越大,小波被拉伸,对应低频轮廓,频率分辨率高。CWT在这个二维平面上扫过全部尺度和位置,信息量很大,适合做时频谱可视化,但工程上计算量大、冗余度高,所以实际项目里我更常用离散小波变换(DWT)。DWT并不简单等同于是对CWT做粗暴采样,它一般通过滤波器组来实现,效率高,还能精确重构,后面所有处理都建立在DWT的基础上。
2.2 多分辨率分析与Mallat算法
DWT的理论基础是多分辨率分析。简单说,我们把信号想象成用一个放大镜从粗到细反复观察:首先把信号通过一个低通滤波器得到逼近系数A1(低频慢变成分),同时通过一个高通滤波器得到细节系数D1(高频快变成分),然后各自做二抽一降采样。下一层再把A1继续拆成逼近A2和细节D2。这样每一层拿出来就是不同频带、不同分辨率下的信号表示,而且所有系数加起来没有冗余,可以通过Mallat算法逆过程精确重建原始信号。
这里有一个工程上容易被忽视的点:DWT分解过程是带降采样的,每层系数长度减半,所以它对数据长度有要求,一般希望原始数据长度比较规整,或者至少满足能被当前分解层数的最大降采样倍数整除;如果长度不匹配,重构时会有麻烦。不同软件库对这个问题处理方式不一样,我喜欢在进入分解之前先把信号长度调整到合适的值,比如做一次边界延拓或直接在采集端截取固定点数,免得后面出现长度问题。这也是我在项目里踩过的一个小坑,后面专门讲。
2.3 “xiaobo_xiaobo”项目中的小波基选择
小波基的选择是项目的第一个关键决策点,也是最容易被新手低估的地方。市面上的小波基一抓一大把:Haar、Daubechies(dbN)、Symlets(symN)、Coiflets(coifN)、Meyer、biorthogonal系列。它们之间的区别主要体现在消失矩、对称性、支撑长度、正则性这几个指标上。消失矩决定了小波对光滑信号的压制能力,消失矩越高,对低频平滑成分的抑制越强,越能凸显瞬态突变;支撑长度则影响计算量和时域定位能力,支撑太长会把一个短脉冲在时间轴上来回拖拽。
局部放电脉冲本质是一个快速上升、快速衰减的冲击波形,工程经验上优先选择与脉冲形态相似的小波基。在我这个项目里,我系统对比过db4、db8和sym8三种基函数在去噪后的信噪比改善、脉冲幅值保持率和计算耗时,最后默认选用db4作为主力基函数。db4的消失矩是2,支撑长度8个采样点,对大多数现场PD脉冲来说形态足够接近,去噪后波形畸变小,计算量也小;db8的消失矩更高,对高频细节更敏感,但如果现场存在较强的高频随机干扰,反而容易把噪声也保留下来;sym8和db8性能接近,对称性更好,在处理相位时延方面略占优。如果你刚开始做,建议老老实实先跑一遍不同基函数的去噪结果,把重构波形叠在原信号上看,比看任何指标都直观。
| 小波基 | 消失矩 | 支撑长度 | 对称性 | 在PD去噪中的表现 |
|---|---|---|---|---|
| haar | 1 | 2 | 是 | 波形阶梯化严重,不推荐 |
| db4 | 2 | 8 | 近似 | 综合最优,默认首选 |
| db8 | 4 | 16 | 近似 | 高频细节更好,噪声强时慎用 |
| sym8 | 4 | 16 | 较好 | 与db8相当,相位保持略优 |
3. 核心实操:基于小波阈值的局部放电信号去噪
3.1 实测数据的噪声来源与信噪比问题
讲完理论,进入项目的核心部分:去噪。实测数据里的噪声严格说不止一种,我的经验是先做个噪声成分拆解,再决定处理手段。按照来源可以大致分成四类:第一类是放大器带来的白噪声,频谱平缓,时域上表现为无规律的毛刺;第二类是窄带干扰,比如附近通信载波、谐波,在频域里是一条条谱线;第三类是周期性脉冲干扰,来自可控硅开关、逆变器等设备,频率往往和工频或开关频率挂钩;第四类是随机瞬态干扰,比如现场电焊、雷击感应,波形可能和真实局部放电长得很像。
去噪策略要和噪声类型对应。白噪声用阈值去噪最有效;窄带干扰一般在频域用陷波,或者在小波包分解后把对应子带系数置零;周期性脉冲和随机干扰则需要结合相位信息和脉冲形态做进一步筛选。项目里遇到最头疼的就是白噪声很重、信噪比跌到-10dB左右的现场数据,这时候如果只做一次小波阈值去噪,效果往往一般,需要配合多次分解和子带加权。
3.2 阈值选择(VisuShrink、SureShrink、启发式)
小波阈值去噪的流程不复杂:先做DWT分解得到各层细节系数,再对细节系数做阈值处理,最后重建信号。最关键的就是怎么选阈值、怎么处理超过阈值的系数。选择上主流有三种:VisuShrink通用阈值、SureShrink无偏风险阈值、以及启发式阈值。通用阈值的公式是:
[ T = \sigma \sqrt{2 \ln N} ]
需要注意的是,公式里的 (\sigma) 需要估计,常见做法是取第一层细节系数的中位绝对偏差:(\sigma = \text{median}(|D1|) / 0.6745)。这个估计对噪声异常值比较鲁棒,实测下来比直接算标准差稳。VisuShrink的缺点是当采样点数很多的时候阈值会偏大,容易把真实的小幅值放电脉冲也消掉;SureShrink能根据每一层系数的分布自适应选择阈值,在小脉冲较多时表现更好,但计算量稍大,且对噪声的平稳性有要求。我在现场一般这样处理:先用 (\sigma) 估计出通用阈值,然后乘以一个0.6到0.8之间的系数作为最终阈值。这样做的原因是PD信号往往比预期更微弱,留一点余量能保住小脉冲;如果你只是做趋势分析不介意丢几个小脉冲,可以直接用标准通用阈值。
阈值处理方式还分硬阈值和软阈值。硬阈值是绝对值小于阈值的系数直接清零,大于等于阈值的保留原值,优点是能最大程度保持脉冲幅值和边缘,缺点是重构后可能产生振荡伪影;软阈值是把超过阈值的系数统一做收缩处理,结果更平滑,但脉冲幅值会被系统性削弱。如果后续要做放电量标定和幅值统计,我不建议用纯软阈值,可以在软阈值基础上乘一个经验补偿系数,比如1.2到1.5,把幅值拉回来一点。
3.3 分解层数怎么定
分解层数是另一个需要拍板的参数。分解层数太浅,噪声剥不干净;太深,真实脉冲的能量会被拆散到多个尺度,反而降低每层的信噪比。我的经验法则是:让最深层的高频细节对应的频带刚好覆盖到PD信号的主要频带之上一点点,这样既能保证噪声被大量滤除,又不会把信号本身推散。实际操作中,对采样率100MS/s、分析窗选10ms以内的高频电流信号,我一般默认做4到6层分解;如果现场干扰很强,会试探到7层再看。参考逻辑是:每多一层分解,低频部分频带减半,高层细节主要体现的是低频噪声和工频成分,对PD脉冲贡献不大。
更严谨的方法是观察各层细节系数的幅度。分解到某一层时,如果该层系数的能量跟前几层相比断崖式下降,说明再往下分已经没有有效信息了。这个信号本身的拐点通常就是最佳分解层数。我可以给一个简单有效的检验办法:去掉高频前几层细节系数后重建信号,看PD脉冲的形状和幅值保持得怎么样,如果脉冲陡峭程度明显下降,说明分过了。
3.4 完整的Python实现(pywt)
代码我用Python加上PyWavelets库来演示。如果你用的是MATLAB,思路完全一样,对应函数就是wavedec、wthresh、waverec。先说下环境,pywt目前主推的是2.x版本,API和1.x略有不同,我下面的写法在1.1到1.4以及2.x里都能跑通。
import numpy as np import pywt import matplotlib.pyplot as plt # 采样参数,模拟一个50MS/s下的局部放电脉冲加白噪声 fs = 50e6 t = np.arange(0, 1000) / fs # 20us窗口 # 模拟一个衰减振荡脉冲,出现在第400个采样点附近 pulse = np.exp(-((t - t[400]) * fs / 30.0) ** 2) * np.sin(2 * np.pi * 3e6 * t) x = np.zeros_like(t) x[100:650] = pulse[100:650] # 加入高斯白噪声,信噪比约在5dB上下 noise = np.random.normal(0, 0.12, size=t.shape) sig = x + noise # 小波参数 wavelet = 'db4' level = 4 mode = 'symmetric' # 分解 coeffs = pywt.wavedec(sig, wavelet, level=level, mode=mode) cA4, cD4, cD3, cD2, cD1 = coeffs # 用第一层细节系数估计噪声标准差 sigma = np.median(np.abs(cD1)) / 0.6745 # 通用阈值,乘以0.7保留更多小脉冲 thr = sigma * np.sqrt(2 * np.log(len(sig))) * 0.7 # 软阈值处理所有细节系数,逼近系数不动 coeffs_th = [cA4] for i in range(1, len(coeffs)): coeffs_th.append(pywt.threshold(coeffs[i], thr, mode='soft')) # 重建 sig_den = pywt.waverec(coeffs_th, wavelet, mode=mode) # 简单评估:去噪前后的信噪比 def snr_db(clean, noisy): noise_part = clean - noisy return 10 * np.log10(np.sum(clean**2) / np.sum(noise_part**2)) print("去噪前SNR: %.2f dB" % snr_db(x, sig)) print("去噪后SNR: %.2f dB" % snr_db(x, sig_den)) # 画图对比 plt.figure(figsize=(12, 6)) plt.subplot(2, 1, 1) plt.plot(t*1e6, sig, '0.7', label='raw') plt.plot(t*1e6, x, 'r', label='true pulse') plt.legend() plt.subplot(2, 1, 2) plt.plot(t*1e6, sig_den, 'b', label='denoised') plt.plot(t*1e6, x, 'r', label='true pulse') plt.legend() plt.xlabel('time/us') plt.show()这段代码里的关键点我拆开说。第一,我习惯在第一层细节系数上估计噪声 (\sigma),因为第一层细节对应的频带最宽,最接近高频噪声,而且受工频和窄带干扰的影响相对小。第二,阈值乘以0.7这个系数并不是固定值,而是我在大量现场数据上调出来的经验值,如果你处理的信号噪声很强,可以适当提高;如果你更关心波形保真,可以降到0.5左右。第三,软阈值和硬阈值的选择会直接影响后续的幅值统计,如果你拿不准,可以把两种结果都跑一遍,对比脉冲幅值差异再决定。
另外说一句,pywt.wavedec输出的系数列表顺序是[cA_level, cD_level, cD_level-1, ..., cD1],重构时不要搞反顺序,这是特别容易犯的低级错误。
4. 从去噪到识别:小波包与特征向量的提取
4.1 为什么从DWT升级到WPT
去噪只是第一步,项目更核心的目标是把处理后的信号变成能描述放电类型的特征。传统DWT有个结构性限制:它只对低频逼近部分做逐层分解,高频细节一旦分出来就不再继续细分。这意味着DWT对低频成分有很高的频率分辨率,但对高频成分的频率分辨率始终不够。可局部放电脉冲偏偏就是宽频信号,高频分量里藏着很多关于放电类型的线索,所以我在项目里选择了DWT去噪、WPT(小波包变换)提特征这个组合。
小波包变换在每一层都同时分解低频和高频,所以经过3层分解后就得到8个等带宽的频带节点,经过4层就是16个节点。每个节点对应一段明确的频带,这样PD信号的频域信息被切得很细,不同放电类型的细微差异更容易显现。代价是计算量和特征维度同步上升,所以并不是分解越深越好,一般3到4层足够。
4.2 小波包能量特征计算方法
特征提取我用的方法是:对去噪后的信号做4层小波包分解,计算出每个叶节点的系数能量,再做归一化,得到一个16维特征向量。为什么用能量作为特征而不是直接用系数?因为放电的强度通常不是绝对稳定的,而能量谱的形状能相对稳定地反映脉冲频率结构,对幅值变化不敏感,更利于做类型识别。
def wp_energy(sig, wavelet='db4', level=4): wp = pywt.WaveletPacket(data=sig, wavelet=wavelet, mode='symmetric', maxlevel=level) nodes = wp.get_level(level, order='freq') # 按频率顺序取节点 energy = [] for node in nodes: coef = node.data energy.append(np.sum(np.abs(coef) ** 2)) energy = np.array(energy) total = np.sum(energy) if total == 0: return energy return energy / total使用的时候要注意,get_level(order='freq')里面的order参数按频率排序,不是按节点自然序号,很多教程没用这个参数,导致后面特征维度的顺序是乱的。另外,节点数据的长度会随着分解层数增加而指数缩小,如果原始信号太短,最后一层节点可能只有少数几个系数,此时能量估计的方差会变大,建议原始数据长度不低于 (2^{level} \times 16),也就是说4层分解最少要256个点起步,实际现场信号一般远超这个数。
拿到特征向量之后,我会再加上统计特征做补充,比如脉冲的等效时间、等效频宽、偏斜度、峰度,这些特征在区分不同放电类型时跟小波包能量有互补作用。特征向量就可以输入SVM或随机森林做分类。
4.3 不同放电类型的特征差异
不同放电类型在小波包特征上的差异,我举几个典型例子。电晕放电通常发生在导体尖端,信号时域上呈现单极性脉冲串,重复频率高,主要在工频的负半周(也看电极极性),能量集中在中高频段;内部气隙放电在正负半周都比较对称,相位区间相对固定,能量在低频和高频都有分布;沿面放电和悬浮电位放电相位区间更宽,能量谱会更发散。这些规律不是绝对的,但作为经验判断很有价值,尤其是配合PRPD图谱一起看。
| 放电类型 | 相位区间特征 | 小波包能量分布特点 |
|---|---|---|
| 电晕放电 | 通常在负半周或正半周窄区间 | 中高频集中,低频较弱 |
| 内部气隙放电 | 正负半周对称,相位窄 | 中低频为主,高频较明显 |
| 沿面放电 | 相位区间较宽 | 能量分散,低频和高频都有 |
| 悬浮电位放电 | 相位宽且不稳定 | 谐波特征明显,能量跳跃 |
5. 实战中的坑与排查技巧
5.1 边界效应对分解结果的影响
小波分解和重构都涉及卷积,而卷积在信号两端天然会出现边界问题。如果不做处理,重构信号在开头和结尾会有一小段畸变。处理办法有几种:最省事的是在pywt.wavedec里指定mode参数,比如'symmetric'把信号镜像延拓,'periodic'则按周期延拓;更稳的办法是在进入分解之前对原始信号两端各加一段保护带,处理完再把保护带裁掉。这个方法在遇到现场数据开头或结尾正好有脉冲时特别好用,不然你很容易把边界畸变当成真实放电,造成误判。
我在项目里是通过采集配置解决的:每次分析窗取2个工频周期的数据,但实际截取2.1个周期,留出的0.1个周期当保护带,去噪后再丢弃。这个思路在离线数据和在线监测程序里都能用,成本几乎为零,强烈建议加上。
5.2 小波基选错的典型表现
小波基选错的表现不是程序报错,而是结果静悄悄出错。我可以给几个典型的病征:用Haar处理光滑沿的脉冲,重构波形会阶梯化;用支撑很长的db20处理极窄脉冲,会在脉冲前后产生拖尾,看着像有两个峰,影响脉冲相位和幅值计算;用过于光滑的小波基处理高频毛刺多的放电,会把它误当成噪声滤掉。所以做小波基选择时千万不要只看重构误差,要结合波形形态、时延、幅值三个指标一起看。
教你一个排查技巧:在项目里准备一组标定的仿真信号,用已知的脉冲位置和幅值去测不同小波基,快速批量跑一遍,统计脉冲起始时刻误差和幅值误差,排在前面的候选基才有资格进入现场数据测试。我在项目里就是用这个办法很快锁定了db4。
5.3 阈值过高/过低的表现与调整
阈值过高和过低在结果上表现完全不同。阈值过高时,噪声虽然没了,但真实的PD脉冲也会被削减,特别是小幅值放电直接消失,去噪后的波形看起来“干净”但空得过分,时序趋势会漏报;阈值过低时,波形里还能看到明显噪声,相位图谱上会多出一大片随机散布的点,这时候你可能以为发现了什么新缺陷,实际只是噪声没滤干净。所以判断去噪效果不能只看波形平不平,一定要结合原始信号里的脉冲特征来看。
我常用的调参方法是:对同一组数据,把阈值从0.2倍通用阈值到1.5倍通用阈值每隔0.1跑一遍,画出去噪后脉冲幅值保持率和噪声残留率随阈值变化的曲线,在两条曲线交叉点附近选阈值。这个方法比凭感觉试参数快得多,也更容易跟现场同事解释为什么定这个数。
5.4 去噪前后相位分辨PRPD谱图对比
最后聊PRPD图,这是局部放电分析里绕不开的图表。横轴是工频相位0到360度,纵轴是放电幅值或放电量,颜色深浅表示该相位和幅值处出现的次数。去噪前的PRPD图,因为噪声没有相位规律,整个图会被噪声层铺满,原本隐藏在里面的放电簇根本看不出来;去噪后的PRPD图,脉冲被留下来,噪声层的底色变浅,才能真正看出放电集中在哪个相位,比如典型的内部气隙放电会在0到90度和180到270度两个象限形成对称的簇,而电晕放电往往只在其中一个半周出现。
我在项目交付时给客户的报告里,会把去噪前和去噪后的PRPD图放在同一页,并标注相位区间、幅值稳定性和重复性。这个呈现方式有个额外的好处:它能帮现场工程师判断去噪参数是不是合理,如果去噪后的PRPD图丢失了原有相位结构,或者出现了本来没有的密集区域,那就是处理参数调过头了。我还建议在去噪后对脉冲做一次相位一致性校验:所有脉冲的相位分布应当符合局部放电的工频相关特性,如果出现大量随机相位脉冲,就要回头检查是不是有周期性脉冲干扰混进来了。
最后说几句个人体会。xiaobo_xiaobo这个项目做下来,我最大的感触是小波处理调参的功夫其实都在信号理解上,小波基、阈值、分解层数没有一套通行参数能覆盖所有现场,换一个变电站、换一种干扰源,可能都要微调。好在办法是通用的:先把原始信号看明白,再做参数验证,最后用PRPD做闭环判断,一套流程走下来基本不会出大差错。如果你正在学小波或手头有局部放电数据要处理,我建议先别急着追最新模型,把db4、通用阈值、4层分解这套组合跑熟,再逐步根据效果调整。还有一个实在的小技巧:调参的时候把去噪后波形和原始波形叠在同一张图里,脉冲极性、相位一旦对不上,赶紧停手检查参数,这时候基本就是某一步处理出问题了。
本文还有配套的精品资源,点击获取