一维信号的小波分解重构程序

感谢网友‘李明杨艳’指出了我此前三个版本的小波信号分解重构程序中有关一维信号分解重构的程序mydwtmyidwt都存在的一个大Bug,因为当时编程时都是按照haar小波的特点来写的代码,没有考虑到使用其它小波函数滤波器组时卷积运算的输出序列长度变化的问题,后来的版本也只集中于二维图像方面,没有考虑一维信号,现已修正。更新的程序代码如下:<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />

function [c,l] = mydwt(x,lpd,hpd,dim);

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

% 函数 [c,l]=MYDWT(X,LPD,HPD,DIM) 对输入序列x进行一维离散小波分解,输出分解序列c

% 输入参数:x——输入序列;

% lpd——低通滤波器;

% hpd——高通滤波器;

% dim——小波分解层数。

% 输出参数:c——小波分解系数序列;

% l——各级小波分解系数的长度。

%

% Copyright by Zou Yuhua ( chenyusiyuan ), Created: <?xml:namespace prefix = st1 ns = "urn:schemas-microsoft-com:office:smarttags" /><chsdate w:st="on" isrocdate="False" islunardate="False" day="10" month="11" year="2007">2007-11-10</chsdate>,

% Modified: <chsdate w:st="on" isrocdate="False" islunardate="False" day="1" month="9" year="2008">2008-09-01</chsdate>

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

cA=x;

c=[];

l=length(x);

for i=1:dim

cvl=conv(cA,lpd); % 低通滤波

dnl=downspl(cvl); % 通过下抽样求出平均部分的分解系数

cvh=conv(cA,hpd); % 高通滤波

dnh=downspl(cvh); % 通过下抽样求出本层分解后的细节部分系数

cA=dnl; % 下抽样后的平均部分系数进入下一层分解

c=[dnh,c]; % 将本层分解所得的细节部分系数存入序列c

lcd=length(dnh); % 求出细节部分分解系数的长度,存入序列数组 l

l=[lcd,l];

end

c=[cA,c];

l=[length(cA),l];

function y = myidwt(c,l,lpr,hpr);

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

% 函数 MYIDWT() 对输入的小波分解系数进行逆离散小波变换,重构出信号序列 y

% 输入参数:c——小波分解系数序列;

% l——各级小波分解系数的长度。;

% lprhpr —— 重构所用的低通、高通滤波器。

%

% Copyright by Zou Yuhua ( chenyusiyuan ), Created: <chsdate w:st="on" isrocdate="False" islunardate="False" day="10" month="11" year="2007">2007-11-10</chsdate>,

% Modified: <chsdate w:st="on" isrocdate="False" islunardate="False" day="1" month="9" year="2008">2008-09-01</chsdate>

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

cA=c(1:l(1));

for i=1:length(l)-2

upl=upspl(cA); % 对平均部分系数进行上抽样

cvl=conv(upl,lpr); % 低通卷积

cvl=wkeep(cvl,l(i+2));

st=sum(l(1:i))+1;

ed=st+l(i+1)-1;

cD=c(st:ed); % 取出本层重构所需的细节部分系数

uph=upspl(cD); % 对细节部分系数进行上抽样

cvh=conv(uph,hpr); % 高通卷积

cvh=wkeep(cvh,l(i+2));

cA=cvl+cvh; % 用本层重构的序列更新cA,以进行下一层重构

end

y=cA; % 输出的重构序列 y 等于重构完成后的平均部分系数序列 cA

function y=downspl(x);

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

% 函数 Y=DOWMSPL(X) 对输入序列进行下抽样,输出序列 Y

% 下抽样是对输入序列取其偶数位,舍弃奇数位。例如 x=[x1,x2,x3,x4,x5],则 y=[x2,x4].

%

% Copyright by Zou Yuhua ( chenyusiyuan ), Version: 1.0, Date: <chsdate w:st="on" isrocdate="False" islunardate="False" day="10" month="11" year="2007">2007-11-10</chsdate>

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

N=length(x); % 读取输入序列长度

M=floor(N/2); % 输出序列的长度是输入序列长度的一半(带小数时取整数部分)

i=1:M;

y(i)=x(2*i);

% y=x(2:2:end);

function y=upspl(x);

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

% 函数 Y = UPSPL(X) 对输入的一维序列x进行上抽样,即对序列x每个元素之间

% 插零,例如 x=[x1,x2,x3,x4],上抽样后为 y=[0,x1,0,x2,0,x3,0,x4,0];

%

% Copyright by Zou Yuhua ( chenyusiyuan ), Created: <chsdate w:st="on" isrocdate="False" islunardate="False" day="10" month="11" year="2007">2007-11-10</chsdate>, Modified: <chsdate w:st="on" isrocdate="False" islunardate="False" day="7" month="7" year="2008">2008-07-07</chsdate>

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

N=length(x); % 读取输入序列长度

M=2*N+1; % 输出序列的长度是输入序列长度的2倍再加一

y=zeros(1,M);

k=1:N;

y(2*k)=x(k); % 输出序列的奇数位为0,偶数位按次序等于相应位置的输入序列元素

你可能感兴趣的:(C++,c,Microsoft,C#,Office)