Matlab时频分析之连续小波变换CWT

1. 小波分析介绍

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

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

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

2. 小波分析基本原理

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

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

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

小波中,一般用尺度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小波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;%预期的频率

%自己实现的小波函数
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自带的函数得到的结果基本相同。
在这里插入图片描述

  • 19
    点赞
  • 134
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
小波变换的图像处理%MATLAB2维小波变换经典程序 % FWT_DB.M; % 此示意程序用DWT实现二维小波变换 % 编程时间2004-4-10,编程人沙威 %%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%% clear; clc; T=256; % 图像维数 SUB_T=T/2; % 子图维数 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % 1.调原始图像矩阵 load wbarb; % 下载图像 f=X; % 原始图像 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % 2.进行二维小波分解 l=wfilters('db10','l'); % db10(消失矩为10)低通分解滤波器冲击响应(长度为20) L=T-length(l); l_zeros=[l,zeros(1,L)]; % 矩阵行数与输入图像一致,为2的整数幂 h=wfilters('db10','h'); % db10(消失矩为10)高通分解滤波器冲击响应(长度为20) h_zeros=[h,zeros(1,L)]; % 矩阵行数与输入图像一致,为2的整数幂 for i=1:T; % 列变换 row(1:SUB_T,i)=dyaddown( ifft( fft(l_zeros).*fft(f(:,i)') ) ).'; % 圆周卷积FFT row(SUB_T+1:T,i)=dyaddown( ifft( fft(h_zeros).*fft(f(:,i)') ) ).'; % 圆周卷积FFT end; for j=1:T; % 行变换 line(j,1:SUB_T)=dyaddown( ifft( fft(l_zeros).*fft(row(j,:)) ) ); % 圆周卷积FFT line(j,SUB_T+1:T)=dyaddown( ifft( fft(h_zeros).*fft(row(j,:)) ) ); % 圆周卷积FFT end; decompose_pic=line; % 分解矩阵 % 图像分为四块 lt_pic=decompose_pic(1:SUB_T,1:SUB_T); % 在矩阵左上方为低频分量--fi(x)*fi(y) rt_pic=decompose_pic(1:SUB_T,SUB_T+1:T); % 矩阵右上为--fi(x)*psi(y) lb_pic=decompose_pic(SUB_T+1:T,1:SUB_T); % 矩阵左下为--psi(x)*fi(y) rb_pic=decompose_pic(SUB_T+1:T,SUB_T+1:T); % 右下方为高频分量--psi(x)*psi(y) %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % 3.分解结果显示 figure(1); colormap(map); subplot(2,1,1); image(f); % 原始图像 title('original pic'); subplot(2,1,2); image(abs(decompose_pic)); % 分解后图像 title('decomposed pic'); figure(2); colormap(map); subplot(2,2,1); image(abs(lt_pic)); % 左上方为低频分量--fi(x)*fi(y) title('\Phi(x)*\Phi(y)'); subplot(2,2,2); image(abs(rt_pic)); % 矩阵右上为--fi(x)*psi(y) title('\Phi(x)*\Psi(y)'); subplot(2,2,3); image(abs(lb_pic)); % 矩阵左下为--psi(x)*fi(y) title('\Psi(x)*\Phi(y)'); subplot(2,2,4); image(abs(rb_pic)); % 右下方为高频分量--psi(x)*psi(y) title('\Psi(x)*\Psi(y)'); %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % 5.重构源图像及结果显示 % construct_pic=decompose_matrix'*decompose_pic*decompose_matrix; %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% l_re=l_zeros(end:-1:1); % 重构低通滤波 l_r=circshift(l_re',1)'; % 位置调整 h_re=h_zeros(end:-1:1); % 重构高通滤波 h_r=circshift(h_re',1)'; % 位置调整 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% top_pic=[lt_pic,rt_pic]; % 图像上半部分 t=0; for i=1:T; % 行插值低频 if (mod(i,2)==0) topll(i,:)=top_pic(t,:); % 偶数行保持 else t=t+1; topll(i,:)=zeros(1,T); % 奇数行为零 end end; for i=1:T; % 列变换 topcl_re(:,i)=ifft( fft(l_r).*fft(topll(:,i)') )'; % 圆周卷积FFT end; %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% bottom_pic=[lb_pic,rb_pic]; % 图像下半部分 t=0; for i=1:T; % 行插值高频 if (mod(i,2)==0) bottomlh(i,:)=bottom_pic(t,:); % 偶数行保持 else bottomlh(i,:)=zeros(1,T); % 奇数行为零 t=t+1; end end; for i=1:T; % 列变换 bottomch_re(:,i)=ifft( fft(h_r).*fft(bottomlh(:,i)') )'; % 圆周卷积FFT end; construct1=bottomch_re+topcl_re; % 列变换重构完毕 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% left_pic=construct1(:,1:SUB_T); % 图像左半部分 t=0; for i=1:T; % 列插值低频 if (mod(i,2)==0) leftll(:,i)=left_pic(:,t); % 偶数列保持 else t=t+1; leftll(:,i)=zeros(T,1); % 奇数列为零 end end; for i=1:T; % 行变换 leftcl_re(i,:)=ifft( fft(l_r).*fft(leftll(i,:)) ); % 圆周卷积FFT end; %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% right_pic=construct1(:,SUB_T+1:T); % 图像右半部分 t=0; for i=1:T; % 列插值高频 if (mod(i,2)==0) rightlh(:,i)=right_pic(:,t); % 偶数列保持 else rightlh(:,i)=zeros(T,1); % 奇数列为零 t=t+1; end end; for i=1:T; % 行变换 rightch_re(i,:)=ifft( fft(h_r).*fft(rightlh(i,:)) ); % 圆周卷积FFT end; %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% construct_pic=rightch_re+leftcl_re; % 重建全部图像 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % 结果显示 figure(3); colormap(map); subplot(2,1,1); image(f); % 源图像显示 title('original pic'); subplot(2,1,2); image(abs(construct_pic)); % 重构源图像显示 title('reconstructed pic'); error=abs(construct_pic-f); % 重构图形与原始图像误值 figure(4); mesh(error); % 误差三维图像 title('absolute error display');
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值