原创 连续小波变换实现方法的小结与程序详解

2011-6-14 15:08 8185 9 10 分类: 测试测量
http://www.chinavib.com/forum/thread-56930-1-79.html

 

连续小波变换实现方法的小结与程序详解
在帖子“给大家分享我自己编的程序-连续小波变换” 中,pengzk版友给出了morlet小波变换的源代码,但其中的许多参数和语句意义不够明确,这就给一些希望了解连续小波
变换实现方法的版友带来不便。因此,本帖将对连续小波变换的实现原理做个小结,希望对各位有所帮助。
   
      首先说明的是,在Matlab的小波工具箱和pengzk版友提供的程序中,连续小波变换都是依据以下原理实现的:连续小波变换可以看成是原信号与小波基进行卷积的结果
   
      下面我以自编的连续morlet小波变换程序为例说明利用卷积方法实现连续小波变换的过程(参见程序注释)。其中,所用morlet小波的定义
59843_1247061059OKxq.jpg

 程序如下:
复制内容到剪贴板 代码:function wcoefs = mymorletcwt(Sig,Scales,fc,fb)
%============================================================%
%  Continuous Wavelet Transform using Morlet function               
%%%%%%%%%%%%%%%%%%%%%%%%输入%%%%%%%%%%%%%%%%%%%%%%%%%%
%    Sig: 输入信号                                          
%    Scales: 输入的尺度序列
%    fc: morlet小波中心频率  (默认为2)
%    fb: morlet小波带宽参数   (默认为2)      
%%%%%%%%%%%%%%%%%%%%%%%%输出%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%    wcoefs:  morlet小波变换计算结果
%============================================================%
if (nargin <= 1),
     error('At least 2 parameters required');
end;
if (nargin < 4),
     fb = 2;
elseif (nargin < 3),
     fc = 2;
end;
wavsupport=8;                           % 默认morlet小波的支撑区为[-8,8]
nLevel=length(Scales);                  % 尺度的数目
SigLen = length(Sig);                   % 信号的长度
wcoefs = zeros(nLevel, SigLen);         % 分配计算结果的存储单元
for m = 1:nLevel                        % 计算各尺度上的小波系数
   
    a = Scales(m);                                   % 提取尺度参数                              
    t = -round(a*wavsupport):1:round(a*wavsupport);          % 在尺度a的伸缩作用下,此时小波函数的支撑区会变为[-a*wavsup,a*wavsup],采样频率为1Hz
    Morl = fliplr((pi*fb)^(-1/2)*exp(i*2*pi*fc*t/a).*exp(-t.^2/(fb*a^2)));     % 计算当前尺度下的小波函数,按小波变换的定义这里需要倒置
    temp = conv(Sig,Morl) / sqrt(a);            % 计算信号与当前尺度下小波函数的卷积   
    d=(length(temp)-SigLen)/2;                  % 由于卷积计算所得结果的长度可能远远大于原信号,只需提取按原信号的长度提取中间部分的系数
    first = 1+floor(d);                         % 区间的起点
    wcoefs(m,=temp(first:first+SigLen-1);   
   
end
从以上程序可以看出,基于卷积原理的连续小波变换实现的关键是求出某一尺度下的小波函数离散化后的序列。该序列可以通过对该尺度下的小波函数进行采样求得,采样区间为此时小波
函数的支撑区,采样频率可取为1Hz。

   注:(1)按我的理解,采样频率取得越大,计算结果也越精确,但我在测试中发现,采样频率取得太高反而会影响分析结果的精度,在本例中采样频率最好取为1Hz。
         (2)在小波工具箱的cwt函数中,某一尺度下的小波函数采样序列是直接对母小波采样序列伸缩而得。


下面利用zhlong给出的例子对mymorletcwt进行测试,并与小波工具箱中cwt所得结果进行对比。
复制内容到剪贴板 代码:clc;
clear;
SampFreq = 30;
t=1/SampFreq:1/SampFreq:4;
sig = sin(12*pi*t);
sig(1:end/2) = sig(1:end/2) + sin(6*pi*t(1:end/2));
sig(end/2+1:end) = sig(end/2+1:end) + sin(18*pi*t(end/2+1:end));
fmax = 0.5;                                    % 最高分析频率(归一化频率)
fmin = 0.005;                                  % 最低分析频率(归一化频率)
fb = 4 ;                                       % 取cmor4-2小波进行实验,带宽参数为4
fc = 2;                                        % 中心频率2Hz                                      
totalscal = 512;                               % 所取尺度的数目                                         
FreqBins = linspace(fmin,fmax,totalscal);      % 将频率轴在分析范围内等间隔划分
Scales = fc./ FreqBins;                        % 计算相应的尺度参数
wcoefs = mymorletcwt(sig,Scales,fc,fb);        
RealFreqBins = FreqBins * SampFreq;            % 尺度所对应的实际频率
%%%%%%%%%%%%%%%%%%%%%%%%%本帖方法的结果%%%%%%%%%%%%%%%%%%%%%%%%
figure(1)
pcolor(t,RealFreqBins,abs(wcoefs));
colormap jet;
shading interp;
axis([min(t) max(t) min(RealFreqBins) max(RealFreqBins)]);
colorbar;
ylabel('Frequency / Hz');
xlabel('Time / sec');
%%%%%%%%%%%%%%%%%%%%%%%%%小波工具箱中的cwt结果%%%%%%%%%%%%%%%%%%%%%%%%
figure(2)
MWT=cwt(sig,Scales,'cmor4-2');
pcolor(t,RealFreqBins,abs(MWT));
colormap jet;
shading interp;
colorbar;
axis([min(t) max(t) min(RealFreqBins) max(RealFreqBins)]);
ylabel('Frequency / Hz');
xlabel('Time / sec');
测试结果如下:
本帖方法的结果
59843_1247061064Ta5Z.jpg
 
小波工具箱中的cwt结果
59843_1247061070XQ5h.jpg 
 


     对比两图可见,两种方法的精度相仿。我通过查看cwt的源代码发现,两者的区别在于小波工具箱中的cwt是按先对小波函数积分,卷积后再微分的方法来求小波系数的。至于这样做的根据就不得而知了。对于其它小波,也应该可以按以上原理实现,特别是那些可以用解析形式表示的小波,如Gaussian小波、Shannon小波、B样条小波等。

     小结:按卷积原理实现的连续小波变换的方法简单直观,并且个人认为其本质上是一种矩形数值积分法。但这种方法的计算精度和速度可能不如其它方法,如更高精度的数值积分法、调频Z变换法、梅林变换法等。在此,偶也希望其它版友能积极发帖对这几种方法进行讨论。

文章评论1条评论)

登录后参与讨论

用户377235 2016-2-19 15:08

垃圾。。
相关推荐阅读
xuyaosong 2012-11-28 14:24
Lesson 4 4:MATLAB - FFT and Zero Padding
http://blinkdagger.com/matlab/matlab-fft-and-zero-padding This is the fourth post in the blinkdag...
xuyaosong 2012-11-28 13:54
C语言中 多个源文件之间函数如何调用
首先要建立一个头文件,以.h保存 这样 #include typedef struct { char name[100][60]; char number[100][8]; int m...
xuyaosong 2012-11-28 13:53
小波变换尺度相关性去噪程序
所实现的相关性去噪函数为function [s1 a d] = SSNF(s, n, h, g, g1),具体的实现步骤为: 1) 调用离散二进小波分解函数对信号进行分解,得到逼近系数a 和细节...
xuyaosong 2012-11-28 13:29
功率谱密度幅值的具体含义??
http://www.chinavib.com/forum/thread-17307-1-48.html 求信号功率谱时候用下面的不同方法,功率谱密度的幅值大小相差很大! 我的问题是,计算具体...
xuyaosong 2012-01-12 18:38
声明函数指针并实现回调
程序员常常需要实现回调。本文将讨论函数指针的基本原则并说明如何使用函数指针实现回调。注意这里针对的是普通的函数,不包括完全依赖于不同语法和语义规则的类成员函数(类成员指针将在另文中讨论)。 ...
xuyaosong 2012-01-12 18:36
如何不用访问地址的方式来编写并口程序 ★★★★★
兄弟我在精华发现了一些关于并口打印的文章,但是都是用inb outb操作的,不知道各路高人能否给小弟一个用open write ioctl read close控制的判断状态并读写的例子,尤...
我要评论
1
9
关闭 站长推荐上一条 /2 下一条