news 2026/10/19 3:58:30

基于S变换的电能质量扰动识别:从时频图到复合扰动拆解

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
基于S变换的电能质量扰动识别:从时频图到复合扰动拆解

做了几年波形分析,我最怕的不是信号本身有多复杂,而是拿到一段“看着不对劲、又说不清哪里不对劲”的电压波形。谐波、闪变、暂升这些扰动叠在一起的时候,示波器上就是一坨乱糟糟的曲线,算THD只能告诉你总畸变率,看不出扰动发生在什么时候;FFT能告诉你有哪些频率成分,又完全丢掉时间信息。直到我系统地折腾了一套基于S变换的时频分析方法,才真正把“电能质量扰动识别”这件事从靠感觉变成了可复现的流程:信号进来,S变换出一张时频图,单一扰动有单一定位,复合扰动也能分块拆解。

这篇文章不打算做理论搬运,就围绕S变换对电能质量扰动(谐波、闪变、暂升以及它们组合出的复合扰动)做时频变换识别这条主线,把原理、代码、参数、坑位一次性说清楚。适合正在做电能质量监测、故障录波分析,或者想把手里的波形数据变成分类特征的同行参考。

1. 为什么扰动识别偏偏选中S变换

1.1 谐波、闪变、暂升的时域特征,决定了工具必须“两全”

先说清楚一个问题:电能质量扰动识别,本质上是想从电压(或电流)信号里回答三个问题——有什么扰动、发生在什么时间、强度有多大。

谐波扰动是稳态的,持续存在,特征集中在频域:50Hz基波之外,5次、7次、11次谐波各自在固定频率上有一个峰值。这类信号用FFT看频谱非常清晰,但FFT一旦面对闪变和暂升就露馅了。

闪变本质是工频幅值的低频调幅,调制频率一般在0.05Hz到35Hz之间。它的频谱特征是基频两侧出现一对边带,例如9Hz调制会在50Hz附近出现41Hz和59Hz的旁瓣。光看频谱能发现边带,但如果想知道闪变的持续时间、调制深度变化,FFT完全给不了时间维度。

暂升、暂降这类扰动就更典型了:持续时间往往只有几个周波到几百毫秒,幅值先跳变、维持一段、再恢复。这种信号在频域上能量是散开的,在时域上看幅值跳变倒是清楚,可一旦混入谐波,时域波形又会糊成一片。

换句话说,扰动识别需要的是一个能同时给出“频率在哪、时间在哪”的工具。这决定了短时傅里叶变换、小波变换、S变换三选一的路口。

1.2 三种时频工具的取舍:固定窗、尺度窗和频率自适应窗

短时傅里叶变换(STFT)实现最简单:把信号切成一堆短窗,对每个窗做FFT。但它的窗宽是固定的,选了窄窗,时间分辨率高、频率分辨率低,谐波频率看不准;选了宽窗,频率分开了、时间上又模糊了。闪变和暂升这种“低频慢变+突变”混在一起的情况,固定窗很难两头兼顾。

小波变换用尺度伸缩替代固定窗,高频用窄窗、低频用宽窗,理论上自适应了,但小波输出的尺度与实际频率之间不是线性映射,从时频图里读不出“这个是50Hz基波、那个是250Hz谐波”这种直观信息。做扰动识别的工程师,还是希望坐标轴直接就是频率,否则分类逻辑很难跟物理意义挂钩。

S变换最特别的地方在于它的窗宽随频率倒数变化:低频的时候窗宽、频率分辨率高,正好照顾基波和闪变边带这类低频成分;高频的时候窗窄、时间分辨率高,能定位谐波或暂升突变产生的瞬态成分。而且它是在傅里叶变换框架下构建的,输出坐标天然就是时间和频率,相位信息也保留,不会像小波那样把相位信息弄丢。对谐波、闪变、暂升这类“低频稳、高频瞬”的多模态扰动信号,S变换是三者里最“省心”的。

1.3 一维波形变成二维时频图,识别问题瞬间变成图像问题

S变换把一维时间序列变成二维复数矩阵:横轴是时间,纵轴是频率,每个点的幅值代表该时刻该频率成分的能量强弱。把幅值矩阵画成热力图,就是常说的S变换时频图。

这个变换带来的直接好处是:扰动识别从“波形形态判断”变成“时频图上的特征定位”。谐波是一排水平亮线,闪变是基频线附近的周期性波动带,暂升是一条幅值整体抬升的色块,复合扰动则是这些特征在图上叠加。到了这一步,哪怕不写分类算法,人眼也能在时频图上把扰动成分拆得七七八八。而机器识别更是可以把时频图当二维图像输入,用统计特征或者深度学习模型做分类,这也是我后来把整套流程跑通的核心思路。

2. S变换的原理与扰动在时频图上的“指纹”

2.1 S变换的数学表达与离散实现

S变换的定义容易看懂:

S(τ, f) = ∫ x(t) · w(τ - t) · e^{-i2πft} dt

其中高斯窗w(t)的宽度与频率成反比:

w(t) = (|f| / √(2π)) · e^{-t² · f² / 2}

这个表达式的含义是:对每一个分析频率f,用一个宽度为1/f量级的高斯窗去截取信号,再做傅里叶分析,从而得到该频率下的时间-幅值变化曲线。频率越低,窗越宽,频率分辨率越好;频率越高,窗越窄,时间定位越准。实践中最常用的离散实现方式是借助FFT加快运算:先把信号做FFT得到X(k),对每个频率f,在频域将X(k)与一个平移高斯函数相乘,再做逆FFT,得到该频率对应的时间序列。

下面是我在实际项目里用的一个精简版Python实现:

import numpy as np def s_transform(x, fs, fmin=1.0, fmax=2500.0, nf=256): """ 简化版S变换 x: 输入信号 fs: 采样频率 Hz fmin / fmax: 分析频率范围 nf: 频率轴采样点数 返回 freq_axis, t_axis, st_matrix """ n = len(x) t = np.arange(n) / fs Xf = np.fft.fft(x) freqs = np.fft.fftfreq(n, d=1.0/fs) freq_axis = np.linspace(fmin, fmax, nf) st = np.zeros((nf, n), dtype=complex) for idx, f in enumerate(freq_axis): # 频域高斯窗,宽度与频率f成正比(此处窗在频域表示为关于f的标准差) gaussian = np.exp(-2 * np.pi**2 * (freqs - f)**2 / f**2) st[idx, :] = np.fft.ifft(Xf * gaussian) return freq_axis, t, st

这段代码能跑通,但对于实际工况数据,我建议重点关注两件事:一是频率范围不要从0Hz开始,因为高斯窗在0Hz附近会变成一条极宽的平线,计算意义不大;二是采样长度N和频率点数nf决定了输出矩阵的尺寸,默认256×N在大部分工控机上都没问题。

2.2 单一扰动的时频特征速查

把S变换跑完后,我最常做的事情是先画时频幅值热力图。不同扰动在图上留下的“指纹”差异非常明显,我把它们整理成了一张速查表:

扰动类型时频图特征典型频段时间形态
谐波基频及整数倍频处多条水平亮线50、150、250Hz等持续稳定、无随时间波动
闪变基频两侧的一对边带,强度周期性波动基频±(0.05~35Hz)亮线围绕基频上下振动
暂升整个频带幅值突增的色块全频带,基频最明显突变起点与恢复点有明显分界
暂降与暂升相反,幅值突降的凹陷色块全频带,基频最明显同样有明显起止时刻
暂中断幅值近零的贯穿型缺口全频带持续时间通常较长

这里要特别说明一下:我见过不少初学者只盯着基频那条亮线看,其实谐波的亮线位置是判断扰动类型最直观的线索。如果看到150Hz、250Hz上出现了与基频平行的稳定亮线,基本可以断定有3次和5次谐波;如果这些亮线的颜色深浅随时间周期性变化,就要考虑谐波与闪变同时存在的可能。

2.3 从时频图看谐波与闪变:两条最容易识别的“指纹”

谐波的识别在时频图上几乎是最容易的。一个纯谐波扰动信号做S变换后,基频50Hz处是一条贯穿整个时间轴的亮线,150Hz、250Hz等位置也会出现亮线,幅值大小与谐波含量正相关。如果谐波含量稳定,这些线的颜色整段几乎一致。我经常用这种方式快速核对THD计算结果,两三秒就能确认到底是哪几次谐波偏高。

闪变识别则要看基频亮线的“波动性”。因为闪变是对工频幅值的低频调幅,S变换在基频附近的时频幅值会随时间上下浮动,并且在基频两侧出现对称的边带亮线。比如8.8Hz调制引起的闪变,会在41.2Hz和58.8Hz附近各出现一条细线,这两条线的间距就等于调制频率。看边带比看基频波动更准确,因为基频幅值波动有时会被采样噪声干扰,而边带频率位置很少误判。

3. 实操流程:从原始采样到扰动识别

3.1 数据采集与预处理:决定结果的“隐形参数”

做S变换之前,数据质量不过关的话,后面所有特征都白搭。我先说采样:目前电力行业通用测试规范对电能质量监测的采样率要求,一般建议每周波至少128个采样点,也就是在50Hz工频下采样率至少6400Hz。我自己的项目里习惯用每周波128点的配置,既满足谐波分析到50次谐波的需求,又不会让S变换矩阵过大。

预处理有几个容易忽略但影响很大的细节:

  • 去直流:采样系统有时会引入很小的直流偏置,不去掉的话,S变换在0Hz附近的能量会污染低频段分析,我一般在做FFT前先减去信号均值。
  • 归一化:把波形幅值除以基波幅值,让不同电压等级的监测数据可以横向比较,否则分类模型容易被幅值大小带偏。
  • 找基波频率:电网频率在49.8Hz到50.2Hz之间波动,直接把S变换的基频坐标固定成50Hz会引入误差。我习惯先做一次粗略FFT,锁定实际基波频率,再把这个频率代入S变换的频率轴生成逻辑。

3.2 S变换参数怎么定:频率范围、频率点数和窗宽

参数设置方面,我踩过不少坑,这里给出经过验证的推荐起点:

  • 频率范围:一般从1Hz到2500Hz。低频从1Hz开始是为了覆盖闪变调制频率,高频到2500Hz对应每周波128点采样率下的奈奎斯特频率3200Hz留出余量。如果只关注谐波和暂升,可以把上限降到1000Hz,计算量能小一半。
  • 频率点数nf:默认取256到512。点数太少,频率分辨率不够,谐波亮线可能落在两个频点之间导致幅值被平均;点数太多,比如2048,计算时间和内存会迅速上涨,但识别准确率提升有限。实测下来256个频率点对常见扰动已经够用。
  • 高斯窗的离散化处理:理论中的高斯窗是连续函数,离散实现时要注意频率f不能太接近0,否则高斯窗退化成恒定值,整个S变换失去意义。这也是我为什么把fmin设成1Hz而不是0Hz的原因。

计算量有个粗略的估算方法:S变换的计算复杂度约为O(nf × N logN),N是采样点数。假设记录长度是3秒、采样率6400Hz,N=19200,nf=256,单次S变换耗时在普通笔记本上大约零点几秒到一两秒,完全可接受。如果做在线实时监测,可以缩短记录长度到1秒,或者每秒钟只对最新一个周波做滑动S变换,牺牲少量时间分辨率换取实时性。

3.3 特征提取的三种思路:统计量、突变点、分类器

S变换矩阵拿到手之后,怎么把它变成可用于识别的特征,是整套流程里最体现功底的部分。我常用三种思路,分别适用不同场景。

第一种是纯统计特征:对S变换幅值矩阵按频率带划分(基频带、谐波带、边带),分别计算均值、方差、峰值、能量。例如,基频带的幅值方差能反映闪变调制强弱,谐波带的平均幅值能反映谐波含量。这种特征的优点是解释性强,调试的时候能直接对应到物理量。

第二种是突变点特征:提取基频幅值的时间序列,对它做一阶差分或边缘检测,找到幅值跳变的起点和恢复点。两个跳变点之间的时间跨度既是暂升/暂降的持续时间,两个跳变点的幅值差就是扰动深度。对谐波+暂升这种复合扰动,就分别看基频线的幅值阶跃和谐波线的存在情况,两个特征独立提取再合并。

第三种是图像化特征:直接把S变换幅值矩阵作为二维图像,输入卷积神经网络(CNN)做分类。这个思路的好处是省去了人工设计特征的环节,坏处是数据量要求高、解释性差。我建议在项目初期先用前两种方法把流程跑通、建立“时频图长什么样”的直觉,再考虑上深度学习。

下面是一段提取基频幅值序列和暂升/暂降起点检测的示例代码:

def extract_perturbation_features(st_matrix, freq_axis, fs): # 找基频位置 f0_idx = np.argmin(np.abs(freq_axis - 50.0)) base_trace = np.abs(st_matrix[f0_idx, :]) # 基频幅值的一阶差分,用于检测突变时刻 diff_trace = np.diff(base_trace) jump_idx = np.where(np.abs(diff_trace) > 0.15 * np.mean(base_trace))[0] # 暂升/暂降持续时间 if len(jump_idx) >= 2: duration = (jump_idx[-1] - jump_idx[0]) / fs max_deviation = np.max(base_trace[jump_idx[0]:jump_idx[-1]]) \ - np.min(base_trace[jump_idx[0]:jump_idx[-1]]) else: duration = 0.0 max_deviation = 0.0 return base_trace, duration, max_deviation

配合后面接一层简单的决策规则,就能把暂升、暂降、短时中断这类以幅值突变为主的扰动识别出来。

3.4 单一扰动识别的完整流程示例

拿电压暂升举个例子:一段3秒的电压波形,在0.8秒到2.1秒之间幅值从1.0pu抬升到1.25pu。

第一步,预处理去直流、归一化;第二步,S变换得到256×19200的时频矩阵;第三步,提取基频幅值时间序列,用差分检测到两个跳变点,起点在0.8秒附近,终点在2.1秒附近,持续时间约1.3秒,幅值抬升幅度约0.25pu;第四步,检查谐波带的平均幅值是否同时升高。在这个例子里,谐波带幅值没有同步变化,于是判定为单一暂升扰动。

整个过程不需要人盯着波形看,程序自动输出“扰动类型=暂升、持续时间=1.3秒、深度=25%”这样的结构化结论。实际项目中,把这套逻辑套到成百上千个录波文件上,比肉眼检查快得多。

4. 复合扰动的识别:时频特征是叠加的,不是糊掉的

4.1 复合扰动到底难在哪

复合扰动是工程里最常见的场景:工厂里的非线性负载一起动,既拉低电压(暂降),又往电网里灌谐波;电弧炉运行的时候,既引起电压闪变又产生间谐波。复合扰动识别难,难在特征互相干扰——暂降发生后谐波幅值也变了,闪变的边带跟间谐波频率靠得很近,单一扰动的判断规则组合在一起经常互相矛盾。

我接触过的一个实际案例是某台区设备投切瞬间录到的波形:电压先短暂跌落,随后出现持续约半秒的谐波畸变。单独看FFT,频谱里既有谐波峰又有低频旁瓣,很难确定哪些是暂降带来的瞬态成分、哪些是稳态谐波;单独看时域波形,跌落过程又淹没在谐波纹波里,根本找不准起点。

4.2 复合扰动的时频图破解法

复合扰动的关键破解点,就是把每个扰动映射到不同的时频区域,然后分区域识别。S变换之后,暂降事件在基频幅值时间序列上表现为明显的凹陷,凹陷的起点和终点非常清楚;谐波畸变在150Hz、250Hz亮线上表现为能量增强。这两个特征在时频图上一高一低、互不遮挡,完全可以在同一张图上分别提取。

实际操作时,我会先把时频图按频率分成三个子带:基频带(45~55Hz)、低频带(1~45Hz)、谐波带(100~2500Hz)。基频带用来判断暂升、暂降、暂中断;低频带用来判断闪变;谐波带用来判断谐波成分。每个子带单独提取特征,最后再组合成一个综合判断。这样做的好处是,一个复合扰动哪怕三个子带同时有特征,也不会因为互相干扰而漏判。

4.3 几个容易混淆的典型场景

复合扰动识别里,我至少踩过三个混淆严重的坑,现在总结如下:

  • 闪变与间谐波:两者都能在基频附近产生谱峰,但闪变的边带对称分布在基频两侧,而且边带间隔等于调制频率;间谐波通常只有一个不对称的谱峰。看时频图时,如果只看到单侧谱线,优先怀疑间谐波而不是闪变。
  • 谐波+暂降与暂降后的谐波突变:前者谐波亮线在暂降期间依然存在,只是幅值随基波成比例变化;后者是暂降发生后新增的谐波亮线,两个事件在时间上有先后关系。判断方法是看谐波亮线出现时刻是否与暂降起点完全一致。
  • 暂升伴随短时中断:这两个从名字上看不应该混淆,但在复合扰动里,先暂升后中断(比如备自投动作过程)会让基频幅值序列出现“先升后断”的形态。如果只检测单个幅值阶跃,很容易漏掉后面的中断。我后来改成对整条基频幅值曲线做分段多项式拟合,把每一段的幅值水平和持续时间都提取出来,才彻底解决这个问题。

5. 常见问题与排查实录

5.1 S变换常见问题速查

按我自己的经验,S变换实现和调参的过程里,大多数“结果不对”都集中在下面几个问题上:

现象可能原因解决思路
时频图低频端一片模糊高斯窗在低频过宽,窗内包含多个周期,时间分辨率丧失适当减小低频起始频率,或提高采样率
谐波亮线偏粗、频率轴错位频率点数nf不足,或基波频率未校正增加nf到512,先FFT锁定实际基频
边缘出现大幅值假象信号两端高斯窗不完整产生的边缘效应分析前加窗或边缘截断,只取中间80%区域
计算耗时严重偏高频率点数太多,或记录长度过长限制fmax,缩短窗口长度,使用FFT加速版本
暂升/暂降起止时刻不准差分阈值设置过低/过高根据噪声水平自适应设定阈值,或先平滑基频幅值曲线

5.2 边缘效应:最容易被误解的“假故障”

边缘效应是S变换里几乎一定会遇到的问题。信号的起始和结束位置,高斯窗有一半是悬空的,窗内能量不足,S变换幅值会明显偏低,表现在时频图上就是左右两端各出现一条“暗带”。如果扰动恰好发生在信号尾部,这个暗带会严重干扰判断。

我的处理办法有两个:一是记录长度留足裕量,比如分析2秒窗,实际采集3秒,只取中间2秒做S变换;二是对提取到的幅值序列做首尾裁剪,判决时只用中间80%的数据。这样做以后,因为边缘效应导致的误判率能下降一大半。

5.3 三个项目里踩过的坑

第一个坑:采样率不匹配导致的谐波分析误差。有一段时间我图省事,直接用FFT结果判谐波,发现5次谐波幅值总是不稳定。后来查明白是采样率只有3200Hz,25次以上的谐波混叠进了低频段,把S变换谱线也污染了。现在我的原则是,能用6400Hz采样就不用32000Hz,谐波次数高需求时直接上12800Hz。

第二个坑:把所有扰动都按同一套频率范围做S变换。闪变分析需要精细的低频分辨率,谐波分析需要尽量高的高频上限。我一开始统一设成0到2500Hz,闪变边带在256个频点下分辨率不够,边带频率读数总是偏。后来改成两遍分析:第一遍低频细化(1到100Hz,256点),第二遍高频粗看(100到2500Hz,128点),闪变谐波两头都照顾到。

第三个坑:复合扰动分类时只看时频图特征,没考虑工况背景。同一种“谐波+暂降”的时频图,在电容投切和电机启动两种场景下,物理本质完全不同。如果只做信号处理不做场景联动,识别结果就只是“像什么样”,而不是“是什么”。后来我在特征向量里加入了事件发生前后的功率曲线、电流波形形态,准确率才真正到了能用的程度。

6. 一点个人心得

把整套S变换扰动识别流程搭起来之后,我的体感是:这方法最大的价值不是“更先进”,而是“更直观”。以前给非专业人员解释谐波和闪变的区别,要对着波形和频谱讲半天;现在直接把时频图摆出来,一条条亮线对应哪类扰动,几分钟就能讲明白。识别算法的调试也变得很简单,哪个特征判断错了,就去看对应频率区域时频图上的实际表现,马上能定位问题。

最后再分享一个小技巧:S变换的幅值矩阵不要只看二维热力图,我建议配合三维瀑布图一起看,把幅值作为高度轴,时间和频率作为水平轴。很多在热力图上看不出来的细微特征,比如闪变调制深度的渐变、复合扰动中两个事件的重叠区间,在三维视角下一目了然。这个方法在我排查复合扰动分类错误时帮过不少忙。

如果后续你想把这套流程做成自动识别系统,建议认真考虑在线滑窗S变换加轻量分类器的组合。先在线检测扰动事件发生时刻,再对事件片段做精细S变换和特征提取,计算量能大幅下降,识别可靠性和实时性也可以兼顾。这条路我自己还在持续优化中,之后有新的实践成果再来分享。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/19 5:26:36

Java毕业设计实战:小区停车位管理系统完整方案解析

每到毕业季,被选题卡住的人不在少数。java小区停车位管理系统这个方向,我见过不少同学拿了标题就发慌,其实它是我认为最适合Java方向毕设的题目之一:业务真实、边界清晰、工作量适中,论文、PPT、源代码、演示视频整套交…

作者头像 李华
网站建设 2026/10/19 9:37:35

C++模板方法模式详解:从流程复用到坑点排查

做后端和客户端开发的同行应该都有这种体验:总有一类流程,长得就像“必须按固定顺序走完的关卡”。比如数据导入模块,不管数据源是什么,整体流程永远是“连接/读取 → 解析 → 校验 → 落库 → 清理收尾”,可偏偏每一步…

作者头像 李华
网站建设 2026/10/18 11:36:21

Linux核心目录详解:从根目录到实战排查的完整指南

第一次在服务器上敲下ls /的时候,我盯着满屏的英文缩写愣了好一会儿。etc到底是什么意思?usr是不是 user 的缩写?tmp为什么能放在根目录下?后来在线上环境踩了大大小小的坑,才慢慢明白这套看似凌乱的结构,其…

作者头像 李华
网站建设 2026/10/19 12:50:55

实时分析系统设计实战:从数据采集到查询优化的完整链路

1. 从“rea”这个标题说起:一个被低估的缩写背后藏着什么第一次看到“rea”这个标题的时候,我承认自己愣了几秒。三个字母,没有上下文,没有说明,放在任何一个技术社区里都像是某种暗号。但恰恰是这种极简的命名方式&am…

作者头像 李华
网站建设 2026/10/19 10:40:24

计算机系统四层数据流模型:从物理约束到协同机制

1. 这不是教科书翻页,而是系统级认知重建“计算机组成原理”这门课,对很多人来说,是考研路上一道绕不开的坎,也是技术面试中高频出现的“压力测试题”。但你有没有发现,哪怕把教材从头背到尾,一遇到“为什么…

作者头像 李华
网站建设 2026/10/18 9:08:49

远程控制PS5实战:AnyPS5串流、端口映射与网络优化指南

1. 从"躺在沙发上想玩主机游戏"说起:AnyPS5到底解决了什么事情是这样的。某天我加班到晚上十点,拖着疲惫的身体回到家,突然特别想玩一会刚买的PS5游戏,但人已经躺床上了,实在不想再爬起来走到客厅去开机器。…

作者头像 李华