Matlab时频分析之连续小波变换CWT | 您所在的位置:网站首页 › 小波基选择 › Matlab时频分析之连续小波变换CWT |
1. 小波分析介绍
和傅里叶变换比,小波变换和短时傅里叶变换都有着相同的优点,就是可以同时在时域和频域观察信号。所以小波变换在非定常信号的分析中有很大的作用。 和短时傅里叶变换相比,小波变换有着窗口自适应的特点,即高频信号分辨率高(但是频率分辨率差),低频信号频率分辨率高(但是时间分辨率差),而在工程中常常比较关心低频的频率和高频出现的时间,所以近些年用途比较广泛。 在数学上,小波还有正交化等优点,应用领域广泛。 本文只讨论如何利用matlab实现cwt的时频分析 2. 小波分析基本原理小波的含义,即为时间上衰减快,和傅里叶的正弦波相比要短。 一个典型的morlet小波如下图: 在时域上,可以通过小波在时间上的移动,逐一比较不同位置的窗口信号,得到小波系数。小波系数越大,则小波与该段信号的拟合程度越好。计算时用小波函数与该窗口的信号卷积,作为该窗口下的小波系数。窗口的长度和小波的长度是相同的。 将不同频率下的小波系数组合起来,便得到了时频变换的小波系数图。 小波中,一般用尺度scale来衡量小波的频率f, 两者之间的转换关系为: scale * f=Fs * wcf公式中,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小波最终得到的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;%预期的频率 %自己实现的小波函数 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;%取小波衰减长度为1% tlow2low=sqrt(Fb*log(1/shuaijian));%单边cmor衰减至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自带的函数得到的结果基本相同。 |
今日新闻 |
推荐新闻 |
专题文章 |
CopyRight 2018-2019 实验室设备网 版权所有 |