模极大值去噪算法步骤:
1.对含噪信号进行尺度为,J=1,2,......,J的小波变换,并求出每个尺度上变换系数的模极大值。
2.从最大尺度开始,确定一个阈值T,把该尺度上模极大值小于T的极值点去掉,保留其他的,得到最大尺度上的一组新的模极大值点。
3.作出尺度函数j=J上保留的每个极大值点的一个邻域,如N(t,s),在J-1尺度上找出与邻域,在J-1尺度上找出与邻域N(t,s)内的极值点相对应的传播点(极值点),保留这些极值点,去掉其他极值点,从而得到j-1尺度上的一组新极值点。
4.置j=j-1,重复步骤3,直到j=2.
5.在j=2时保存的极值点位置上,找出j=1时对应的极值点,而去掉其他。
6.利用多尺度上保留的极值点的小波系数,采取适当方法重构。信号重构的方法有Mallat提出的交错投影的方法(如代码Py投影和Pgama投影),还有利用框架理论近似重构信号的快速算法。
function int=Py(int,len)
%单区间Py投影:对区间进行裁剪,即Py投影,返回裁剪后的区间信号
%输入参数:int为单区间的点,len为区间中点的个数
%返回值int为Py投影后的区间
if sign(int(1))==sign(int(len))%若区间左右端点同号,其中sign为符号函数,Y = sign(x) 返回与 x 大小相同的数组 Y,其中 Y 的每个元素是:1,前提是 x 的对应元素大于 0。0,前提是 x 的对应元素等于 0。-1,前提是 x 的对应元素小于 0。x./abs(x),前提是 x 为复数
int=int.*(sign(int)==sign(int(1)));%区间上,只保留本身符号与左端点符号相同的那些
inte=interp1([1,len],[int(1),int(len)],(1:len),'linear');
%只用区间端点处的值,在区间上进行线性插值,得到区间的插值后的点,与原来区间点个数相同
int=sign(int(1))*(abs(inte)-(abs(inte)-abs(int)).*((abs(inte)-abs(int))>0));
%只保留区间上的点的模值比线性插值对应点模值小的那些点,其余的为0,符号与左端点一致
else
sgn=sign(int(len)-int(1));%若区间端点不同号,则取相减的符号。两极值点异号,中间有单调性
intem=max([int(1),int(len)]);%对端点中的最大和最小点分别赋值
inten=min([int(1),int(len)]);%从区间端点开始,循环找寻该区间的极大值点和极小值点
for i=1:len-2
if sign(int(i+1)-int(i))~=sgn %若差商符号不是sgn,令二者相等,保证两个极值点之间的单调性
int(i+1)=int(i);
end
if int(i+1)>intem %比端点大,则是端点值
int(i+1)=intem;
end
if int(i+1)
function int =Pg(int,lev,sr)
%该函数对一个区间进行Pgama投影
%输入参数:int为极值点处差,lev为层号,sr为采样率
%返回值int为修正的区间
T=length(int);
if T==2 %只有两个点,则不动
int=int;
else
t=linspace(0,(T-1)/sr,T);%在0和(T-1)/sr中均匀插点,使最后点的个数为T
para=(([1,1;exp(2^(-lev)*t(T)),exp(-2^(-lev)*t(T))])\[int(1),int(T)]')';
ap=para(1);
bt=para(2);
int=ap.*exp(2^(-lev).*t)+bt.*exp(-2^(-lev).*t);%修正的区间
end
end
function w2 = Pyg(w1,wp,sr)
%用于进行Pgama和Py投影
%输入参数:w1为加入细节信息改进的分解信号,wp为小波多层分解后的信号的极值点,sr为采样率
%返回值w2为投影的最终结果
err=wp-w1.*(wp~=0);%极值点位置处原来与现在的差
w2=zeros(size(wp));
[r,c]=size(wp);
%对每一层小波分别进行处理
for m=1:r %处理每一层
fr=find(wp(m,:)); %模极值点位置,
num_int=length(fr)-1;%用模极值点将区间分段,区间个数为极值点个数-1
%先找到以模极大值划分的区间,然后对每一区间进行Py投影
for j=1:num_int
int=w1(m,fr(j):fr(j+1));%极值点划分的区间中的点
len=length(int);%区间中点的个数
if len>2
w1(m,fr(j):fr(j+1))=Py(int,len);%区间内多于两个点,即中间有点,则进行Py投影
end
end
%再逐一区间进行Pgama投影
for j=1:num_int
int=err(m,fr(j):fr(j+1)); %在两极值点之间的原来与现在的差,
err(m,fr(j):fr(j+1))=Pg(int,m,sr);
end
w2(m,:)=w1(m,:)+err(m,:); %投影最终结果
end
function s = mden(f,lev,n,wf)
%模极大值法去噪
%参数C,ep,sr可以调节
%输入参数为:f为带去噪信号,lev为小波分解层数,n去噪重构算法的迭代次数,wf为小波函数名称
%返回值s为重建信号
% load sumsin;%输入带噪信号
% f=[sumsin zeros(1,24)];%补零使得信号变成2的幂次,这里是信号长度变为1024
% lev=4;%模极大值提取时的分解层数
% n=20;%模极大值重构信号时的迭代次数
% wf='db3';%采用的小波函数
pp=size(f);
pp=pp(2);%所处理数据的长度
sr=360;%抽样率
[Lo_D,Hi_D,Lo_R,Hi_R]=wfilters(wf);%二进制小波变换
[swa,swd]=swt(f,lev,Lo_D,Hi_D);
%求二进制小波变换的模极大值及其位置
%%初始结果
%dw:局部极大值位置;wp:局部极大序列
dw=zeros(size(swd));
zdw=dw;
fdw=dw;
%要找模极大值,把小波系数中大于0和小于0的分别考虑
%小波系数大于0的赋值给zw
zw=swd.*(swd>0);
%留下左边元素比右边元素小的值的位置记为1,存入zdw中
zdw=((zw(:,1:pp-1)-zw(:,2:pp))<0);
%再计算1,0间隔的点,即找到模极大值的点的位置
zdw(:,2:pp-1)=((zdw(:,1:pp-2)-zdw(:,2:pp-1))>0);
%小波系数小于0的赋值给fw
fw=swd.*(swd<0);
%留下左边元素比右边元素大的值的位置记为1,存入fdw中
fdw=((fw(:,1:pp-1)-fw(:,2:pp))>0);
%再计算1,0间隔的点,即找到模极大值的点的位置
fdw(:,2:pp-1)=((fdw(:,1:pp-2)-fdw(:,2:pp-1))>0);
%将zdw和fdw中的模极大值点位置合并
dw=zdw|fdw;
%保留第一列和最后一列
dw(:,1)=1;
dw(:,pp)=1;
%wp存放模极大值点的值
wp=dw.*swd;
%处理模极大值:从最高层的模极大值点开始
Dwp(:,lev)=wp(lev,:)';
M=max(Dwp(:,lev));
%模极大值的阈值用去噪函数ddencmp来获得
[Thr,sorh,keepapp]=ddencmp('den','wv',f);
C=0.8;%阈值参数
Thr=C*M/lev;%计算阈值
%将大于阈值Thr的最后一层的模极大值留下
Dwp(:,lev)=Dwp(:,lev).*(abs(Dwp(:,lev))>Thr);%处理最后一层
%模极大值的处理方式:
%在尺度j上极大值点位置构造一个搜索区域
%在尺度j-1中,将极大值点落在该区域的点保留,其他的位置0
ep=3;%该参数确定邻域
nL=length(Dwp(:,lev));
for j=1:lev-2
Dwp(:,lev-j)=wp(lev-j,:)';
Dp(:,lev-j+1)=(Dwp(:,lev-j+1)~=0);
DD=Dp(:,lev-j+1);
DDw=DD;
for Pd=1:nL;
if DD(Pd)==1
for i=-ep:ep;
if(Pd-i>=1&Pd-i<=nL)
DDw(Pd-i)=1;
end
end
end
end
Dp(:,lev-j+1)=DDw;
Dwp(:,lev-j)=Dwp(:,lev-j).*Dp(:,lev-j+1);
Dp(:,lev-j)=(Dwp(:,lev-j)~=0);
end
%第一层单独处理,在第二层极大值点位置上,保留第一层相应极大值点
Dwp(:,1)=wp(1,:);
Dwp(:,1)=Dwp(:,1).*Dp(:,2);
wp=Dwp;
wp=wp';
%重构信号
s=swa(lev,:);%s为待重建的信号
%wfr=(wp~=0);%迭代初始化
w0=zeros(1,pp);
[a,d]=swt(w0,lev,Lo_D,Hi_D);%从0开始
w2=d;%重建高频
for j=1:n
w2=Pyg(d,wp,sr);%Py投影和Pgama投影
w0=iswt(s,w2,Lo_R,Hi_R);%Pv投影
[a,d]=swt(w0,lev,Lo_D,Hi_D);
end
s=iswt(swa(lev,:),w2,Lo_R,Hi_R);%计算重建信号
% figure,
% subplot(2,1,1),plot(f,'r');
% grid on;
% title('原始信号');
% subplot(2,1,2),plot(s);
% grid on;
% title('模极值去噪后信号')
end
load sumsin;%输入带噪信号
f=[sumsin zeros(1,24)];%补零使得信号变成2的幂次,这里是信号长度变为1024
lev=4;%模极大值提取时的分解层数
n=20;%模极大值重构信号时的迭代次数
wf='db3';%采用的小波函数
s=mden(f,lev,n,wf);%模极大值去噪算法
%计算PSNR值,MSE值,NC值
P=psnr(f,s);
m=mse(f,s);
% N=nc(f,s);
figure,plot(f,'r');
grid on;
xlabel('t'),ylabel('f(t)');
figure,plot(s);
grid on;
xlabel('t'),ylabel('s(t)');