最近正在学习小波变换分析脑电信号,简单总结一下Haar小波。
一个信号的小波变换,可以分解为这个信号的最粗糙逼近加上各个细节,即AN=A0+W0+W1+…+WN-1;式中,AN为原始信号,A0为AN在最低分辨率下的逼近,W为各个分辨率下的细节部分。
例如,有a=[8,7,6,9]四个数,并使用b[4]数组来保存变换后的结果.
则一级Haar小波变换的结果为:
b[0]=(a[0]+a[1])/2,b[2]=(a[0]-a[1])/2
b[1]=(a[2]+a[3])/2,b[3]=(a[2]-a[3])/2
即依次从数组中取两个数字,计算它们的和以及差,并将和一半和差的一半依次保存在数组的前半部分和后半部分。
例如:有a[8],要进行一维Haar小波变换,结果保存在b[8]中
则一级Haar小波变换的结果为:
b[0]=(a[0]+a[1])/2,b[4]=(a[0]-a[1])/2
b[1]=(a[2]+a[3])/2,b[5]=(a[2]-a[3])/2
b[2]=(a[4]+a[5])/2,b[6]=(a[4-a[5]])/2
b[3]=(a[6]+a[7])/2,b[7]=(a[6]-a[7])/2
Haar小波在MATLAB中的实现(以图像作为输入信号,效果更明显):
%M.m文件
%二维HAAR变换函数
%img:数据
%x:需要进行Haar变换的图像为原图像的几倍,主要用于多级变换
%LL:变换后的最低频
%LH:变换后的中低频
%HH:变换后的高频
%作者:狒狒
%日期:2017.3.5
function im=M(img,x)
[q,w]=size(img);%选取二维信号的长度和宽度
m=q/x;%实际进行变换的图像的长度
n=w/x;%实际进行变换的图像的宽度
for i=1:n/2%构造简单的行Haar小波函数
for j=1:n
if(j==(2*i-1) | j==(2*i))
b(j,i) = 0.5;
else
b(j,i) = 0;
end
end
end
for i=1:n/2
for j=1:n
if(j==(2*i-1))
b(j,i+n/2)=0.5;
end
if(j==(2*i))
b(j,i+n/2)=-0.5;
end
end
end
%对图像进行行变换
L=img(1:m,1:n)*b(:,1:n/2);
H=img(1:m,1:n)*b(:,n/2+1:n);
for i=1:m%构造简单的列Haar小波函数
for j=1:m/2
if(i==(2*j-1) | i==(2*j))
c(j,i) = 0.5;
else
c(j,i) = 0;
end
end
end
for i=1:m
for j=1:m/2
if(i==(2*j-1))
c(j+m/2,i)=0.5;
end
if(i==(2*j))
c(j+m/2,i)=-0.5;
end
end
end
%对图像进行列变换
LL=c(1:m/2,:)*L;
LH=c(m/2+1:m,:)*L;
im=[LL;LH];
im=[im,H];
%若为多级变换,合成最终图像
if(x>1)
im=[im,img(1:m,w-n+1:w)];
e=img((q-m):q,1:w);
im=[im;e];
end
end
h=double(imread('Fig5.07(a).jpg'));%读入图片数据
h1=M(h,1);%Haar二维一阶变换
h2=M(h1,2);%Haar二维二阶变换
subplot(1,2,1);
imshow(uint8(h1));
subplot(1,2,2);
imshow(uint8(h2))
最终效果如图