《实验四 DCT变换HUFFman编码图像压缩.doc》由会员分享,可在线阅读,更多相关《实验四 DCT变换HUFFman编码图像压缩.doc(8页珍藏版)》请在三一办公上搜索。
1、实验四 图像压缩姓名: 学号: 邮箱: 一、 实验目的1. 掌握DCT变换的原理2. 了解DCT变化在图像压缩中的应用3. 掌握图像压缩的基本原理及方法4. 了解霍夫曼编码原理5. 熟悉图像压缩的MATLAB编程二、 实验原理DCT是目前比较好的图像变换,它有很多优点。DCT是正交变换,它可以将8x8图像空间表达式转换为频率域,只需要用少量的数据点表示图像;DCT产生的系数很容易被量化,因此能获得好的块压缩;DCT算法的性能很好,它有快速算法,如采用快速傅立叶变换可以进行高效的运算,因此它在硬件和软件中都容易实现;而且DCT算法是对称的,所以利用逆DCT算法可以用来解压缩图像。由于DCT主要应
2、用在数据和图像的压缩,因此希望原信号的能量在变换后能尽量集中在少数系数上,且这些大能量的系数能处在相对集中的位置,这将有利于进一步的量化和编码。但是如果对整段的数据或整幅图像来做DCT,那就很难保证大能量的系数能处在相对集中的位置。因此,在实际应用中,一般都是将数据分成一段一段来做,一般分成8x8或16x16的方块来做。二维DCT正交变换的公式为:二维DCT逆变换公式: 其中 三、 实验要求利用DCT变换对图像进行压缩,对比不同压缩比下的结果,对比不同压缩比下图像大小的变化。压缩过程如下图所示:DCT变换量化huffman编码四、 实验过程与结果 实验程序如下:(先给出主程序,然后给出各功能子
3、函数的程序) 主程序:clearload(lena.mat)%调入170*170大小的一幅彩色lena图像 l=imresize(lena,256 256);%将图像变换为8的整数倍大小X=rgb2gray(l); Y1=double(X);%读入图像数据lianghua=16 11 10 16 24 40 51 61;%量化矩阵,量化的程度序决定压缩比12 12 14 19 26 58 60 55;14 13 16 24 40 57 69 56;14 17 22 29 51 87 80 62;18 22 37 56 68 109 103 77;24 35 55 64 81 104 113 9
4、2;49 64 78 87 103 121 120 101;72 92 95 98 112 100 103 99;ilianghua=lianghua;%-%图像压缩%-t=dctmtx(8);J=blkproc(Y1,8 8,P1*x*P2,t,t); %分成8*8块进行DCT变换M=blkproc(J,8 8,round(x./P1),lianghua); %量化 u=abs(min(min(M1);M=(M1./u)+1;data=uint8(M);%Huffman编码要求为无符号整形数组M2=M-double(data);zipped,info=huffencode(data); %调
5、用Huffman编码程序进行压缩unzipped=huffdecode(zipped,info,data); %调用Huffman解码程序进行解压缩 k=1;for i=1:256 for j=1:256 unzippedray(i,j)=unzipped(k); k=k+1; endendunzippedray= unzippedray;%对解压缩后得到的一维数组进行变换,得到无损的量化后%二维数组,其值与data数组值是一致的,体现了Huffman编码是一种无损编码unzippedray=(double(unzippedray)-1+M2).*u; T=blkproc(unzippedra
6、y,8 8,x.*P1,ilianghua); %反量化I=blkproc(T,8 8,P1*x*P2,t,t); %8*8DCT反变换%-%调用Huffman编码程序进行解码%显示原始图像和经编码后的图像,显示压缩比,并计算均方根误差得erms=0,表示是Huffman是无失真编码figuresubplot(221);imshow(Y1,);axis square;xlabel(原256*256灰度图像);subplot(222);imshow(I,);axis square;xlabel(Huffman解压缩后图像);subplot(223);imshow(Y1-I),);axis squ
7、are;xlabel(量化后损失的图像部分);h,k=hist(Y1-I),256);%生成直方图数据subplot(224);bar(k,h,k);title(误差图像直方图);%subplot(224);imshow(I,);axis square;xlabel(压缩图像);%erms=compare(data(:),unzipped(:)cr=info.ratiowhos data unzipped zipped%huffencode函数对输入矩阵vector进行Huffman编码,返回%编码后的向量(压缩后数据)及相关信息Huffman编码子程序:function zipped,inf
8、o=huffencode(vector)%输入和输出都是unit8格式%info返回解码需要的机构信息%info.pad是添加的比特数%info.huffcodes是Huffman码字%info.rows是原始图像行数%info.cols是原始图像行数%info.length是原始图像数据长度%info.maxcodelen是最长码长if isa(vector,uint8) error(input argument must be a uint8 vector);endm,n=size(vector);vector=vector(:);f=frequency(vector); %计算各符号出现
9、的概率symbols=find(f=0);f=f(symbols);f,sortindex=sort(f); %将符号按照出现的概率大小排序symbols=symbols(sortindex);len=length(symbols);symbols_index=num2cell(1:len);codeword_tmp=cell(len,1);while length(f)1 %生产Huffman树,得到码字编码表 index1=symbols_index1; index2=symbols_index2; codeword_tmp(index1)=addnode(codeword_tmp(ind
10、ex1),uint8(0); codeword_tmp(index2)=addnode(codeword_tmp(index2),uint8(1); f=sum(f(1:2) f(3:end); symbols_index=index1,index2 symbols_index(3:end); f,sortindex=sort(f); symbols_index=symbols_index(sortindex);endcodeword=cell(256,1);codeword(symbols)=codeword_tmp;len=0;for index=1:length(vector) %得到整
11、个图像所有比特数 len=len+length(codeworddouble(vector(index)+1);endstring=repmat(uint8(0),1,len);pointer=1;for index=1:length(vector) %对输入图像进行编码 code=codeworddouble(vector(index)+1; len=length(code); string(pointer+(0:len-1)=code; pointer=pointer+len;endlen=length(string);pad=8-mod(len,8); %非8整数倍时,最后补pad个0i
12、f pad0 string=string uint8(zeros(1,pad);endcodeword=codeword(symbols);codelen=zeros(size(codeword);weights=2.(0:23);maxcodelen=0;for index=1:length(codeword) len=length(codewordindex); if lenmaxcodelen maxcodelen=len; end if len0 code=sum(weights(codewordindex=1); code=bitset(code,len+1); codewordin
13、dex=code; codelen(index)=len; endendcodeword=codeword:;%计算压缩后的向量cols=length(string)/8;string=reshape(string,8,cols);weights=2.(0:7);zipped=uint8(weights*double(string);%码表存储到一个稀疏矩阵huffcodes=sparse(1,1);for index=1:nnz(codeword) huffcodes(codeword(index),1)=symbols(index);end%填写解码时所需的结构信息info.pad=pad
14、;info.huffcodes=huffcodes;info.ratio=cols./length(vector);info.length=length(vector);info.maxcodelen=maxcodelen;info.rows=m;info.cols=n;%huffdecode函数对输入矩阵vector进行Huffman编码,%返回解压后的图像数据endHuffman解码子程序: function vector=huffdecode(zipped,info,image)ifisa(zipped,uint8) error(input argument must be a uint
15、8 vector);end%产生0,1序列,每位占一个字节len=length(zipped);string=repmat(uint8(0),1,len.*8);bitindex=1:8;for index=1:lenstring(bitindex+8.*(index-1)=uint8(bitget(zipped(index),bitindex);endstring=logical(string(:);len=length(string);%开始解码weights=2.(0:51);vector=repmat(uint8(0),1,info.length);vectorindex=1;code
16、index=1;code=0;for index=1:len code=bitset(code,codeindex,string(index); codeindex=codeindex+1; byte=decode(bitset(code,codeindex),info); if byte0 vector(vectorindex)=byte-1; codeindex=1; code=0; vectorindex=vectorindex+1; endend%vector=reshape(vector,info.rows,info.cols);%函数addnode添加节点endaddnode子程序
17、:function codeword_new=addnode(codeword_old,item)codeword_new=cell(size(codeword_old);for index=1:length(codeword_old) codeword_newindex=item codeword_oldindex;end%函数frequency计算各符号出现的概率end频率计数frequency子程序:function f=frequency(vector)ifisa(vector,uint8) error(input argument must be a uint8 vector);en
18、df=repmat(0,1,256);len=length(vector);for index=0:255 f(index+1)=sum(vector=uint8(index);endf=f./len;%函数decode返回码字对应的符号endbyte子程序:function byte=decode(code,info)byte=info.huffcodes(code);end实验结果如下:其中Cr为压缩比的倒数。即Cr=压缩后位数除以压缩前位数。cr = 0.1285 Name Size Bytes Class Attributes data 256x256 65536 uint8 unzi
19、pped 1x65536 65536 uint8 zipped 1x8421 8421 uint8 由于Huffman编码是无损编码,因此对同一图像,压缩效果的好坏取决于量化的程度。下面使用不同的量化矩阵对原图像进行量化,并进行压缩,观察效果。 分别使用下列模板替代原程序中的lianghua矩阵。由于这里使用1、0模板,所以round(x./P1)没有意义,因此主程序中量化部分需做一点改动,变成M1=blkproc(J,88,x.*P1,lianghua)其余部分不变,得到对应图像maski(i=2、3、5、n):Mask2= 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
20、 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0;Mask3= 1 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0;Mask4= 1 1 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
21、 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0;Mask5= 1 1 1 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0;Maskn= 1 1 1 1 1 1 0 0 1 1 1 1 1 0 0 0 1 1 1 1 0 0 0 0 1 1 1 0 0 0 0 0 1 1 0 0 0 0 0 0 1 0 0 0 0 0 0
22、 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0;cr = 0.1294 Name Size Bytes Class Attributes data 256x256 65536 uint8 unzipped 1x65539 65539 uint8 zipped 1x8480 8480 uint8 cr = 0.1295 Name Size Bytes Class Attributes data 256x256 65536 uint8 unzipped 1x65538 65538 uint8 zipped 1x8486 8486 uint8 cr = 0.1295 Name
23、Size Bytes Class Attributes data 256x256 65536 uint8 unzipped 1x65538 65538 uint8 zipped 1x8489 8489 uint8 cr = 0.1296 Name Size Bytes Class Attributes data 256x256 65536 uint8 unzipped 1x65539 65539 uint8 zipped 1x8493 8493 uint8 cr = 0.1296 Name Size Bytes Class Attributes data 256x256 65536 uint8
24、 unzipped 1x65538 65538 uint8 zipped 1x8493 8493 uint8 五、 实验总结从上面五幅图像与第一幅用标准量化模板量化所得的图像的对比中,我们可以看出,Cr的值越小,压缩比也就越大,在量化时对矩阵系数的精简作用就越明显,丢失的细节也越来越多。因此图像变得越来越模糊。另外,当系数模板从maskn到mask2时,Cr分别是0.1296、0.1296、0.1295、0.1295、0.1294,压缩后图像大小分别是8493、 8493、8489、8486 、8480。可见,在Cr变小、压缩比变大的情况下,压缩后图像在变小,图像质量渐渐变差。然而当模板矩阵达到一定大小时,如mask4之后,再继续增大模板系数范围n时,压缩后图像大小却不再改变,这是因为DCT变换后图像的绝大多数有用系数集中在矩阵的左上角,其余部分系数对图像影响很小,这也验证了DCT变换有利于图像压缩的原理所在。总结,通过上述实验,我们可以知道,适当的选取量化模板,可以实现用较少的系数尽可能多的保存原图像效果,这就是图像压缩的原理。并且,对同一类型量化矩阵,压缩比越大,压缩后图像大小就越小,图像效果就越模糊,因此压缩时选择合适的量化矩阵十分重要。