aspen 发表于 2005-11-23 08:59

[转帖]小波图像分解与合成(例子)

% 该函数是根据对所输入的png格式的真彩图像、小波类型(db9或haar)<BR>% 和相应的阈值进行了三级非标准小波harr或db9的分解和重构,从而达到了对原图像的压缩处理的<BR>% 目的。它首先把通过原图像分离后的某颜色分量作为二维图像矩阵,通过调用自定义的二维离散<BR>% 小波变换函数mydwt2(),并依据指定的小波基函数'wavename'进行二维离散的行、列小波变换,<BR>% 得到了经变换后的相应颜色分量的近似分量% cA,水平细节分量cH,垂直细节分量cV,对角细节<BR>% 分量cD和中间分量cM,然后调用自定义的图像输出函数outrgb分别把中间分量以及cA、cH、cV、<BR>% cD合并后的图像阵进行R、G、B合成输出图像文件,其中某颜色分量的cA又做为下一级二维离散的<BR>% 行、列小波分解的输入图像阵,如此共完成三次。<BR>% 其次,把经过三级非标准小波分解后的各颜色分量的各级水平细节分量、垂直细节分量、对角细<BR>% 节分量矩阵通过调用自定义函数make_0()完成了相应矩阵元素数值小于阀值系数的个数统计,并<BR>% 对它们进行小于阀值系数元素置0处理,且把分量尽数返回,以便三级的非标准小波重构处理。<BR>% 最后,将返回得到的各颜色分量的第三级水平细节分量、垂直细节分量、对角细节分量矩阵和第<BR>% 三级分解后的近似分量作为参数,通过调用自定义的二维离散小波反变换函数myidwt2()进行二维<BR>% 离散的列、行重构,得到了经重构后的近似分量cA 和中间分量cM,把该中间分量cM以及近似分量<BR>% cA分别和经置0处理后第二级cH、cV、cD行列扩展,同时进行R、G、B合成,后调用自定义的图像<BR>% 输出函数outrgb()输出图像文件。其中各颜色分量的cA又做为下一级二维离散的列、行小波重构<BR>% 的输入图像阵,如此共完成三次。最终得到了压缩处理的图像文件。<BR><BR>% 读入图像文件<BR>picchar=strcat(mypic,'.png')<BR>pic=imread(picchar);<BR>pic=double(pic);<BR><BR>% 对原真彩图像进行R、G、B分离<BR>cAr0=pic(:,:,1);cAg0=pic(:,:,2);cAb0=pic(:,:,3);<BR><BR>% 第1级非标准分解<BR> = mydwt2(cAr0,wavename);<BR> = mydwt2(cAg0,wavename);<BR> = mydwt2(cAb0,wavename);<BR><BR>% 输出经第1级非标准分解后的图像文件<BR>outrgb(cMr1,cMg1,cMb1,wavename,threshold,'_1_row');<BR>outrgb(merge(cAr1,cHr1,cVr1,cDr1),merge(cAg1,cHg1,cVg1,cDg1),merge(cAb1,cHb1,...<BR>    cVb1,cDb1),wavename,threshold,'_1_col');<BR><BR>% 第2级非标准分解<BR> = mydwt2(cAr1,wavename);<BR> = mydwt2(cAg1,wavename);<BR> = mydwt2(cAb1,wavename);<BR>% 输出经第2级非标准分解后的图像文件<BR>outrgb(merge(cMr2,cHr1,cVr1,cDr1),merge(cMg2,cHg1,cVg1,cDg1),merge(cMb2,cHb1,...<BR>    cVb1,cDb1),wavename,threshold,'_2_row');<BR>outrgb(merge(merge(cAr2,cHr2,cVr2,cDr2),cHr1,cVr1,cDr1),merge(merge(cAg2,cHg2,...<BR>    cVg2,cDg2),cHg1,cVg1,cDg1),merge(merge(cAb2,cHb2,cVb2,cDb2),cHb1,cVb1,cDb1...<BR>    ),wavename,threshold,'_2_col');<BR><BR>% 第3级非标准分解<BR> = mydwt2(cAr2,wavename);<BR> = mydwt2(cAg2,wavename);<BR> = mydwt2(cAb2,wavename);<BR><BR>% 输出经第2级非标准分解后的图像文件<BR>outrgb(merge(merge(cMr3,cHr2,cVr2,cDr2),cHr1,cVr1,cDr1),merge(merge(cMg3,cHg2,...<BR>    cVg2,cDg2),cHg1,cVg1,cDg1),merge(merge(cMb3,cHb2,cVb2,cDb2),cHb1,cVb1,cDb1...<BR>    ),wavename,threshold,'_3_row');<BR>outrgb(merge(merge(merge(cAr3,cHr3,cVr3,cDr3),cHr2,cVr2,cDr2),cHr1,cVr1,cDr1),...<BR>    merge(merge(merge(cAg3,cHg3,cVg3,cDg3),cHg2,cVg2,cDg2),cHg1,cVg1,cDg1),...<BR>    merge(merge(merge(cAb3,cHb3,cVb3,cDb3),cHb2,cVb2,cDb2),cHb1,cVb1,cDb1),...<BR>wavename,threshold,'_3_col');<BR><BR>% 统计经过三级非标准小波分解后的各颜色分量的各级水平细节分量、垂直细节分量、对<BR>% 角细节分量的相应矩阵元素数值小于阀值系数的个数,并对它们进行小于阀值系数元素<BR>% 置0处理。<BR>zeronum=0;<BR>=make_0(cHr3,cVr3,cDr3,...<BR>    cHr2,cVr2,cDr2,cHr1,cVr1,cDr1,threshold);<BR>zeronum=zeronum+num_0;<BR>=make_0(cHg3,cVg3,cDg3,...<BR>    cHg2,cVg2,cDg2,cHg1,cVg1,cDg1,threshold);<BR>zeronum=zeronum+num_0;<BR>=make_0(cHb3,cVb3,cDb3,...<BR>    cHb2,cVb2,cDb2,cHb1,cVb1,cDb1,threshold);<BR>zeronum=zeronum+num_0;<BR>% 把0的总数写入文本文件<BR>zerotxt=strcat(wavename,'_',threshold,'_','zero','.txt')<BR>csvwrite(zerotxt,zeronum);<BR><BR>% 第1级非标准重构<BR> = myidwt2(cAr3,cHr3,cVr3,cDr3,wavename);<BR> = myidwt2(cAg3,cHg3,cVg3,cDg3,wavename);<BR> = myidwt2(cAb3,cHb3,cVb3,cDb3,wavename);<BR><BR>% 输出经第1级非标准重构后的图像文件<BR>outrgb(merge(merge(cMr3,cHr2,cVr2,cDr2),cHr1,cVr1,cDr1),merge(merge(cMg3,cHg2,...<BR>    cVg2,cDg2),cHg1,cVg1,cDg1),merge(merge(cMb3,cHb2,cVb2,cDb2),cHb1,cVb1,cDb1...<BR>    ),wavename,threshold,'_1_icol');<BR>outrgb(merge(merge(cAr2,cHr2,cVr2,cDr2),cHr1,cVr1,cDr1),merge(merge(cAg2,cHg2,...<BR>    cVg2,cDg2),cHg1,cVg1,cDg1),merge(merge(cAb2,cHb2,cVb2,cDb2),cHb1,cVb1,cDb1...<BR>    ),wavename,threshold,'_1_irow')<BR><BR>% 第2级非标准重构<BR> = myidwt2(cAr2,cHr2,cVr2,cDr2,wavename);<BR> = myidwt2(cAg2,cHg2,cVg2,cDg2,wavename);<BR> = myidwt2(cAb2,cHb2,cVb2,cDb2,wavename);<BR><BR>% 输出经第2级非标准重构后的图像文件<BR>outrgb(merge(cMr2,cHr1,cVr1,cDr1),merge(cMg2,cHg1,cVg1,cDg1),merge(cMb2,cHb1,...<BR>    cVb1,cDb1),wavename,threshold,'_2_icol');<BR>outrgb(merge(cAr1,cHr1,cVr1,cDr1),merge(cAg1,cHg1,cVg1,cDg1),merge(cAb1,cHb1,...<BR>    cVb1,cDb1),wavename,threshold,'_2_irow');<BR><BR>% 第3级非标准重构<BR> = myidwt2(cAr1,cHr1,cVr1,cDr1,wavename);<BR> = myidwt2(cAg1,cHg1,cVg1,cDg1,wavename);<BR> = myidwt2(cAb1,cHb1,cVb1,cDb1,wavename);<BR><BR>% 输出经第3级非标准重构后的图像文件,即最终图像文件<BR>outrgb(cMr1,cMg1,cMb1,wavename,threshold,'_3_icol');<BR>outrgb(cAr0,cAg0,cAb0,wavename,threshold,'_result');<BR>
<br> %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%<BR>function =mydwt2(mypic_RGB,wavename)<BR>%此函数是利用MATLAB工具箱提供的一维离散小波变换函数dwt()对传递进来的图像矩阵mypic_RGB<BR>% 进行相应的小波类型分解处理,其中参数wavename是小波类型。它借助于使用了指定的小波基函<BR>% 数'wavename' 的dwt()首先对图像矩阵进行行分解,而后进行列分解。生成了近似分量cA,水平<BR>% 细节分量cH,垂直细节分量cV,对角细节分量cD和中间分量cM<BR><BR>% 变量初始化<BR>cA=[];cH=[];cV=[];cD=[];cM=[];cAm=[];cDm=[];<BR><BR>% 进行逐行行分解变换<BR>% cA1,cD1为临时近似,细节分量,把两分量进行列数扩展合成为中间分量矩阵以便输出<BR>x=size(mypic_RGB);<BR>for i=1:x(1)<BR>=dwt(mypic_RGB(i,:),wavename);<BR>cAm=;cDm=;<BR>end<BR>cM=;<BR><BR>% 对两临时分量进行逐列列分解变换,最后生成近似分量cA,水平细节分量cH,垂直细节分量cV,对<BR>% 角细节分量cD<BR>cAm=cAm';cDm=cDm';<BR>x=size(cAm);<BR>for i=1:x(1)<BR>=dwt(cAm(i,:),wavename);<BR>cA=;cV=;<BR>end<BR>x=size(cDm);<BR>for i=1:x(1)<BR>=dwt(cDm(i,:),wavename);<BR>cH=;cD=;<BR>end<BR>% 转置矩阵<BR>cA=cA';cH=cH';cV=cV';cD=cD';<BR>
<p><BR> %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%<BR>function =myidwt2(cA,cH,cV,cD,wavename)<BR>% 此函数实现了二维离散小波反变换,即重构。它是利用MATLAB工具箱所提供的一维离散小波反变<BR>% 换函数idwt()对传递进来的近似分量cA、水平细节分量cH、垂直细节分量cV和对角细节分量cD进<BR>% 行相应的小波类型重构处理,其中参数wavename是小波类型。它借助于使用了指定的小波基函数<BR>% 'wavename'的idwt()首先对四个分量矩阵进行列反变换,而后行反变换。重构出中间过程图像矩<BR>% 阵cM和原始图像矩阵mypic_RGB。<BR><BR>cA1=[];cD1=[];<BR><BR>% 进行逐列列重构变换,得到过程矩阵cA1、cD1,再对它们列数扩展合成为中间图阵cM<BR>cA=cA';cH=cH';cV=cV';cD=cD';<BR>mypic_RGB=[];<BR>x=size(cA);<BR>for i=1:x(1)<BR>temp=idwt(cA(i,:),cV(i,:),wavename);<BR>cA1=;<BR>end<BR>x=size(cH);<BR>for i=1:x(1)<BR>temp=idwt(cH(i,:),cD(i,:),wavename);<BR>cD1=;<BR>end<BR><BR>cA1=cA1';<BR>cD1=cD1';<BR>cM=;<BR>% 对上述得到的分量cA1、cD1作为过程细节分量进行逐行行重构变换,得到图像矩阵mypic_RGB<BR>x=size(cA1);<BR>for i=1:x(1)<BR>temp=idwt(cA1(i,:),cD1(i,:),wavename);<BR>mypic_RGB=;<BR>end<BR><BR><BR> %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%<BR>function []=outrgb(pic_R,pic_G,pic_B,wavename,threshold,level)<BR>% 该函数确定了图像在各像素位置上的红、绿、蓝的强度值组合。实现了R、G、B各分量组合后所<BR>% 成的真彩图像的文件输出<BR>temp=size(pic_R);<BR>pic=zeros(temp(1),temp(2),3);<BR>for i=1:temp(1);<BR>for j=1:temp(2);<BR>pic(i,j,1)=pic_R(i,j);<BR>pic(i,j,2)=pic_G(i,j);<BR>pic(i,j,3)=pic_B(i,j);<BR>end<BR>end<BR><BR>%输出RGB图像,即真彩图像。<BR>imwrite(pic/255,strcat('pic','_',wavename,'_',threshold,level,'.png'));<BR><BR>
<p> %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%<BR>function ...<BR>            =make_0(cH3,cV3,cD3,cH2,cV2,cD2,cH1,cV1,cD1,threshold)<BR>% 该函数功能是本课程役计的关键,它完成了对经过三级非标准分解后各分量图矩阵中所有元素数<BR>% 值小于阀值的进行置0处理,为后面进行三级非标准重构原始图像从而实现图像压缩奠定了基础。<BR>% 输入经过非标准分解后颜色分量的各级的水平细节分量、垂直细节分量、对角细节分量和阀值<BR>% threshold其中数字表示非标准处理的级别。输出各分量图矩阵中所有元素数值小于阀值系数置<BR>% 0处理后所对应的各级的水平细节分量、垂直细节分量、对角细节分% 量,并统计它们系数为0个<BR>% 数count。<BR>threshold_num=str2num(threshold);<BR>count=0;<BR><BR>% 借助临时分量对第三级非标准分解的水平细节分量、垂直细节分量、对角细节分量进行行、列数<BR>% 扩展合成cM_matrix3,并对数值小于阀值系数进行置0处理,并统计矩阵元素数值小于阀值系数的<BR>% 个数。<BR>cM_cA3=cD3<BR>cM_cA3=zeros(size(cM_cA3,1),size(cM_cA3,2));<BR>num=size(cM_cA3,1)*size(cM_cA3,2);<BR>cM_matrix3=;<BR>cM_size=size(cM_matrix3);<BR>for i=1:cM_size(1)<BR>for j=1:cM_size(2)<BR>if abs(cM_matrix3(i,j))&lt;=threshold_num<BR>count=count+1;<BR>cM_matrix3(i,j)=0;<BR>end<BR>end<BR>end<BR>% 对所合成的cM_matrix3重新分离出置0处理后的水平细节分量、垂直细节分量和对角细节分量,并<BR>% 精确了矩阵元素数值小于阀值系数的数目。<BR>cH3=cM_matrix3;cV3=cM_matrix3;cD3=cM_matrix3;<BR>cH3(1+size(cM_cA3,1):2*size(cM_cA3,1),:)=[];cH3(:,1:size(cM_cA3,2))=[];<BR>cV3(1:size(cM_cA3,1),:)=[];cV3(:,1+size(cM_cA3,2):2*size(cM_cA3,2))=[];<BR>cD3(1:size(cM_cA3,1),:)=[];cD3(:,1:size(cM_cA3,2))=[];<BR>count=count-num;<BR><BR>% 借助临时分量对第二级非标准分解的水平细节分量、垂直细节分量、对角细节分量进行行、列数<BR>% 扩展合成cM_matrix2,并对数值小于阀值系数进行置0处理,并统计矩阵元素数值小于阀值系数的 % 个数。<BR>cM_cA2=cD2<BR>cM_cA2=zeros(size(cM_cA2,1),size(cM_cA2,2));<BR>num=size(cM_cA2,1)*size(cM_cA2,2);<BR>cM_matrix2=;<BR>cM_size=size(cM_matrix2);<BR>for i=1:cM_size(1)<BR>for j=1:cM_size(2)<BR>if abs(cM_matrix2(i,j))&lt;=threshold_num<BR>count=count+1;<BR>cM_matrix2(i,j)=0;<BR>end<BR>end<BR>end<BR>% 对所合成的cM_matrix2重新分离出置0处理后的水平细节分量、垂直细节分量和对角细节分量,并<BR>% 精确了矩阵元素数值小于阀值系数的数目。<BR>cH2=cM_matrix2;cV2=cM_matrix2;cD2=cM_matrix2;<BR>cH2(1+size(cM_cA2,1):2*size(cM_cA2,1),:)=[];cH2(:,1:size(cM_cA2,2))=[];<BR>cV2(1:size(cM_cA2,1),:)=[];cV2(:,1+size(cM_cA2,2):2*size(cM_cA2,2))=[];<BR>cD2(1:size(cM_cA2,1),:)=[];cD2(:,1:size(cM_cA2,2))=[];<BR>count=count-num;<BR><BR>% 借助临时分量对第一级非标准分解的水平细节分量、垂直细节分量、对角细节分量进行行、列数<BR>% 扩展合成cM_matrix1,并对数值小于阀值系数的元素进行置0处理,且统计矩阵元素数值小于阀值<BR>% 系数的个数。<BR>cM_cA1=cD1<BR>cM_cA1=zeros(size(cM_cA1,1),size(cM_cA1,2));<BR>num=size(cM_cA1,1)*size(cM_cA1,2);<BR>cM_matrix1=;<BR>cM_size=size(cM_matrix1);<BR>for i=1:cM_size(1)<BR>for j=1:cM_size(2)<BR>if abs(cM_matrix1(i,j))&lt;=threshold_num<BR>count=count+1;<BR>cM_matrix1(i,j)=0;<BR>end<BR>end<BR>end<BR>% 对所合成的cM_matrix1重新分离出置0处理后的水平细节分量、垂直细节分量和对角细节分量,并<BR>% 精确了矩阵元素数值小于阀值系数的数目。<BR>cH1=cM_matrix1;cV1=cM_matrix1;cD1=cM_matrix1;<BR>cH1(1+size(cM_cA1,1):2*size(cM_cA1,1),:)=[];cH1(:,1:size(cM_cA1,2))=[];<BR>cV1(1:size(cM_cA1,1),:)=[];cV1(:,1+size(cM_cA1,2):2*size(cM_cA1,2))=[];<BR>cD1(1:size(cM_cA1,1),:)=[];cD1(:,1:size(cM_cA1,2))=[];<BR>count=count-num;<BR><BR>
<p> 
<p> %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%<BR>function pic=merge(cA,cH,cV,cD)<BR>% 该函数实现了对传入的四个参数矩阵cA,cH,cV,cD合并,其中cA,cH,cV,cD分别代表左上角、右上<BR>% 角、左下角、右下角矩阵,合并结果为输出矩阵pic<BR><BR>% 取得四个参数矩阵行、列两维的最大分别值row_max和col_max<BR>temp1=size(cA);temp2=size(cH);temp3=size(cV);temp4=size(cD);<BR>row_max=max();<BR>col_max=max();<BR>% pic=zeros(2*row_max,2*col_max);<BR>% 与最大分别值row_max和col_max比较,对左上角矩阵扩展置0<BR>if temp1(1)&lt;row_max|temp1(2)&lt;col_max<BR>cA(row_max,col_max)=0;<BR>end<BR>% 与最大分别值row_max和col_max比较,对右上角矩阵扩展置0<BR>if temp2(1)&lt;row_max|temp2(2)&lt;col_max<BR>cH(row_max,col_max)=0;<BR>end<BR>% 与最大分别值row_max和col_max比较,对左下角矩阵扩展置0<BR>if temp3(1)&lt;row_max|temp3(2)&lt;col_max<BR>cV(row_max,col_max)=0;<BR>end<BR>% 与最大分别值row_max和col_max比较,对右下角矩阵扩展置0<BR>if temp4(1)&lt;row_max|temp4(2)&lt;col_max<BR>cD(row_max,col_max)=0;<BR>end<BR>% 合并左上角、右上角、左下角、右下角矩阵生成输出pic矩阵<BR>pic=;

yxn2000 发表于 2006-4-19 20:28

xiexie校长

mingmingtree 发表于 2012-4-9 09:23

好长,眼睛都看花了!
不过还是谢谢分享!!

ChaChing 发表于 2012-6-8 00:58

mingmingtree 发表于 2012-4-9 09:23 static/image/common/back.gif
好长,眼睛都看花了!
不过还是谢谢分享!!

% 该函数是根据对所输入的png格式的真彩图像、小波类型(db9或haar)
% 和相应的阈值进行了三级非标准小波harr或db9的分解和重构,从而达到了对原图像的压缩处理的
% 目的。它首先把通过原图像分离后的某颜色分量作为二维图像矩阵,通过调用自定义的二维离散
% 小波变换函数mydwt2(),并依据指定的小波基函数'wavename'进行二维离散的行、列小波变换,
% 得到了经变换后的相应颜色分量的近似分量% cA,水平细节分量cH,垂直细节分量cV,对角细节
% 分量cD和中间分量cM,然后调用自定义的图像输出函数outrgb分别把中间分量以及cA、cH、cV、
% cD合并后的图像阵进行R、G、B合成输出图像文件,其中某颜色分量的cA又做为下一级二维离散的
% 行、列小波分解的输入图像阵,如此共完成三次。
% 其次,把经过三级非标准小波分解后的各颜色分量的各级水平细节分量、垂直细节分量、对角细
% 节分量矩阵通过调用自定义函数make_0()完成了相应矩阵元素数值小于阀值系数的个数统计,并
% 对它们进行小于阀值系数元素置0处理,且把分量尽数返回,以便三级的非标准小波重构处理。
% 最后,将返回得到的各颜色分量的第三级水平细节分量、垂直细节分量、对角细节分量矩阵和第
% 三级分解后的近似分量作为参数,通过调用自定义的二维离散小波反变换函数myidwt2()进行二维
% 离散的列、行重构,得到了经重构后的近似分量cA 和中间分量cM,把该中间分量cM以及近似分量
% cA分别和经置0处理后第二级cH、cV、cD行列扩展,同时进行R、G、B合成,后调用自定义的图像
% 输出函数outrgb()输出图像文件。其中各颜色分量的cA又做为下一级二维离散的列、行小波重构
% 的输入图像阵,如此共完成三次。最终得到了压缩处理的图像文件。

% 读入图像文件
picchar=strcat(mypic,'.png')
pic=imread(picchar);
pic=double(pic);

% 对原真彩图像进行R、G、B分离
cAr0=pic(:,:,1);cAg0=pic(:,:,2);cAb0=pic(:,:,3);

% 第1级非标准分解
= mydwt2(cAr0,wavename);
= mydwt2(cAg0,wavename);
= mydwt2(cAb0,wavename);

% 输出经第1级非标准分解后的图像文件
outrgb(cMr1,cMg1,cMb1,wavename,threshold,'_1_row');
outrgb(merge(cAr1,cHr1,cVr1,cDr1),merge(cAg1,cHg1,cVg1,cDg1),merge(cAb1,cHb1,...
cVb1,cDb1),wavename,threshold,'_1_col');

% 第2级非标准分解
= mydwt2(cAr1,wavename);
= mydwt2(cAg1,wavename);
= mydwt2(cAb1,wavename);
% 输出经第2级非标准分解后的图像文件
outrgb(merge(cMr2,cHr1,cVr1,cDr1),merge(cMg2,cHg1,cVg1,cDg1),merge(cMb2,cHb1,...
cVb1,cDb1),wavename,threshold,'_2_row');
outrgb(merge(merge(cAr2,cHr2,cVr2,cDr2),cHr1,cVr1,cDr1),merge(merge(cAg2,cHg2,...
cVg2,cDg2),cHg1,cVg1,cDg1),merge(merge(cAb2,cHb2,cVb2,cDb2),cHb1,cVb1,cDb1...
),wavename,threshold,'_2_col');

% 第3级非标准分解
= mydwt2(cAr2,wavename);
= mydwt2(cAg2,wavename);
= mydwt2(cAb2,wavename);

% 输出经第2级非标准分解后的图像文件
outrgb(merge(merge(cMr3,cHr2,cVr2,cDr2),cHr1,cVr1,cDr1),merge(merge(cMg3,cHg2,...
cVg2,cDg2),cHg1,cVg1,cDg1),merge(merge(cMb3,cHb2,cVb2,cDb2),cHb1,cVb1,cDb1...
),wavename,threshold,'_3_row');
outrgb(merge(merge(merge(cAr3,cHr3,cVr3,cDr3),cHr2,cVr2,cDr2),cHr1,cVr1,cDr1),...
merge(merge(merge(cAg3,cHg3,cVg3,cDg3),cHg2,cVg2,cDg2),cHg1,cVg1,cDg1),...
merge(merge(merge(cAb3,cHb3,cVb3,cDb3),cHb2,cVb2,cDb2),cHb1,cVb1,cDb1),...
wavename,threshold,'_3_col');

% 统计经过三级非标准小波分解后的各颜色分量的各级水平细节分量、垂直细节分量、对
% 角细节分量的相应矩阵元素数值小于阀值系数的个数,并对它们进行小于阀值系数元素
% 置0处理。
zeronum=0;
=make_0(cHr3,cVr3,cDr3,...
cHr2,cVr2,cDr2,cHr1,cVr1,cDr1,threshold);
zeronum=zeronum+num_0;
=make_0(cHg3,cVg3,cDg3,...
cHg2,cVg2,cDg2,cHg1,cVg1,cDg1,threshold);
zeronum=zeronum+num_0;
=make_0(cHb3,cVb3,cDb3,...
cHb2,cVb2,cDb2,cHb1,cVb1,cDb1,threshold);
zeronum=zeronum+num_0;
% 把0的总数写入文本文件
zerotxt=strcat(wavename,'_',threshold,'_','zero','.txt')
csvwrite(zerotxt,zeronum);

% 第1级非标准重构
= myidwt2(cAr3,cHr3,cVr3,cDr3,wavename);
= myidwt2(cAg3,cHg3,cVg3,cDg3,wavename);
= myidwt2(cAb3,cHb3,cVb3,cDb3,wavename);

% 输出经第1级非标准重构后的图像文件
outrgb(merge(merge(cMr3,cHr2,cVr2,cDr2),cHr1,cVr1,cDr1),merge(merge(cMg3,cHg2,...
cVg2,cDg2),cHg1,cVg1,cDg1),merge(merge(cMb3,cHb2,cVb2,cDb2),cHb1,cVb1,cDb1...
),wavename,threshold,'_1_icol');
outrgb(merge(merge(cAr2,cHr2,cVr2,cDr2),cHr1,cVr1,cDr1),merge(merge(cAg2,cHg2,...
cVg2,cDg2),cHg1,cVg1,cDg1),merge(merge(cAb2,cHb2,cVb2,cDb2),cHb1,cVb1,cDb1...
),wavename,threshold,'_1_irow')

% 第2级非标准重构
= myidwt2(cAr2,cHr2,cVr2,cDr2,wavename);
= myidwt2(cAg2,cHg2,cVg2,cDg2,wavename);
= myidwt2(cAb2,cHb2,cVb2,cDb2,wavename);

% 输出经第2级非标准重构后的图像文件
outrgb(merge(cMr2,cHr1,cVr1,cDr1),merge(cMg2,cHg1,cVg1,cDg1),merge(cMb2,cHb1,...
cVb1,cDb1),wavename,threshold,'_2_icol');
outrgb(merge(cAr1,cHr1,cVr1,cDr1),merge(cAg1,cHg1,cVg1,cDg1),merge(cAb1,cHb1,...
cVb1,cDb1),wavename,threshold,'_2_irow');

% 第3级非标准重构
= myidwt2(cAr1,cHr1,cVr1,cDr1,wavename);
= myidwt2(cAg1,cHg1,cVg1,cDg1,wavename);
= myidwt2(cAb1,cHb1,cVb1,cDb1,wavename);

% 输出经第3级非标准重构后的图像文件,即最终图像文件
outrgb(cMr1,cMg1,cMb1,wavename,threshold,'_3_icol');
outrgb(cAr0,cAg0,cAb0,wavename,threshold,'_result');

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function =mydwt2(mypic_RGB,wavename)
%此函数是利用MATLAB工具箱提供的一维离散小波变换函数dwt()对传递进来的图像矩阵mypic_RGB
% 进行相应的小波类型分解处理,其中参数wavename是小波类型。它借助于使用了指定的小波基函
% 数'wavename' 的dwt()首先对图像矩阵进行行分解,而后进行列分解。生成了近似分量cA,水平
% 细节分量cH,垂直细节分量cV,对角细节分量cD和中间分量cM

% 变量初始化
cA=[];cH=[];cV=[];cD=[];cM=[];cAm=[];cDm=[];

% 进行逐行行分解变换
% cA1,cD1为临时近似,细节分量,把两分量进行列数扩展合成为中间分量矩阵以便输出
x=size(mypic_RGB);
for i=1:x(1)
=dwt(mypic_RGB(i,:),wavename);
cAm=;cDm=;
end
cM=;

% 对两临时分量进行逐列列分解变换,最后生成近似分量cA,水平细节分量cH,垂直细节分量cV,对
% 角细节分量cD
cAm=cAm';cDm=cDm';
x=size(cAm);
for i=1:x(1)
=dwt(cAm(i,:),wavename);
cA=;cV=;
end
x=size(cDm);
for i=1:x(1)
=dwt(cDm(i,:),wavename);
cH=;cD=;
end
% 转置矩阵
cA=cA';cH=cH';cV=cV';cD=cD';


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function =myidwt2(cA,cH,cV,cD,wavename)
% 此函数实现了二维离散小波反变换,即重构。它是利用MATLAB工具箱所提供的一维离散小波反变
% 换函数idwt()对传递进来的近似分量cA、水平细节分量cH、垂直细节分量cV和对角细节分量cD进
% 行相应的小波类型重构处理,其中参数wavename是小波类型。它借助于使用了指定的小波基函数
% 'wavename'的idwt()首先对四个分量矩阵进行列反变换,而后行反变换。重构出中间过程图像矩
% 阵cM和原始图像矩阵mypic_RGB。

cA1=[];cD1=[];

% 进行逐列列重构变换,得到过程矩阵cA1、cD1,再对它们列数扩展合成为中间图阵cM
cA=cA';cH=cH';cV=cV';cD=cD';
mypic_RGB=[];
x=size(cA);
for i=1:x(1)
temp=idwt(cA(i,:),cV(i,:),wavename);
cA1=;
end
x=size(cH);
for i=1:x(1)
temp=idwt(cH(i,:),cD(i,:),wavename);
cD1=;
end

cA1=cA1';
cD1=cD1';
cM=;
% 对上述得到的分量cA1、cD1作为过程细节分量进行逐行行重构变换,得到图像矩阵mypic_RGB
x=size(cA1);
for i=1:x(1)
temp=idwt(cA1(i,:),cD1(i,:),wavename);
mypic_RGB=;
end


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function []=outrgb(pic_R,pic_G,pic_B,wavename,threshold,level)
% 该函数确定了图像在各像素位置上的红、绿、蓝的强度值组合。实现了R、G、B各分量组合后所
% 成的真彩图像的文件输出
temp=size(pic_R);
pic=zeros(temp(1),temp(2),3);
for i=1:temp(1);
for j=1:temp(2);
pic(i,j,1)=pic_R(i,j);
pic(i,j,2)=pic_G(i,j);
pic(i,j,3)=pic_B(i,j);
end
end

%输出RGB图像,即真彩图像。
imwrite(pic/255,strcat('pic','_',wavename,'_',threshold,level,'.png'));



%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function ...
=make_0(cH3,cV3,cD3,cH2,cV2,cD2,cH1,cV1,cD1,threshold)
% 该函数功能是本课程役计的关键,它完成了对经过三级非标准分解后各分量图矩阵中所有元素数
% 值小于阀值的进行置0处理,为后面进行三级非标准重构原始图像从而实现图像压缩奠定了基础。
% 输入经过非标准分解后颜色分量的各级的水平细节分量、垂直细节分量、对角细节分量和阀值
% threshold其中数字表示非标准处理的级别。输出各分量图矩阵中所有元素数值小于阀值系数置
% 0处理后所对应的各级的水平细节分量、垂直细节分量、对角细节分% 量,并统计它们系数为0个
% 数count。
threshold_num=str2num(threshold);
count=0;

% 借助临时分量对第三级非标准分解的水平细节分量、垂直细节分量、对角细节分量进行行、列数
% 扩展合成cM_matrix3,并对数值小于阀值系数进行置0处理,并统计矩阵元素数值小于阀值系数的
% 个数。
cM_cA3=cD3
cM_cA3=zeros(size(cM_cA3,1),size(cM_cA3,2));
num=size(cM_cA3,1)*size(cM_cA3,2);
cM_matrix3=;
cM_size=size(cM_matrix3);
for i=1:cM_size(1)
for j=1:cM_size(2)
if abs(cM_matrix3(i,j))<=threshold_num
count=count+1;
cM_matrix3(i,j)=0;
end
end
end
% 对所合成的cM_matrix3重新分离出置0处理后的水平细节分量、垂直细节分量和对角细节分量,并
% 精确了矩阵元素数值小于阀值系数的数目。
cH3=cM_matrix3;cV3=cM_matrix3;cD3=cM_matrix3;
cH3(1+size(cM_cA3,1):2*size(cM_cA3,1),:)=[];cH3(:,1:size(cM_cA3,2))=[];
cV3(1:size(cM_cA3,1),:)=[];cV3(:,1+size(cM_cA3,2):2*size(cM_cA3,2))=[];
cD3(1:size(cM_cA3,1),:)=[];cD3(:,1:size(cM_cA3,2))=[];
count=count-num;

% 借助临时分量对第二级非标准分解的水平细节分量、垂直细节分量、对角细节分量进行行、列数
% 扩展合成cM_matrix2,并对数值小于阀值系数进行置0处理,并统计矩阵元素数值小于阀值系数的 % 个数。
cM_cA2=cD2
cM_cA2=zeros(size(cM_cA2,1),size(cM_cA2,2));
num=size(cM_cA2,1)*size(cM_cA2,2);
cM_matrix2=;
cM_size=size(cM_matrix2);
for i=1:cM_size(1)
for j=1:cM_size(2)
if abs(cM_matrix2(i,j))<=threshold_num
count=count+1;
cM_matrix2(i,j)=0;
end
end
end
% 对所合成的cM_matrix2重新分离出置0处理后的水平细节分量、垂直细节分量和对角细节分量,并
% 精确了矩阵元素数值小于阀值系数的数目。
cH2=cM_matrix2;cV2=cM_matrix2;cD2=cM_matrix2;
cH2(1+size(cM_cA2,1):2*size(cM_cA2,1),:)=[];cH2(:,1:size(cM_cA2,2))=[];
cV2(1:size(cM_cA2,1),:)=[];cV2(:,1+size(cM_cA2,2):2*size(cM_cA2,2))=[];
cD2(1:size(cM_cA2,1),:)=[];cD2(:,1:size(cM_cA2,2))=[];
count=count-num;

% 借助临时分量对第一级非标准分解的水平细节分量、垂直细节分量、对角细节分量进行行、列数
% 扩展合成cM_matrix1,并对数值小于阀值系数的元素进行置0处理,且统计矩阵元素数值小于阀值
% 系数的个数。
cM_cA1=cD1
cM_cA1=zeros(size(cM_cA1,1),size(cM_cA1,2));
num=size(cM_cA1,1)*size(cM_cA1,2);
cM_matrix1=;
cM_size=size(cM_matrix1);
for i=1:cM_size(1)
for j=1:cM_size(2)
if abs(cM_matrix1(i,j))<=threshold_num
count=count+1;
cM_matrix1(i,j)=0;
end
end
end
% 对所合成的cM_matrix1重新分离出置0处理后的水平细节分量、垂直细节分量和对角细节分量,并
% 精确了矩阵元素数值小于阀值系数的数目。
cH1=cM_matrix1;cV1=cM_matrix1;cD1=cM_matrix1;
cH1(1+size(cM_cA1,1):2*size(cM_cA1,1),:)=[];cH1(:,1:size(cM_cA1,2))=[];
cV1(1:size(cM_cA1,1),:)=[];cV1(:,1+size(cM_cA1,2):2*size(cM_cA1,2))=[];
cD1(1:size(cM_cA1,1),:)=[];cD1(:,1:size(cM_cA1,2))=[];
count=count-num;



 

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function pic=merge(cA,cH,cV,cD)
% 该函数实现了对传入的四个参数矩阵cA,cH,cV,cD合并,其中cA,cH,cV,cD分别代表左上角、右上
% 角、左下角、右下角矩阵,合并结果为输出矩阵pic

% 取得四个参数矩阵行、列两维的最大分别值row_max和col_max
temp1=size(cA);temp2=size(cH);temp3=size(cV);temp4=size(cD);
row_max=max();
col_max=max();
% pic=zeros(2*row_max,2*col_max);
% 与最大分别值row_max和col_max比较,对左上角矩阵扩展置0
if temp1(1)<row_max|temp1(2)<col_max
cA(row_max,col_max)=0;
end
% 与最大分别值row_max和col_max比较,对右上角矩阵扩展置0
if temp2(1)<row_max|temp2(2)<col_max
cH(row_max,col_max)=0;
end
% 与最大分别值row_max和col_max比较,对左下角矩阵扩展置0
if temp3(1)<row_max|temp3(2)<col_max
cV(row_max,col_max)=0;
end
% 与最大分别值row_max和col_max比较,对右下角矩阵扩展置0
if temp4(1)<row_max|temp4(2)<col_max
cD(row_max,col_max)=0;
end
% 合并左上角、右上角、左下角、右下角矩阵生成输出pic矩阵
pic=;
页: [1]
查看完整版本: [转帖]小波图像分解与合成(例子)