基于MATLAB小波变换的信号突变点检测
之前在不经意间也有接触过求突变点的问题。在我看来,与其说是求突变点,不如说是我们常常玩的"找不同"。给你两幅图像,让你找出两个图像中不同的地方,我认为这其实也是找突变点在生活中的应用之一吧。回到找突变点位置上,以前自己有过一个傻傻的方法:就是直接求前后两个采样的的差分值,最后设置一个阈值,如果差分值大于这个阈值则该点是突变点。但这个方法问题很大,实际中突变点幅值有大有小,你怎么能确定阈值到底是多少呢?还有可能信号本来的差分值就比你那突变点的差分值还要大。所以这种方法在信号或噪声稍微复杂一点就行不通了。
这几天看到了一种船新的信号突变点检测的方法-基于小波变换的信号突变点检测。于是乎去学习了一下小波变换的相关知识和应用,学习的不是很深入,但也模模糊糊感觉到了小波变换确实是检测突变点的一大利器,下面分为两个大部分总结一下我所学习到的小波变换求突变点的实现过程和相关知识理论。
一:小波变换求信号突变点实现
我喜欢直接从应用入手,或者应用结合理论。一步一步分析代码,看数据和图像的变化比一步一步推公式有趣的多(虽然可能是错误的呀)。于是在这里我就先直接上代码和图像了,这样先让我们对整个过程有个感性的认识。
1.1 原始信号的生成
首先生成原始信号,这里随便什么信号都可以,那我就生成一个正弦信号吧,具体信号参数见代码注释。
clear all; close all; clc;
Fs = 1000; % 采样频率1000Hz
Ts = 1 / Fs; % 采样时间间隔1ms
L = 1000; % 采样点数1000
t = (0 : L - 1) * Ts; % 采样时间。1000个点,每个点1ms,相当于采集了1s
x = sin(2 * pi * 10 * t); % 原始正弦信号,频率为10Hz,振幅为1

1.2 添加突变点
第二步我们要人为添加突变点了,为了看起来直观就暂时不添加噪声了。此处我们添加两个突变点,将第233个点的幅度在原本基础上增加0.5,将第666个点的幅度在原本基础上增加0.1,代码和添加后信号图像如下:
x(233) = x(233) + 0.5;
x(666) = x(666) + 0.1;

可以看到一个突变点很明显,而另一个却不是那么的明显,可能肉眼看的话都会忽略掉这个突变点。
1.3 对信号做傅里叶变换
可能有人要问,既然我们做的是小波变换,为什么又要对信号做傅里叶变换呢?其实我们确实可以不用做傅里叶变换的,但是为了与小波变换做对比,分析各自的优势和劣势,我们还是看一下该突变信号的傅里叶变换。
Y = fft(x,1024);
f = Fs * (0 : (L / 2)) / L;
P2 = abs(Y / L);
P1 = P2(1 : L / 2 + 1);
plot(f,P1)

1.3.1 补充
下面我们再给一个原始信号的fft幅度谱。从肉眼来看,我们可以发现原始信号和添加突变信号的频域差别不大,只是突变信号的频谱在高频部分多了些抖动。所以要从傅里叶变换的频域来检测突变信号是不合适的。具体原因在第二部分会有总结,主要是两个变换选取“基”的不同而导致的。

1.4 对信号做小波变换
重头戏小波变换来了,这里我们用两种小波变换的方法检测突变点,一是连续小波变换;二是离散小波变换,这里只会简略说明一下图像,可以结合第二部分原理一起查看。
1.4.1 连续小波变换
我们对突变信号进行连续小波变换,实现代码和图像如下:
cw1 = cwt(x,1:32,'sym2','plot'); % 对信号做连续小波变换
title('连续小波变换');
cwt(Continuous wavelet transform)函数表示进行连续小波变换,主要是处理一维的数据,比如我们这个数据。参数x是输入的信号;1:32表示尺度参数Scales的取值范围为(1:32);'sym2’表示我们用的小波是sym2小波;'plot’是画出连续小波变换系数的意思。运行图像如下:

不同于傅里叶变换只有w一个自变量,小波变换有两个自变量,分别是a(尺度参数)和b(位移参数)。从上图我们可以看出在小波位移到第233个点和第666个点,且a较小时,可以看到一条较亮的白条,可以暂且理解成小波在这个位移和尺度上与信号相关性较大。在某个位置出现小波与信号相关性激增的原因就是信号在这个位置出现了突变,于是我们就愉快的找到了两个突变点的位置。
1.4.2 离散小波变换
由于连续小波变换的位移参数(b)和尺度参数(a)都是连续变化的,特别是尺度参数的连续变化,会带来巨大的计算量,于是利用离散小波变换来处理信号,一种方法是我们可以直接取离散的a和b的值,然后计算得到其系数图,从不同的尺度观察信号的特征,例外一种更常用的离散小波变换方法叫做Wallat算法,是通过构造一个低通滤波器和一个高通滤波器不断对信号进行滤波,从而得到信号不同频率的细节的方法。这里还是主要说代码和图像,具体实现原理在第二部分有粗浅介绍。
wavedec(x,3,‘db4’)函数表示进行离散小波多层分解,x是待处理的输入信号;3表示进行3层分解,'db4’是一个小波的名字。处理完毕后得到1、2、3层的细节系数(details)d1、d2、d3和第3层的近似系数(Approximations)a3。本段代码和分解后的图像如下:
[d,a]=wavedec(x,3,'db4'); %对原始信号进行3层离散小波分解
a3=wrcoef('a',d,a,'db4',3); %重构第3层近似系数
d3=wrcoef('d',d,a,'db4',3); %重构第3层细节系数
d2=wrcoef('d',d,a,'db4',2); %重构第2层细节系数
d1=wrcoef('d',d,a,'db4',1); %重构第1层细节系数

我们还可以用另一个函数dwt()来手动进行一层一层的分解,不过注意分解过后每一层的分解信号长度会少一半,因为进行了下采样。具体原因可见第二部分的介绍,手动分解的代码和分解图像入下:
[ca11,cd1] = dwt(x,'db4'); % 第1层分解
[ca22,cd2] = dwt(ca11,'db4'); % 第2层分解
[ca3,cd3] = dwt(ca22,'db4'); % 第3层分解

由上图可明显看出,除去开头和结尾的一些比较大的点外,在第1、2、3层的细节信号中,最大值点恰恰是第233点和第666点,于是也可以愉快的可以确定这两个点即是突变信号的位置了。
这里还可以稍微注意一下近似信号a3,它类似于原始信号滤去了高频成分的样子,它是怎么得来的你看了第二部分就知道了!
1.5 总结
在这一部分中我们直抓要害,知道了怎么通过小波变换来检测信号的突变点,MATLAB的函数用起来就是爽有木有。但是能应用是一回事,我们还是尽量多了解一下小波变换的原理为好。小波是怎么构造的,它的性质有什么?连续小波变换的图像是怎么计算出来的呢?离散小波变换的每一层又是怎么算出来的呢?只有学习了它们背后的支撑运算的数学公式,我们才能算真正理解了它。
二:小波变换的基础知识
关于基础知识这一部分,主要都是参考的[2]里面的内容,我只是提炼了一些我认为重要的内容写出来,然后有自己小小的补充。
2.1 连续小波变换(CWT)
首先直接给出连续小波变换公式:
C ( a , b ) = 1 a ∫ R f ( t ) ψ ∗ ( t − b a ) d t C(a,b) = \frac{1}{\sqrt{a}} \int_R f(t) \psi^*(\frac{t-b}{a})dt C(a,b)=a1∫Rf(t)ψ∗(at−b)dt
连续小波变换的结果就是得到很多个小波系数 C ( a , b ) C(a,b) C(a,b),它有两个自变量参数,分别是尺度参数a和位移参数b。注意在CWT中a和b都是连续变化的。
2.1.1 尺度参数与位移参数
尺度变换:
如何对小波进行尺度变换呢?其实就是简单的拉伸或者压缩,下图表现为一个小波在不同的尺度参数下的变换,可以看到尺度参数a越小,小波越压缩,频率越高;尺度参数a越大,小波越拉伸,频率越低。

位移变换:
位移变换意味着将小波延迟或提前,如下图将小波 ψ ( t ) \psi(t) ψ(t)往右移位长度k得到 ψ ( t − k ) \psi(t-k) ψ(t−k)。

2.1.2 连续小波变换具体过程
连续小波变换其实就是把小波从小尺度拉伸到大尺度,然后把不同尺度的小波依次从0位移到信号的完整长度,并不断地计算它们的积分的过程。详细来说就是下面几个步骤:
- 将小波 ψ ( t ) \psi(t) ψ(t)放到原始信号 f ( t ) f(t) f(t)的开头处进行比较。
- 计算小波系数C,C其实也表示了小波与信号这一部分的相关程度。C越大,说明相似度越高。

- 将小波向右平移,距离为b,小波函数变为 ψ ( t − b ) \psi(t-b) ψ(t−b)。并且重复步骤1和2,直到小波位移完整个信号 f ( t ) f(t) f(t)。

- 扩展小波的尺度,比如扩展一倍,小波函数变为 ψ ( t 2 ) \psi(\frac{t}{2}) ψ(2t)。然后重复步骤1~3。

- 重复步骤1~4直到小波已经拓展到规定的最大尺度。
进行完这五个步骤之后,我们就能够得到在不同的小波尺度和不同的信号位置上的小波系数了。如何更直观的理解这个系数呢?于是我们可以把 C ( a , b ) C(a,b) C(a,b)画出来,x轴代表信号的时间(或说小波位移的长度b);y轴表示尺度a;图中每个点的颜色浅深表示C(a,b)的大小。下面是一个系数图,其实在第一部分中也有我自己信号的CWT系数图,忘了的可以回去看一下。

当然也可以看系数图的侧面视角,图像如下:

回到文章主题,检测信号突变点上。如果信号存在突变点的话,总有一些小尺度的小波在经过突变点这个位置的时候,此时计算出的 C ( a , b ) C(a,b) C(a,b)会比周围的点都大。从系数图中我们可以想到这些位置会更亮一些,于是就找到了突变点。
2.2 离散小波变换(DWT)
f ( t ) f(t) f(t)的二进制连续小波变换为:
C ( 2 j , b ) = 1 2 j ∫ R f ( t ) ψ ∗ ( t − b 2 j ) d t (1) C(2^j,b) = \frac{1}{\sqrt{2^j}} \int_R f(t) \psi^*(\frac{t-b}{2^j})dt \tag{1} C(2j,b)=2j1∫Rf(t)ψ∗(2jt−b)dt(1)
当 b = k 2 j b=k2^j b=k2j,式(1)为离散小波变换;当 b = k b=k b=k,式(1)为平稳小波变换(二进小波变换)。
平稳小波变换只对尺度参数进行了离散化,而对时间域上的平移参数保持整数连续变化,平稳小波变换未破坏信号在时间域上的平移不变量。
DWT有多种实现方式,除了按照上述公式做的离散小波变换,其实还有一种更为常用的离散小波变换的方法,叫做Mallat算法,其实我们在第一部分将信号分成3层近似系数和细节系数就是用的这种方法。
2.2.1 半子带滤波
对于大多数信号来说,信号的低频部分是对信号整体特征的刻画;而高频部分则表现了信号的细枝末节。比如我们的声音,如果把声音的高频部分去去掉,虽然听起来有点不一样,但我们仍然能够听得出说的什么内容,但如果把足够多的低频分量去掉,那就完全不知道在说什么了。
在小波分析中,我们把信号的低频部分称之为近似系数A(Approximations),把信号的高频部分称作细节系数D(Details),于是我们可以通过一个半子带滤波器来得到A和D。

原始信号S,通过两个互补的滤波器,生成两个信号A和D。
值得注意的一点是,假设原始实数字信号S有1000个采样点的长度,那么经过滤波后,A和D分别都会有1000个点,它们加在一起有2000个点,就比S还长了。由于之后重构S的需要,现在我们使用下采样的方法将A和D各自降成500个点,方法是每两个点取一个点就好了。下采样之后的信号分别是cA1和cD1。

2.2.2 离散小波分解
在得到近似系数cA1之后,对cA1也进行半子带滤波加下采样,得到cA2和cD2,重复这个操作,可以最多进行 l o g 2 N log_2{N} log2N层小波分解。

三:源码下载链接
相关文章:

基于MATLAB小波变换的信号突变点检测
之前在不经意间也有接触过求突变点的问题。在我看来,与其说是求突变点,不如说是我们常常玩的"找不同"。给你两幅图像,让你找出两个图像中不同的地方,我认为这其实也是找突变点在生活中的应用之一吧。回到找突变点位置上…...

JUC并发编程(JUC核心类、TimeUnit类、原子操作类、CASAQS)附带相关面试题
目录 1.JUC并发编程的核心类 2.TimeUnit(时间单元) 3.原子操作类 4.CAS 、AQS机制 1.JUC并发编程的核心类 虽然java中的多线程有效的提升了程序的效率,但是也引发了一系列可能发生的问题,比如死锁,公平性、资源管理…...

个人用C#编写的壁纸管理器 - 开源研究系列文章
今天介绍一下笔者自己用C#开发的一个小工具软件:壁纸管理器。 开发这个小工具的初衷是因为Windows操作系统提供的功能个人不满意,而且现在闲着,所以就随意写了个代码。如果对读者有借鉴参考作用就更好了,能够直接代码段复用即可。…...
iTextSharp 生成PDF
示例代码定义了一个名为PdfController的API控制器,其中的GeneratePdf方法创建了一个新的PDF文档,并将内容添加到文档中。最后,将文档内容转换为字节数组,并通过File方法返回给前端。 注意,你需要在你的项目中添加对iT…...

基于微信小程序的传染病酒店隔离平台设计与实现(Java+spring boot+MySQL+微信小程序)
获取源码或者论文请私信博主 演示视频: 基于微信小程序的传染病酒店隔离平台设计与实现(Javaspring bootMySQL微信小程序) 使用技术: 前端:html css javascript jQuery ajax thymeleaf 微信小程序 后端:…...

vue3中用watch监听响应式数据的注意点
如果你在vue3中使用reactive()方法创建响应式数据,然后又用torefs()方法将响应式数据解构成单一的ref响应式数据。 此时,如果你想用watch监听解构出来单一的响应式数据,watch不起作用。 此时,你需要用watch监听之前的reactive()…...

Jmeter(五) - 从入门到精通 - 创建网络计划实战和创建高级Web测试计划(详解教程)
1.简介 上一篇中已经将其的理论知识介绍了一下,这一篇就带着大家一步一步的把上一篇介绍的理论知识实践一下,然后再说一下如何创建高级web测试计划。 2.网络计划实战 通过上一篇的学习,将其分类为: (1)不需…...

【单片机】51单片机,TLC2543,驱动程序,读取adc
TLC2543 是一款 12 位精密模数转换器 (ADC)。 1~9、11、12——AIN0~AIN10为模拟输入端; 15——CS 为片选端; 17——DIN 为串行数据输入端;(控制字输入端,用于选择转换及输出数据格式) 16——…...
誉天HCIE-Cloud_Computing3.0课程简介
课时:60 第一天 1. 华为云 Stack 解决方案及架构介绍 3. 华为云 Stack 的安装流程解析及规划设计 4. 华为云 Stack 的网络平面的规划解析 5. 华为云 Stack Deploy 部署工具的安装,配置,创建工程,下载 LLD 表 6. 华为云 Stack 的 …...

Unity之ShaderGraph 节点介绍 Procedural节点
程序化 噪声Gradient Noise(渐变或柏林噪声)Simple Noise(简单噪声)Voronoi(Voronoi 噪声) 形状Ellipse(椭圆形)Polygon(正多边形)Rectangle(矩形…...

期权定价模型系列【1】—BSM通用式模型
这是期权定价模型专栏的第一篇文章,此专栏旨在分享一些期权定价模型,将会从最基础的BSM模型开始写起,逐步扩散到蒙特卡洛模拟、二叉树等数值法模型,以及跳跃扩散模型、随机波动率模型,神经网络模型等等。 如果你觉得有…...

HA3 SQL样本实验:一种混合计算查询的全新样本解决方案
作者:陆唯一(芜霜) HA3(对外开源代号:Havenask )是阿里智能引擎团队自研的大规模分布式检索系统,广泛应用于阿里内部的搜索业务,是十多年来阿里在电商领域积累下来的核心竞争力产品。Ha3 SQL 是在原有Ha3引…...
Linux(Web与html)
域名 DNS与域名: 网络是基于tcp/ip协议进行通信和连接的 tcp/ip协议是五层协议:应用层–传输层—网络层----数据链路层----物理层每一台主机都有一个唯一的地址标识(固定的ip地址,用于区分用户和计算机。 ip地址:由…...

SpringBoot 底层机制分析[上]
文章目录 分析SpringBoot 底层机制【Tomcat 启动分析Spring 容器初始化Tomcat 如何关联Spring 容器】[上]搭建SpringBoot 底层机制开发环境Configuration Bean 会发生什么,并分析机制提出问题:SpringBoot 是怎么启动Tomcat ,并可以支持访问C…...

电源控制--对数与db分贝
在控制理论中,"db"通常表示分贝(decibel)的缩写。分贝是一种用于度量信号强度、增益或衰减的单位。 在控制系统中,分贝常用于描述信号的增益或衰减。通常,增益以正数的分贝值表示,而衰减以负数的…...
LeetCode 1749. 任意子数组和的绝对值的最大值(前缀和)
题目: 链接:LeetCode 1749. 任意子数组和的绝对值的最大值 难度:中等 给你一个整数数组 nums 。一个子数组 [numsl, numsl1, …, numsr-1, numsr] 的 和的绝对值 为 abs(numsl numsl1 … numsr-1 numsr) 。 请你找出 nums 中 和的绝对…...

python爬虫相关
目录 初识爬虫 爬虫分类 网络爬虫原理 爬虫基本工作流程 搜索引擎获取新网站的url robots.txt HTHP协议 Resquests模块 前言: 安装 普通请求 会话请求 response的常用方法 简单案例 aiohttp模块 使用前安装模块 具体案例 数据解析 re解析 bs4…...

PAT(Advanced Level) Practice(with python)——1023 Have Fun with Numbers
Code N int(input()) D_N 2*N # print(Yes)if len(str(D_N))>len(str(N)):print(No) else:for s in str(D_N):if s not in str(N) or str(D_N).count(s)!str(N).count(s):print("No")breakelse:print(Yes) print(D_N)...

springboot vue 初步集成onlyoffice
文章目录 前言一、vue ts1. 安装依赖2. onlyoffice组件实现(待优化)3. 使用组件4. 我的配置文件 二、springboot 回调代码1. 本地存储 三、效果展示踩坑总结问题1问题2 前言 对接onlyoffice,实现文档的预览和在线编辑功能。 一、vue ts …...

Win10语言设置 - 显示语言和应用语言
前言 Win10的语言设置可以设置显示语言和应用语言。其中,显示语言用于显示系统文字;应用语言用于应用程序显示文字。下文介绍如何设置。 显示语言 打开系统设置,选择时间和语言,如下图: 修改Windows显示语言即可更…...
KubeSphere 容器平台高可用:环境搭建与可视化操作指南
Linux_k8s篇 欢迎来到Linux的世界,看笔记好好学多敲多打,每个人都是大神! 题目:KubeSphere 容器平台高可用:环境搭建与可视化操作指南 版本号: 1.0,0 作者: 老王要学习 日期: 2025.06.05 适用环境: Ubuntu22 文档说…...
Python爬虫实战:研究MechanicalSoup库相关技术
一、MechanicalSoup 库概述 1.1 库简介 MechanicalSoup 是一个 Python 库,专为自动化交互网站而设计。它结合了 requests 的 HTTP 请求能力和 BeautifulSoup 的 HTML 解析能力,提供了直观的 API,让我们可以像人类用户一样浏览网页、填写表单和提交请求。 1.2 主要功能特点…...

JavaSec-RCE
简介 RCE(Remote Code Execution),可以分为:命令注入(Command Injection)、代码注入(Code Injection) 代码注入 1.漏洞场景:Groovy代码注入 Groovy是一种基于JVM的动态语言,语法简洁,支持闭包、动态类型和Java互操作性,…...
在鸿蒙HarmonyOS 5中实现抖音风格的点赞功能
下面我将详细介绍如何使用HarmonyOS SDK在HarmonyOS 5中实现类似抖音的点赞功能,包括动画效果、数据同步和交互优化。 1. 基础点赞功能实现 1.1 创建数据模型 // VideoModel.ets export class VideoModel {id: string "";title: string ""…...
在四层代理中还原真实客户端ngx_stream_realip_module
一、模块原理与价值 PROXY Protocol 回溯 第三方负载均衡(如 HAProxy、AWS NLB、阿里 SLB)发起上游连接时,将真实客户端 IP/Port 写入 PROXY Protocol v1/v2 头。Stream 层接收到头部后,ngx_stream_realip_module 从中提取原始信息…...
OkHttp 中实现断点续传 demo
在 OkHttp 中实现断点续传主要通过以下步骤完成,核心是利用 HTTP 协议的 Range 请求头指定下载范围: 实现原理 Range 请求头:向服务器请求文件的特定字节范围(如 Range: bytes1024-) 本地文件记录:保存已…...

网络编程(UDP编程)
思维导图 UDP基础编程(单播) 1.流程图 服务器:短信的接收方 创建套接字 (socket)-----------------------------------------》有手机指定网络信息-----------------------------------------------》有号码绑定套接字 (bind)--------------…...

分布式增量爬虫实现方案
之前我们在讨论的是分布式爬虫如何实现增量爬取。增量爬虫的目标是只爬取新产生或发生变化的页面,避免重复抓取,以节省资源和时间。 在分布式环境下,增量爬虫的实现需要考虑多个爬虫节点之间的协调和去重。 另一种思路:将增量判…...
在QWebEngineView上实现鼠标、触摸等事件捕获的解决方案
这个问题我看其他博主也写了,要么要会员、要么写的乱七八糟。这里我整理一下,把问题说清楚并且给出代码,拿去用就行,照着葫芦画瓢。 问题 在继承QWebEngineView后,重写mousePressEvent或event函数无法捕获鼠标按下事…...
uniapp 实现腾讯云IM群文件上传下载功能
UniApp 集成腾讯云IM实现群文件上传下载功能全攻略 一、功能背景与技术选型 在团队协作场景中,群文件共享是核心需求之一。本文将介绍如何基于腾讯云IMCOS,在uniapp中实现: 群内文件上传/下载文件元数据管理下载进度追踪跨平台文件预览 二…...