去年11月发布了一系列有关小波变换和图像处理的文章,把学习小波过程中的心得体会和编写的程序放在网上和大家共享交流。半年来,感谢大家的关注和帮助,在相互的讨论交流中,我不断地从大家提出的问题中拓展自己的知识面,对小波的理论及其应用有了更深入的了解和掌握。根据和大家讨论交流中发现的问题,对博客中的程序进行修正。有关小波图像分解和重构的两篇文章中分享的程序,存在下列问题:
1/2],是固化在 mydwt2.m 的程序中的,不能选择其他的小波函数;
中列变换的矩阵对象为输入矩阵,这是错误的,其矩阵对象应该是行变换后的缓存矩阵;
的输出用[LL,HL,LH,HH]表示,不是很规范,应改为[cA,cV,cH,cD]来表示,即一级小波变换输出的系数矩阵有4个部分:平均部分、垂直细节部分、水平细节部分和对角线细节部分。
相同大小的矩阵,并且已将N级分解后所有的平均、细节系数组合成一体的。实际上,这种定义只对Haar小波有效。
次方整除,主要是为了生成塔式结构图像而设的,对上述问题修正后,这个 modmat 函数已不需使用了。
http://blog.csdn.net/chenyusiyuan/archive/2008/06/05/2513865.aspx
http://blog.csdn.net/chenyusiyuan/archive/2008/06/05/2514119.aspx
上一篇文章中我们实现了小波的一维、二维信号分解与重构,其中的二维信号分解与重构,只要稍作修改,就可以实现图像的分解和重构了。修改的工作,主要是对图像信号进行规范化处理、数据格式转换和绘图细节处理等。
函数实现此功能:
function y=modmat(x,dim)
% 函数 MODMAT()
对输入矩阵x进行规范化,使其行列数均能被 2^dim 整除
% 输入参数:x —— r*c 维矩阵;
%
dim —— 矩阵重构的维数
% 输出参数:y —— rt*ct
维矩阵,mod(rt,2^dim)=0,mod(ct,2^dim)=0
[row,col]=size(x);
% 求出输入矩阵的行列数row,col
rt=row - mod(row,2^dim); %
将row,col分别减去本身模 2^dim 得到的数
ct=col - mod(col,2^dim); %
所得的差为rt、ct,均能被 2^dim 整除
y=x(1:rt,1:ct);
% 输出矩阵 y 为输入矩阵 x 的 rt*ct 维子矩阵
function y=mywavedec2(x,dim)
% 函数 MYWAVEDEC2()
对输入矩阵 x 进行 dim 层分解,得到相应的分解系数矩阵 y
% 输入参数:x —— 输入矩阵;
%
dim —— 分解层数。
% 输出参数:y —— 分解系数矩阵。
x=modmat(x,dim);
% 首先规范化输入矩阵,使其行列数均能被 2^dim 整除
subplot(121);imshow(x);title('原始图像'); %
画出规范化后的源图像
[m,n]=size(x);
% 求出规范化矩阵x的行列数
xd=double(x);
% 将矩阵x的数据格式转换为适合数值处理的double格式
for
i=1:dim
xd=modmat(xd,1);
[dLL,dHL,dLH,dHH]=mydwt2(xd); % 矩阵小波分解
tmp=[dLL,dHL;dLH,dHH]; %
将分解系数存入缓存矩阵
xd=dLL;
% 将缓存矩阵左上角部分的子矩阵作为下一层分解的源矩阵
[row,col]=size(tmp);
% 求出缓存矩阵的行列数
y(1:row,1:col)=tmp;
% 将缓存矩阵存入输出矩阵的相应行列
end
yd=uint8(y);
% 将输出矩阵的数据格式转换为适合显示图像的uint8格式
for
i=1:dim
% 对矩阵 yd 进行分界线处理,画出分解图像的分界线
m=m-mod(m,2);
n=n-mod(n,2);
yd(m/2,1:n)=255;
yd(1:m,n/2)=255;
m=m/2;n=n/2;
end
subplot(122);imshow(yd);title([ num2str(dim) '
维小波分解图像']);
上述的图像分解程序,其输出数据是double格式的,以便作为重构程序的输入。
function
y=mywaverec2(x,dim)
dim——重构层数;
%将输入矩阵的数据格式转换为适合显示图像的uint8格式
i=1:dim
%对转换矩阵xd进行分界线处理
subplot(121);imshow(xd);title([ num2str(dim) '层小波分解图像']); %画出带有分界线的分解图像
%将输入矩阵的数据格式转换回适合数值处理的double格式
i=dim:-1:1 %重构次序是从内层往外层进行,所以先抽取矩阵xr的最内层分解矩阵进行重构
tmp=xr(1:floor(row/2^(i-1)),1:floor(col/2^(i-1)));
%重构的内层矩阵的行列数均为矩阵xr的2^(i-1)
[rt1,ct1]=size(tmp);
%读取待重构矩阵tmp的行列数
rLL=tmp(1:rt/2,1:ct/2);
%将待重构矩阵tmp分解为四个部分
tmp(1:rt,1:ct)=myidwt2(rLL,rHL,rLH,rHH);
%将重构结果返回到矩阵tmp
xr(1:rt1,1:ct1)=tmp; %把矩阵tmp的数据返回到矩阵xr的相应区域,准备下一个外层的重构
%重构结束后得到的矩阵xr即为输出矩阵y
%将矩阵xr的数据格式转换为适合显示图像的uint8格式
类别: 默认分类 查看评论