目录一、设计目的二、设计环境三、设计原理四、源程序与设计成果五、参考文献六、设计总结Huffman编码解码的设计一、设计目的1、熟悉和掌握MATLAB程序设计方法2、掌握图像Huffman的编码解码过程3、学习和熟悉MATLAB图像处理工具箱4、学会运用MATLAB工具箱对图像进行处理和分析二、设计环境WindowXP,MATLAB7.0三、设计原理:赫夫曼(Huffman)编码是1952年提出的,是一种比较经典的信息无损熵编码,该编码依据变长最佳编码定理,应用Huffman算法而产生。Huffman编码是一种基于统计的无损编码。设信源X的信源空间为:)()()()(:)(::][32121NNxPxPxPxPXPxxxXPX其中,1)(1NiixP,现用二进制对信源X中的每一个符号ix(i=1,2,…N)进行编码。根据变长最佳编码定理,Huffman编码步骤如下:(1)将信源符号xi按其出现的概率,由大到小顺序排列。(2)将两个最小的概率的信源符号进行组合相加,并重复这一步骤,始终将较大的概率分支放在上部,直到只剩下一个信源符号且概率达到1.0为止;(3)对每对组合的上边一个指定为1,下边一个指定为0(或相反:对上边一个指定为0,下边一个指定为1);(4)画出由每个信源符号到概率1.0处的路径,记下沿路径的1和0;(5)对于每个信源符号都写出1、0序列,则从右到左就得到非等长的Huffman码。Huffman编码的特点是:(1)Huffman编码构造程序是明确的,但编出的码不是唯一的,其原因之一是两个概率分配码字“0”和“1”是任意选择的(大概率为“0”,小概率为“1”,或者反之)。第二原因是在排序过程中两个概率相等,谁前谁后也是随机的。这样编出的码字就不是唯一的。(2)Huffman编码结果,码字不等长,平均码字最短,效率最高,但码字长短不一,实时硬件实现很复杂(特别是译码),而且在抗误码能力方面也比较差。(3)Huffman编码的信源概率是2的负幂时,效率达100%,但是对等概率分布的信源,产生定长码,效率最低,因此编码效率与信源符号概率分布相关,故Huffman编码依赖于信源统计特性,编码前必须有信源这方面的先验知识,这往往限制了哈夫曼编码的应用。(4)Huffman编码只能用近似的整数位来表示单个符号,而不是理想的小数,这也是Huffman编码无法达到最理想的压缩效果的原因。Huffman编码解码的设计流程图:算术编码程序流程图:四、源程序:clear;f0=imread('jx.jpg');subplot(121)imshow(uint8(f0));xlabel('\fontsize{16}原始图像');f=abs(f0/4)-10;[M,N]=size(f);p=zeros(1,61);fort=1:61count=0;fori=1:Mforj=1:Niff(i,j)==t-1count=count+1;endendendp(t)=count;p0=p;endcore=cell(61,1);sign=zeros(61);forhh=1:60re=M*N;fort=1:61if(p(t)re)&(p(t)0)re=p(t);endendt=1;while(p(t)~=re)&(t61)t=t+1;endifsign(t,1)==0core{t}='0';elsecore{t}=['0',core{t}];i=1;while(sign(t,i)~=0)&(i61)core{sign(t,i)}=['0',core{sign(t,i)}];i=i+1;endendp(t)=0;cou=t;re1=M*N;fort=1:61if(p(t)re1)&(p(t)0)re1=p(t);endendt=1;while(p(t)~=re1)&(t61)t=t+1;endifsign(t,1)==0core{t}='1';elsecore{t}=['1',core{t}];i=1;while(sign(t,i)~=0)&(i61)core{sign(t,i)}=['1',core{sign(t,i)}];i=i+1;endendp(t)=p(t)+re;cou1=t;i=1;while(sign(t,i)~=0)&(i61)i=i+1;endsign(t,i)=cou;i=i+1;j=1;while(sign(cou,j)~=0)&(j61)sign(t,i)=sign(cou,j);i=i+1;j=j+1;endend%产生huffman码fc=cell(M,N);fori=1:Mforj=1:Niff(i,j)61fc{i,j}=core{f(i,j)+1};elsefc{i,j}='0';endendend%fcimcore=char();fori=1:Mforj=1:Nimcore=[imcore,fc{i,j}];endendsavepictureimcorecore;%保存图片码流和编码对应表clear;loadpicture.mat%载入图片码流和编码对应表Nc=size(core);Nic=size(imcore);flag=0;i=1;j=1;n=1;cz=char();f=zeros(128);forn=1:400930ifflag==0cz=[cz,imcore(n)];elsecz=imcore(n);flag=0;endfort=1:61ifstrcmp(cz,core{t})f(j,i)=t;flag=1;ifi127;i=1;j=j+1;elsei=i+1;endbreak;endendendf=uint8(f*4+35);subplot(122)imshow(f);xlabel('\fontsize{16}解码后的图像');X=imread('jx.jpg','jpg');data=uint8(X);[zipped,info]=huffencode(data);unzipped=huffdecode(zipped,info);%显示原始图像和经编码解码后的图像,显示压缩比,并计算均方根误差得erms=0,%表示huffman是无失真编码subplot(121);imshow(data);subplot(122);imshow(unzipped);cr=info.ratio%函数addnode添加节点functioncodeword_new=addnode(codeword_old,item)codeword_new=cell(size(codeword_old));forindex=1:length(codeword_old)codeword_new{index}=[itemcodeword_old{index}];end%huffencode函数对输入矩阵vector进行huffman编码,返回编码后的向量及相关信息function[zipped,info]=huffencode(vector)if~isa(vector,'uint8')eror('inputargumentmustbeauint8vector');end[m,n]=size(vector);vector=vector(:)';f=frequency(vector);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);whilelength(f)1index1=symbols_index{1};index2=symbols_index{2};codeword_tmp(index1)=addnode(codeword_tmp(index1),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;forindex=1:length(vector)len=len+length(codeword{double(vector(index))+1});endstring=repmat(uint8(0),1,len);pointer=1;forindex=1:length(vector)code=codeword{double(vector(index))+1};len=length(code);string(pointer+(0:len-1))=code;pointer=pointer+len;endlen=length(string);pad=8-mod(len,8);ifpad0string=[stringuint8(zeros(1,pad))];endcodeword=codeword(symbols);codelen=zeros(size(codeword));weights=2.^(0:23);maxcodelen=0;forindex=1:length(codeword)len=length(codeword{index});iflenmaxcodelenmaxcodelen=len;endiflen0code=sum(weights(codeword{index}==1));code=bitset(code,len+1);codeword{index}=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);forindex=1:nnz(codeword)huffcodes(codeword(index),1)=symbols(index);end%填写解码时所需的结构信息info.pad=pad;info.huffcodes=huffcodes;info.ratio=cols./length(vector);info.length=length(vector);info.maxcodelen=maxcodelen;info.rows=m;info.cols=n;%huffdecode函数对输入矩阵vector进行huffman解码,返回解压后的图像数据functionvector=huffdecode(zipped,info,image)if~isa(zipped,'uint8')error('inputargumentmustbeauint8vector');end%产生0,1序列,每位占一个字节len=length(zipped);string=repmat(uint8(0),1,len.*8);bitindex=1:8;forindex=1:lenstring(bitindex+8.*(index-1))=uint8(bitget(zipped(index),bitindex));endstring=logical(string(:)');len=length(string);str