matlab时频分析之连续小波变换cwt

2023-11-07


(2020年7月更新,第3节绘制了一个实部、虚部的关系图)

1 小波分析简介

和傅里叶变换比,小波变换和短时傅里叶变换都有着相同的优点,就是可以同时在时域和频域观察信号。所以小波变换非定常信号的分析中有很大的作用。

有关短时傅里叶变换的文章,可以参见我之前写的:
matlab时频分析之短时傅里叶变换 spectrogram
https://blog.csdn.net/weixin_42943114/article/details/88735799

和短时傅里叶变换相比,小波变换有着窗口自适应的特点,即高频信号分辨率高(但是频率分辨率差),低频信号频率分辨率高(但是时间分辨率差),而在工程中常常比较关心低频的频率,关心高频出现的时间,所以近些年用途比较广泛。

在数学上,小波还有正交化等优点,应用领域广泛。
但是,本文只讨论如何利用matlab实现cwt的时频分析

2 小波分析基本原理

小波的含义,即为时间上衰减快,和傅里叶的正弦波相比要短。
一个典型的morlet小波如下图:
在这里插入图片描述
matlab有很多自带的小波函数,利用wavemngr(‘read’,1)可以进行小波的查看,利用waveinfo可以查看小波的相关信息。

在时间域上,可以通过小波在时间上的移动,逐一比较不同位置的窗口信号,得到小波系数,小波系数越大,则证明小波与该段信号的拟合程度越好。计算中用小波函数与该窗口信号的卷积,作为该窗口下的小波系数。窗口的长度和小波的长度是相同的。
在这里插入图片描述
在频率域上,通过拉伸或压缩小波的长度,来改变小波的长短和频率,实现不同频率下的小波系数。相应的,窗口长度也会随着小波长度变化。由于高频处小波被压缩,时间窗变窄,使得时间分辨率更高。

将不同频率下的小波系数组合起来,便得到了时频变换的小波系数图。
在这里插入图片描述
从图上可以看到,低频处频率分辨率要好于高频处的。小波时频图的特点为整体呈现高频处高而瘦,低频处矮而宽。

小波中,一般用尺度scale来衡量小波的频率f,两者之间的转换关系为:
s c a l e ∗ f = F s ∗ w c f scale * f=Fs * wcf scalef=Fswcf
公式中,Fs代表信号的采样频率,wcf为小波的中心频率(wave central freq),在matlab里可以用 centfrq(wavename) 来查询。

3 cwt的matlab实现

matlab自带的有两种实现方式,一种是2006年版本推出的函数cwt,一种是2016年版本推出的函数cwt。两个函数名称相同,用法不同。
(我也不知道为什么会这样。。。-_-||)

由于名称一样,在使用中,要想调用不同的版本,只能用输入输出格式来区分。

旧版本cwt用法为:

coefs = cwt(x,scales,'wname')

新版本cwt用法为:

[wt,f] = cwt(x,wname,fs)

最明显的区别在于,新版本取消了自定义尺度函数scales的功能。同时新版本还更新替换了一部分小波函数。旧版本支持 ‘haar’,‘db’,‘sym’,‘cmor’,‘mexh’,‘gaus’,‘bior’等小波,新版本支持’morse’, 'amor’和 'bump’小波。

新版小波的介绍可以参见:
https://ww2.mathworks.cn/help/wavelet/gs/choose-a-wavelet.html

新版本的小波函数用法如下:

% 定义信号信息
fs=2^6;    %采样频率
dt=1/fs;    %时间精度
timestart=-8;
timeend=8;
t=(0:(timeend-timestart)/dt-1)*dt+timestart;
L=length(t);

z=4*sin(2*pi*linspace(6,12,L).*t);

%matlab自带的小波变换
%新版本
figure(1)
[wt,f,coi] = cwt(z,'amor',fs);
pcolor(t,f,abs(wt));shading interp

旧版本的小波函数用法如下:
这里用到了cmor小波,以及频率转尺度的方法。

% 定义信号信息
fs=2^6;    %采样频率
dt=1/fs;    %时间精度
timestart=-8;
timeend=8;
t=(0:(timeend-timestart)/dt-1)*dt+timestart;
L=length(t);

z=4*sin(2*pi*linspace(6,12,L).*t);
%旧版本
wavename='cmor1-3'; %可变参数,分别为cmor的
%举一个频率转尺度的例子
fmin=2;
fmax=20;
df=0.1;

f=fmin:df:fmax-df;%预期的频率
wcf=centfrq(wavename); %小波的中心频率
scal=fs*wcf./f;%利用频率转换尺度
coefs = cwt(z,scal,wavename);
figure(2)
pcolor(t,f,abs(coefs));shading interp

对于cmor小波Fc和Fb的选取,可以认为最终结果只与Fc*√Fb的乘积大小有关就行。实际应用中具体值需要根据最终效果选择。

cmor小波最终得到的coefs小波系数,是一个复数矩阵,绝对值abs()代表信号的幅值,角度angle()代表信号的相位。一般用小波系数的实部real()来同时表示信号正负变化。
在这里插入图片描述
实部、虚部、相位、振幅的关系如下图所示:
在这里插入图片描述

其实cwt的原理很简单,就是用不同尺度的小波逐个窗口去卷积,得到小波系数矩阵。所以根据原理,可以自己编程实现小波变换。

自己编程的cwt函数如下,这里主要算法参考了matlab官方的文档。这里我依然用的是cmor小波作为例子,morlet函数公式可以查询到,也可以用cmorwavf()函数调用:

fs=2^6;    %采样频率
dt=1/fs;    %时间精度
timestart=-8;
timeend=8;
t=(0:(timeend-timestart)/dt-1)*dt+timestart;
L=length(t);
z=4*sin(2*pi*linspace(6,12,L).*t);

%定义计算范围和精度
fmin=2;
fmax=20;
df=0.1;
totalscal=(fmax-fmin)/df;
f=fmin:df:fmax-df;%预期的频率
wcf=centfrq(wavename); %小波的中心频率
scal=fs*wcf./f;

%自己实现的小波函数
coefs2=cwt_cmor(z,1,3,f,fs);
figure(3)
pcolor(t,f,abs(coefs2));shading interp


%后面是函数
function coefs=cwt_cmor(z,Fb,Fc,f,fs)
%1 小波的归一信号准备
z=z(:)';%强行变成y向量,避免前面出错
L=length(z);
%2 计算尺度
scal=fs*Fc./f;

%3计算小波
shuaijian=0.001;%取小波衰减长度为0.1%
tlow2low=sqrt(Fb*log(1/shuaijian));%单边cmor衰减至0.1%时的时间长度,参照cmor的表达式

%3小波的积分函数
iter=10;%小波函数的区间划分精度
xWAV=linspace(-tlow2low,tlow2low,2^iter);
stepWAV = xWAV(2)-xWAV(1);
val_WAV=cumsum(cmorwavf(-tlow2low,tlow2low,2^iter,Fb,Fc))*stepWAV;
%卷积前准备
xWAV = xWAV-xWAV(1);
xMaxWAV = xWAV(end);
coefs     = zeros(length(scal),L);%预初设coefs

%4小波与信号的卷积
for k = 1:length(scal)    %一个scal一行
    a_SIG = scal(k); %a是这一行的尺度函数

    j = 1+floor((0:a_SIG*xMaxWAV)/(a_SIG*stepWAV));
        %j的最大值为是确定的,尺度越大,划分的越密。相当于把一个小波拉伸的越长。
    if length(j)==1 , j = [1 1]; end
    
    waveinscal = fliplr(val_WAV(j));%把积分值扩展到j区间,然后左右颠倒。f为当下尺度的积分小波函数
    
    %5 最重要的一步 wkeep1取diff(wconv1(ySIG,f))里长度为lenSIG的中间一段
    %conv(ySIG,f)卷积。
    coefs(k,:) = -sqrt(a_SIG)*wkeep1(diff(conv2(z,waveinscal, 'full')),L);
    %
end
end

输出的结果如下,可以看到和matlab自带的函数得到的结果基本相同。
在这里插入图片描述

4 cwt的边缘效应与影响锥

利用自带的cwt函数,可以很方便的绘制出影响锥。

cwt(z)

在这里插入图片描述
由于小波计算中,小波系数是利用窗口函数和小波卷积而来的,当窗口在信号的边缘时,窗口内会存在一部分没有信号。这时,matlab就把窗口内这部分不完整的信号补零处理,凑够长度。

此时由于信号在边缘被强制补零,导致信号会失真,具体在时频图中表示为频率变宽,信号强度降低。严重的时候,甚至整个低频部分都会出现失真。这就是cwt的边缘效应。

为了确定边缘效应的影响,绘制出了一条影响曲线,曲线内部的信号影响小或者不受影响,曲线外部影响较大。曲线像一个锥形,高频处靠近两侧,低频处靠近中间,所以也被叫做影响锥。
在这里插入图片描述
所以根据边缘效应的原理,可以知道,之所以高频处影响范围小,是因为高频处小波被压缩,所以窗口更窄。低频处小波被拉伸,所以对应着窗口更宽。窗口的长度和小波的长度是相同的。

关于影响范围的评价,有很多种,这里为了方便说明,我直接用小波的半长度作为影响范围,来绘制影响锥。具体的思路如下,我认为超过小波长度一半的范围都是失真的,然后通过频率求出每一点的小波长度,再在图上连线绘制出来。
在这里插入图片描述

代码如下,依然以cmor小波为例,为了反应相位的影响,这里用的是real():

%小波变换展示
clear
fs=2^6;    %采样频率
dt=1/fs;    %时间精度
timestart=-8;
timeend=8;
t=(0:(timeend-timestart)/dt-1)*dt+timestart;
L=length(t);

z=sin(2*pi*5.*t)+sin(2*pi*9.*t)+sin(2*pi*15.*t);

%定义范围
wavename='cmor1-3'; %可变参数
fmin=2;
fmax=20;
df=0.1;
totalscal=(fmax-fmin)/df;
f=fmin:df:fmax-df;%预期的频率
wcf=centfrq(wavename); %小波的中心频率
scal=fs*wcf./f;

%旧版本
coefs = cwt(z,scal,wavename);
figure(2)
pcolor(t,f,real(coefs));shading interp

tlow2low=sqrt(1*log(1/0.001));%单边cmor衰减至0.1%时的时间长度
tcoi41=tlow2low*scal;%小波一半长度
bur=(tcoi41<L/2);
fcoi4=f(bur);
tcoi41=tcoi41(bur);
tcoi42=-tcoi41+L;
hold on
plot(tcoi41/fs+timestart,fcoi4,'r','LineWidth',2)
plot(tcoi42/fs+timestart,fcoi4,'r','LineWidth',2)
hold off

在这里插入图片描述

5 cwt的重构——icwt

如果用的是matlab新版的默认小波,那么可以直接把cwt之后小波系数icwt即可。

load mtlb;
wt = cwt(mtlb);
xrec = icwt(wt);

对于morlet小波,可以直接 sum(real(coefs),1) 来实现重构。但是,这里尺度最好用默认尺度,否则会出现重复叠加导致幅值出现问题。

具体用法可以参见帮助文档。

6 增加cwt的分辨率的wsst

利用wsst可以显著的提高cwt的频率分辨率。具体用法如下:

clear
fs=2^6;    %采样频率
dt=1/fs;    %时间精度
timestart=-8;
timeend=8;
t=(0:(timeend-timestart)/dt-1)*dt+timestart;
L=length(t);
z=4*sin(2*pi*linspace(6,12,L).*t);

[sst,f] = wsst(z,fs);
figure(4)
pcolor(t,f,abs(sst));shading interp

与普通cwt的对比图如下:
在这里插入图片描述
左图是cwt的时频图,右图是wsst的时频图。
wsst同样可以利用iwsst进行重构,具体方法可以参见iwsst的帮助文档。

如果想要提高wsst的精度,可以在matlab里选中wsst,然后Ctrl+D进入wsst的代码界面,把里面的na参数,强行改的大一点。

具体方法为在下面代码后,加上一个na=512(这里不一定是512,具体根据na实际值进行适当放大,在我这里的例子中,na=288。如果怕出错,建议备份)。

na = noct*params.nv;
na=512

这样做的优点是,在不影响iwsst的运行结果的基础上,显著的提高分解的精度。

在这里插入图片描述

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

matlab时频分析之连续小波变换cwt 的相关文章

  • for 循环中的绘图没有可见点

    我正在努力解决我想使用 for 循环制作的情节 我知道当我在循环之后添加它时它会起作用 只是一个简单的图 但我想用另一种方式尝试一下 fib ones 1 10 for k 3 10 hold on fib k fib k 1 fib k
  • 在matlab中,如何读取python pickle文件?

    在 python 中 我生成了一个 p 数据文件 pickle dump allData open myallData p wb 现在我想在Matlab中读取myallData p 我的Matlab安装在Windows 8下 其中没有Pyt
  • 获取向量幂的有效方法

    我编写了一个代码 在数值上使用勒让德多项式直至某个高 n 阶 例如 case 8 p 6435 x 8 12012 x 6 6930 x 4 1260 x 2 35 128 return case 9 如果向量x太长这会变得很慢 我发现说之
  • Ilnumerics Ilpanel 在 winform 中编译成 dll 并加载到 matlab 时不激活

    我想将 Visual studio 2012 中用 C 编写的 winform 编译为 dll 然后将其加载到 matlab 2013a 中 然后 我想使用 matlab net 接口与 winform 进行交互 侦听其事件并通过一组预定义
  • matlab中更快的插值方法

    我正在使用 interp1 来插值一些数据 temp 4 30 4 rand 365 10 depth 1 10 dz 0 5 define new depth interval bthD min depth dz max depth ne
  • 禁止 MATLAB 自动获取焦点[重复]

    这个问题在这里已经有答案了 我有以下问题 在我的 MATLAB 代码中 我使用如下语句 figure 1 更改某些数据的目标数字 问题是 在此 MATLAB 之后 系统将焦点集中在具有该图形的窗口上 当我在后台运行一个大脚本并尝试在计算机上
  • 将向量(或弧)绘制到玫瑰图上。 MATLAB

    我有两个数据集 其中详细列出了angles 我正在绘制玫瑰图 angles 0 8481065519 0 0367932161 2 6273740453 n 另一个 从这组角度详细说明方向统计 angle error 0 848106563
  • 如何选择面积最大的对象?

    我用过bwconvhull检测图像的某个部分 正如您在图像中看到的那样 有许多具有特定质心的对象 我想做的是检测面积最大的物体 左起第一个大物体 并忽略其他物体 我应该遵循哪种方法 我将非常感谢您的帮助 以下是代码 由于我仍在努力 所以写得
  • MATLAB:将当前文件夹设置为脚本位置

    我在不同的文件夹中有一些脚本和数据 我使用addpath和相对路径经常 我的问题是 只有当我的当前文件夹是我执行的脚本所在的位置时 这才有效 例如 如果我执行添加路径 X 的脚本 A 然后执行位于路径 X 中的脚本 B 则 Matlab 不
  • 使用简单矩阵乘法时出错

    我在一次简单的乘法运算中偶然发现了一个错误 这让我感到非常惊讶 我一直以为这里发生了什么 只为矩阵乘法 http www mathworks nl help matlab matlab prog operators html x 2 y z
  • 如何在 MATLAB 中将矩阵元素除以列总和?

    有没有一种简单的方法可以将每个矩阵元素除以列和 例如 input 1 4 4 10 output 1 5 4 14 4 5 10 14 以下是执行此操作的不同方法的列表 使用bsxfun https www mathworks com he
  • 保存符号方程以供以后使用?

    From here http www mathworks com help releases R2011a toolbox symbolic brvfu8o 1 html brvfxem 1 我正在尝试求解这样的符号方程组 syms x y
  • 通过颜色渐变修补圆

    我正在尝试绘制一个颜色渐变 我希望它沿轴均匀 在下图由角度定义的情况下 pi 7 当我使用patch命令 绘图与所需的梯度方向匹配 但沿其方向并不均匀 沿圆的点之间形成各种三角形 这是代码 N 120 theta linspace pi p
  • 如何从 matlab 调用 Qtproject?

    我在 matlab 中有一个函数可以写入一个 file txt 我在 qt 项目中使用它 So 当我使用 unix 获取要运行的 qt 编译可执行文件时 我有一个 Matlab 文件 但出现错误 代码 unix home matt Desk
  • 2D 网格的纹理贴图

    我有一组点 x y meshgrid 1 N 1 M 在常规二维上定义 N x M网格 我还有另一组要点 u v 这是原始网格的一些变形 即 u v f x y 但是我没有实际的f导致变形 如何将纹理映射到由定义的 变形 网格u v 即 给
  • 像matlab一样在python中连接数组而不知道输出数组的大小

    我正在尝试在 python 中连接数组 类似于 matlab array1 zeros 3 500 array2 ones 3 700 array array1 array2 我在 python 中做了以下操作 array1 np zero
  • 氡变换线检测

    我正在尝试检测灰度图像中的线条 为此 我在 MATLAB 中使用 Radon 变换 我的 m 文件的示例如下所示 我可以使用此代码检测多行 我还使用线条的移位和旋转属性来绘制线条 但是 我不明白在获取rho和theta值后如何获取检测线的起
  • Blob 的簇生长

    考虑以下来自 Mathworks 的图像 我已经用标签标记了斑点 L num bwlabel I 如何迭代连接所有斑点 即从一个斑点开始 找到离它最近的一个 考虑最左边的两个斑点 可以从一个斑点的许多点绘制许多条线来连接到另一个斑点blob
  • 用于读取csv写入数组的c++程序;然后操作并打印到文本文件中(已经用 matlab 编写)

    我想知道是否有人可以帮助我 我正在尝试构建一个程序 从 csv 文件中读取大小未知的浮点数大数据块 我已经在 MATLAB 中编写了此代码 但想要编译和分发此代码 因此转向 C 我只是在学习并尝试阅读本文以开始 7 5 19892 4 23
  • Matlab 错误:()-索引必须出现在索引表达式的最后

    我有这段代码 想要在制表符分隔的 txt 文件中写入一个数组 fid fopen oo txt wt for x 1 length s fprintf fid s t n s x 1 end fclose fid 但我收到此错误 Error

随机推荐

  • RedHat系统NetworkManage网络管理工具简介及相关命令(lspci、lshw)

    1 RedHat网络管理工具简介 在早期的Linux发行版本中几乎所有的网络服务都是network服务 从RHEL7开始 红帽官方建议采用NetworkManage方式配置网络 而不建议再使用network服务这种传统的方式配置网络 因为网
  • C++中对象的动态建立与释放详解

    我们知道可以用new运算符可以动态的分配内存 用delete运算符可以释放这些内存 当我们使用new运算符动态的分配一个内存之后 会自动返回一个该内存段的起始地址 也就是指针 下面先给出一个new和delete基本应用的例子 回顾一下它的基
  • Python自动化工具(自动化操作)

    一 多层目录的遍历 1 绝对路径和相对路径 相对路径 此路径下的 比绝对路径短 绝对路径 完整的路径 根目录开始 C盘等 C 或 开始 2 不同系统的路径问题 import os 来适应不同系统 版本windows和liunx 3 多层级的
  • 最大堆 和 优先队列

    最大堆 MaxHeap java import java util Random 后面测试用 public class MaxHeap
  • Gan学习

    参考博客 https blog csdn net u010678153 article details 54629393 https www cnblogs com Charles Wan p 6238033 html GAN原理介绍 说到
  • Java框架!mysqlmd5解密

    并发编程三大特性 原子性 一个操作或者多次操作 要么所有的操作全部都得到执行并且不会受到任何因素的干扰而中断 要么所有的操作都执行 要么都不执行 对于基本数据类型的访问 读写都是原子性的 long和double可能例外 如果需要更大范围的原
  • CTF从入门到提升(十一)文件包含

    Include stdio h Import request 很多网站的admin 管理员 入口和user 用户 入口是分开的 登陆过程所调用的函数可能都是同一个函数 最后操作的表不同 如果调用的是同一个函数 网站一般分开两个文件存储 ad
  • JetBrains 各 IDE 通用快捷键总结(包括 InteliJ idea,PyCharm,RubyMine,GoLand 等)

    JetBrains 全家桶 IDE 集成开发环境 用起来很方便 而且快捷键都是通用的 至少绝大部分常用的快捷键是通用的 功能十分强大 还可以安装 ideaVim 等各种插件 熟练掌握对提高效率很有帮助 我会把常用的命令用红色粗体标记一下 C
  • STM32中GPIO的8种工作模式!

    一 推挽输出 可以输出高 低电平 连接数字器件 推挽结构一般是指两个三极管分别受两个互补信号的控制 总是在一个三极管导通的时候另一个截止 高低电平由IC的电源决定 推挽电路是两个参数相同的三极管或MOSFET 以推挽方式存在于电路中 各负责
  • T1串口波特率的计算方法

    T1的波特率 2 SMOD指数 32 定时器T1的溢出率 TI溢出率 TI计数率 产生溢出所需的周期数 具体来说 一个机器周期是晶振的频率f除以12 标准模式 每当计数到256 TH1溢出一次 定时器1工作在方式2 8位 使用11 0592
  • 数仓建模分层理论

    分层建设理论 简单点儿 直接ODS DM就可以了 将所有数据同步过来 然后直接开发些应用层的报表 当DM层的内容多了以后 想要重用 就会再拆分一个公共层出来 变成3层架构 这个过程有点类似代码重构 就是在实践中不断的进行抽象 总结 数仓的建
  • 计算工资

    某公司员工的工资计算方法如下 一周内工作时间不超过40小时 按正常工作时间计酬 超出40小时的工作时间部分 按正常工作时间报酬的1 5倍计酬 员工按进公司时间分为新职工和老职工 进公司不少于5年的员工为老职工 5年以下的为新职工 新职工的正
  • Nginx的重写功能——Rewrite

    目录 Nginx常见模块 nginx内置模块 nginx配置文件的常见模块 location模块 常见的正则表达式 location常用的匹配规则 Rewrite模块 Rewrite功能 Rewrite跳转场景 Rewrite跳转实现 语法
  • git:在提交后修改历史提交的作者并同步修改历史commit

    Reset author after author has been changed in the global config 参考 https github com 521xueweihan git tips 同时里面还有其他的git使用
  • 什么是敏捷测试?

    敏捷测试是一种遵循敏捷软件开发规则和原则的测试实践 与瀑布方法不同 敏捷测试可以在项目开始时就开始进行 而开发和测试之间会不断进行集成 敏捷测试方法不是连续的 从某种意义上说 它仅在编码阶段之后执行 而是连续的 敏捷测试计划 敏捷测试计划包
  • Vue+ElementUI+Echarts的地图DOM

    地图图表的开发在我们开发的过程中就很常见 特别是在开发大屏的时候 最近在进行地图图表的开发 就单独用引入的方式来记录一个DOM 让大家一起学习下 示例图 从上图可以看到 这个主要是就是对地图做个一个展示 省份的高亮 各个板块的颜色修改的一些
  • docker安装hbase

    1 下载docker与hbase docker 的下载与安装请参考 https blog csdn net weixin 35757704 article details 114777186 docker pull harisekhon h
  • Vue全局后置守卫

    全局后置守卫 一 在 router 目录下的 index js 文件中配置全局后置守卫 import Vue from vue import VueRouter from vue router Vue use VueRouter impor
  • 如何将时间戳转化为时间格式化字符串

    问题描述 通常服务器返回的时间都不以这种格式出现比如2021 6 1 20 08 30 通常会以Unix时间元年为起点 返回对应的时间戳 15355352553 时间戳 那么我们如何将时间戳转化为时间格式化字符串 首先将时间戳转化为Date
  • matlab时频分析之连续小波变换cwt

    matlab时频分析之连续小波变换cwt 1 小波分析简介 2 小波分析基本原理 3 cwt的matlab实现 4 cwt的边缘效应与影响锥 5 cwt的重构 icwt 6 增加cwt的分辨率的wsst 2020年7月更新 第3节绘制了一个