霍夫曼图像压缩编码源程序

合集下载

huffman压缩存储和解压缩源代码(精品文档)

huffman压缩存储和解压缩源代码(精品文档)

fst.open(filename, ifstream::in|ifstream::binary); wfile(fst, pssfile, Bytecode); fst.close(); pssfile.close(); system("pause"); }
void HuffmanCoding(array<huffman, m> &HT, array<string, n> &code, array<double, n> freq) { int j; unsigned char cj = 0; for (j = 0; j < n; ++j) { HT[cj].freq = freq[cj]; HT[cj].lchild = 0; HT[cj].rchild = 0; HT[cj].parent = 0; ++cj; } int i,s1, s2; for (i= n ; i <m; ++i) { myselect(HT, i, s1, s2); HT[s1].parent = i; HT[s2].parent = i; HT[i].lchild = s1; HT[i].rchild = s2; HT[i].freq = HT[s1].freq + HT[s2].freq; } for (i = 0; i < n; ++i) { string cd(n-1, '0'); int start = n-1; int k, f; for (k = i, f = HT[i].parent; f != 0; k = f, f = HT[f].parent) if (HT[f].lchild == k) cd[--start] = '0'; else cd[--start] = '1'; string cds(cd.substr(start, (n-1) - start)); code[i] = cds; }

霍夫曼编码(含源程序)

霍夫曼编码(含源程序)

多媒体技术根底实验报告——霍夫曼编码学院:电子工程与光电技术学院专业:电子信息工程某某:学号:任课教师:康其桔实验时间:一、实验内容与要求1、使用Matlab编程实现霍夫曼编码2、通过键盘输入字符串3、在屏幕上显示编码结果二、实验原理霍夫曼编码是霍夫曼在1952年提出和描述的“从下到上〞的熵编码方法。

根据给定数据集中各元素所出现的频率来压缩数据的一种统计压缩编码方法。

这些元素(如字母)出现的次数越多,其编码的位数就越少。

其根本步骤为:(1) 将压缩的各字符的出现概率按减少(或增加)的顺序进展排列。

(2) 将两个最小的概率进展组合相加得到一个新概率将这一新概率与其它概率一起继续执行1 和2 的操作直至最后概率为1.0。

(3) 对每对组合中的概率较大者指定为1,较小者指定为0。

(4) 画出由每个信源符号概率到处的路径记下路径的1和0。

(5) 对每个信源符号由从右到左写出1/0序列,对概率较高的标1,对概率较低的标0(或对概率较高的标0,对概率较低的标1),就得到了对应的Huffman码。

下面举个例子来说明霍夫曼编码的具体过程。

设需要编码的信息为:BACDEBACDEBACDEBADEBAEBABABABB,统计各个字符出现的次数分别为B(10次)、A(8次)、C(3次)、D(4次)、E(5次)。

各个字符出现的概率为B(10/30)、A(8/30)、E(5/30)、D(4/30)、C(3/30)。

霍夫曼编码的过程如1下: B(10/30) A(8/30) E(5/30) D(4/30)C(3/30)霍夫曼编码后平均码长为2(10/308/305/30)3(4/303/30) 2.23b ⨯+++⨯+≈ 。

而信源熵 2.19H b =。

由此,我们可以看出,霍夫曼编码结果已经很接近理想信源熵。

三、设计方案设计的流程图如下:四、各模块设计〔一〕读入字符串并去除空格在Matalb 中使用语句inputstring=input('请输入需要编码的字符:','s'),输入的字符串存入char 型数组inputstring 中。

霍夫曼压缩算法与其压缩比.

霍夫曼压缩算法与其压缩比.

霍夫曼压缩算法与其压缩比霍夫曼压缩算法是一种不失真的压缩方法,下面分别说明其算法执行过程与数据压缩率的计算方法:1.霍夫曼压缩算法我们为了说明方法本身,不妨做一些简化假定。

假定信源S包含的码元有{S1、S2、S3、S4、S5、S6、S7},而它们在通信消息中出现的概率分别是{0.21、0.11、0.08、0.18、0.03、0.25、0. 14}。

即S={S1,S2,S3,S4,S5,S6,S7},而其相应的出现概率P={P1,P2,P3,P4,P5,P6,P7}={0.21,0.11,0.08,0.18,0.03,0.25,0.14}。

霍夫曼编码过程中需要使用霍夫曼树,即如下图所示:算法的计算步骤叙述如下:1)将信源中的码元按照其在消息中出现概率的降序排列,即S6, S1, S4, S7, S2, S3, S5,作为霍夫曼树的叶子;2)将其中最小的两个码元概率相加组成一个新概率值,以此信概率值做自树的根形成一棵子树,并分别将连连接其中较小概率叶子的边标为“1”,较大概率叶子的边标为“0”;3)再找出两个概率较小的节点,重复2)的操作,形成新的子树。

直到最后形成子树的根节点概率值为1时停止。

这个根就是霍夫曼树的根。

4)从霍夫曼树的根沿着每棵子树的边向叶节点察看,并记录经过的每条边上的“0”与“1”的数字,结果便组成了该叶节点的霍夫曼编码。

按照上述方法计算得到的霍夫曼编码为:2.压缩率计算1)原来码元共有7个,它们可用4位二进制数编码,因为4位二进制数可描述8种组合。

所以平均码长为4位。

2)压缩后的平均码长L 应按照下式计算:L =∑=n1i Pi *Si所以,上述S 信源霍夫曼编码的平均码长为:L = 2*0.25+2*0.21+3*0.18+3*0.14+3*0.11+4*0.08+4*0.03 = 2.64位3)所以S 信源的霍夫曼编码压缩率为:4 / 2.54 = 1.52倍总之,由以上计算可以看出,不失真压缩算法的压缩率一般并不是十分高的。

霍夫曼编码的基本步骤

霍夫曼编码的基本步骤

霍夫曼编码的基本步骤霍夫曼编码(Huffman coding)是一种用于数据压缩的有效方法。

该方法基于一种前缀编码技术,即没有任何两个编码的前缀是相同的,从而避免了歧义。

霍夫曼编码经常被用作数据压缩算法,以压缩图像、音频和文本等数据。

下面介绍霍夫曼编码的基本步骤。

1.统计字符出现频率。

在对数据进行霍夫曼编码前,首先需要统计每个字符在数据中出现的频率。

这个过程称为字符频率统计。

统计完字符频率后,我们可以得到一个字符频率表,它表示了每个字符的出现频率。

2.构造霍夫曼树。

根据字符频率表建立霍夫曼树。

霍夫曼树是一棵二叉树,它的叶子节点代表每个字符,节点的权值等于对应字符在数据中出现的频率。

构建霍夫曼树的过程中,需要按照权值大小将节点进行排序并分组,然后逐步合并节点,形成新的子树。

最后合并成一棵完整的霍夫曼树。

3.创建编码表。

根据霍夫曼树,可以为每个字符创建对应的编码。

编码的规则是:从根节点到对应叶子节点的路径表示该字符的编码。

当遍历树时,每次走向左子树添加0,每次走向右子树添加1、因为是前缀编码,所以如果某个字符的编码是另一个字符编码的前缀,则需要为该字符再添加一位编码。

创建编码表后,每个字符都有了对应的编码。

4.对数据进行编码。

在对数据进行编码时,挨个读取原始数据中的字符,并用相应的编码来进行替换。

最终的编码结果就是所有字符的编码串,即为压缩后的数据。

如果有一些字符的编码比其它字符的编码短,那么压缩后的数据就相对变得更小。

5.解码数据。

在解压数据时,需要先用霍夫曼树进行解码。

将压缩后的数据中每一位取出,并从霍夫曼树的根节点开始遍历直到叶子节点找到对应的字符。

将解码后的字符依次排列,即可得到原始的数据。

6.总结。

霍夫曼编码是一种十分有效的数据压缩算法,因为它可以通过对原始数据进行编码和解码来实现数据压缩和恢复。

通过统计字符出现频率、构建霍夫曼树,创建编码表、对数据进行编码和解码,霍夫曼编码过程能够显著减少数据的存储空间,提高数据传输效率。

霍夫曼编码解码过程

霍夫曼编码解码过程

霍夫曼编码解码过程霍夫曼编码是一种基于概率的变长编码方法,主要用于无损数据压缩。

其核心思想是给出现概率较高的符号赋予较短的编码,反之则赋予较长的编码。

这样,平均码长将会接近于原始数据的熵,从而实现有效的数据压缩。

以下是霍夫曼编码和解码的过程:霍夫曼编码过程:1.首先,统计出待编码数据中每个字符出现的频率,例如,对于字符串"ABABABABA",我们可以得到字符'A'出现4次,字符'B'出现5次。

2.创建一个霍夫曼树。

这个树是一个二叉树,其中每个节点代表一个字符,节点的频率作为权重。

3.从根节点开始,对于每个节点,如果其左子节点和右子节点代表的字符不同,则将当前节点替换为一个新的字符,这个新字符的码字是左子节点和右子节点码字的组合。

需要注意的是,实际的霍夫曼编码过程中可能会有多种不同的树结构生成相同的结果,因此在具体实现时需要保证算法的稳定性和可重复性。

霍夫曼解码过程:霍夫曼解码是将霍夫曼编码后的数据进行还原的过程。

由于霍夫曼编码是前缀编码,也就是说编码后的码字没有前缀相同的后缀,因此解码过程是唯一的。

具体来说,解码步骤如下:1.从第一个字节开始,根据霍夫曼树的每个分支的权值(即字符出现的频率),从根节点向下查找对应的字符。

例如,对于码字"00",我们首先找到根节点,然后找到左子节点对应的字符'A'。

2.对于每个后续的字节,重复上述步骤。

需要注意的是,由于霍夫曼编码是前缀编码,因此我们不需要担心码字的结束位置,只要遇到一个码字,就可以一直解码下去,直到所有数据都被解码。

通过以上步骤,我们可以将霍夫曼编码的数据还原成原始的数据。

总的来说,霍夫曼编码是一种非常有效的无损数据压缩方法,尤其适用于数据中存在大量重复元素的情况。

用Huffman编码实现图像压缩

用Huffman编码实现图像压缩

用Huffman编码实现图像压缩摘要:当前,网络和多媒体技术日新月异,信息量急速膨胀。

针对这种情况,本文探讨了它的解决方法——数据压缩(主要是图像压缩)。

着重研究了无失真条件下的最佳编码方法——huffman编码,对其方法的优劣做了较为客观的评价。

关键词:图像压缩编码 huffman编码中图分类号:tp393.03 文献标识码:a 文章编号:1007-9416(2011)12-0238-021、前言随着科技的发展,现在各种各样的数据和信息正在急速膨胀,每天出现的新知识正以近乎指数的规律逐日上升。

如何方便快速地存储、处理和传输这些日益增加的信息,使之更好的为我们服务,已经成为多数行业共同的呼声。

特别是近几年来随着网络走进普通家庭,昔日老牛拉破车似的网速已让多数人所不能容忍。

因为数据在数据传输时,要占据很大的信道容量。

为此,人们想到了采用对图像新的表达方法以减小表示一幅图像所需数据量,这就是图像编码要解决的主要问题。

由于图像编码减少了数据量,因此人们也常称图像编码为图像压缩。

本文将着重研究huffman编码方法,并形成一个对huffman编码方法的较为完整的评价。

2、正文2.1 huffman编码huffman编码的主导思想是根据数据符号发生的概率进行编码。

在源数据中出现概率越高的符号,相应的码长越短;出现概率越小的符号,其码长越长,从而达到用尽可能少的码符号表示源数据。

huffman编码方法是接近压缩比上限的一种最佳的编码方法。

2.2 具体编码过程(1)将信源符号按出现概率由大到小排列。

(2)将2个最小概率相加,形成一新的概率集合,对应一新的信源,符号数减小一个,即具有q-1个符号数,称为缩减信源a。

(3)将缩减信源a中q-1个符号再按概率大小排列。

如符号间概率相等,则排列次序不论。

(4)如此继续,得到具有(q-2)、(q-3)、(q-4)、...个符号的缩减信源b、c、d等,直到只有2个符号为止。

霍夫曼成像原理

霍夫曼成像原理

霍夫曼成像原理
霍夫曼成像原理(Huffman imaging principle)是一种基于自适应编码技术的图像压缩原理。

该原理是由大卫·霍夫曼(David Huffman)在1952年提出的。

在霍夫曼成像原理中,首先对图像的像素值进行统计,将出现频率较高的像素值用较短的编码表示,出现频率较低的像素值用较长的编码表示,从而实现对图像的压缩。

具体步骤如下:
1. 统计图像中各个像素值的出现频率。

2. 根据频率构建霍夫曼树(Huffman tree),树的叶子节点代表图像中的各个像素值,叶子节点的权值即为相应像素值的频率。

3. 从霍夫曼树中对各个像素值进行编码,路径向左的边表示编码位为0,路径向右的边表示编码位为1,从根节点到叶子节点的路径即为该像素值的编码。

4. 使用霍夫曼编码表将图像中的每个像素值替换为相应的编码。

5. 将编码后的图像存储或传输。

在解码时,只需根据编码表将编码还原为原始的像素值,即可还原出压缩前的图像。

Huffman压缩 实验报告 源程序

Huffman压缩 实验报告 源程序

用哈夫曼编码实现文件压缩实验目的⒈了解有关文件的基本概念⒉掌握哈夫曼树的概念及其构造方法⒊正确实现线性链表的插入,删除等运算⒋掌握遍历二叉树的方法⒌运用哈夫曼树及其编码实验环境Windows XP VC++ 6.0实验内容根据ascii码文件中各ascii字符出现的频率情况创建哈夫曼树,再将各字符对应的哈夫曼编码相连,每八位作为一个字符,写入文件中,同时Huffman树也要压缩后写入压缩文件,以实现文件压缩。

设计概要压缩部分1.构造哈夫曼树,对其进行前缀编码(1)扫描待压缩文件,得出各字符出现频率。

(2)根据给定的n个权值{W1,W2,...Wn}构成n棵二叉树的集合F={T1,T2,…,Tn},每棵二叉树Ti中只有一个带权为Wi的根节点,其左右子树均空。

(3)在F中选取两棵根节点的权值最小的树作为左右子树构造一棵新的二叉树,且值新的二叉树的根节点的权值为其左右子树上根节点的全值之和。

(4)在F中删除这两棵树。

同时将新得到的二叉树加入F中。

重置(2)和(3),直到F只含一棵树为止。

这棵树便是哈夫曼树。

2.由Huffman树得到各字符前缀编码。

3.根据前缀编码,对文件中各个字符进行编码,并按每八位一次写入压缩文件。

4.处理剩余不到八位部分,写入压缩文件。

5.将前缀编码及相关信息写入压缩文件。

6.关闭指针,完成压缩。

计算压缩率。

解压部分1.读入压缩文件长度和源文件长度。

读入前缀编码。

2.对文件中各字符解码,写入解压文件。

3.判断解压文件是否完好(对比压缩前文件长度),关闭指针,完成解压。

源码部分:#include <stdio.h>#include <string.h>#include <stdlib.h>#include <conio.h>struct head {unsigned char b; //记录字符在数组中的位置long count; //字符出现频率(权值)long parent,lch,rch; //定义哈夫曼树指针变量char bits[256]; //定义存储哈夫曼编码的数组}header[512],tmp;void compress(){char filename[255],outputfile[255],buf[512];unsigned char c;long n,m,i,j,f; //作计数或暂时存储数据用long min1,pt1,flength=0,length1,length2; //记录最小结点、文件长度double div; //计算压缩比用FILE *ifp,*ofp; //分别为输入、输出文件指针printf("\t请您输入需要压缩的文件(需要路径):");gets(filename);ifp=fopen(filename,"rb");if(ifp==NULL){printf("\n\t文件打开失败!\n ");system("pause");return;}printf("\t请您输入压缩后的文件名(如无路径则默认为桌面文件):");gets(outputfile);ofp=fopen(outputfile,"wb");if(ofp==NULL){printf("\n\t压缩文件失败!\n ");system("pause");return;}flength=0;while(!feof(ifp)){fread(&c,1,1,ifp);header[c].count++; //字符重复出现频率+1flength++; //字符出现原文件长度+1 }flength--;length1=flength; //原文件长度用作求压缩率的分母header[c].count--;for(i=0;i<512;i++){if(header[i].count!=0)header[i].b=(unsigned char)i;/*将每个哈夫曼码值及其对应的ASCII码存放在一维数组header[i]中,且编码表中的下标和ASCII码满足顺序存放关系*/ elseheader[i].b=0;header[i].parent=-1;header[i].lch=header[i].rch=-1; //对结点进行初始化}for(i=0;i<256;i++){ //按出现权值从大到小排序for(j=i+1;j<256;j++){if(header[i].count<header[j].count){tmp=header[i];header[i]=header[j];header[j]=tmp;}}}for(i=0;i<256;i++) //找到第一个空的header结点if(header[i].count==0)break;n=i;m=2*n-1;for(i=n;i<m;i++){min1=999999999; //预设的最大权值,即结点出现的最大次数for(j=0;j<i;j++){if(header[j].parent!=-1)continue; /*parent!=-1说明该结点已存在哈夫曼树中,跳出循环重新选择新结点*/ if(min1>header[j].count){pt1=j;min1=header[j].count;continue;}}header[i].count=header[pt1].count;header[pt1].parent=i;header[i].lch=pt1;min1=999999999;for(j=0;j<i;j++){if(header[j].parent!=-1)continue;if(min1>header[j].count){pt1=j;min1=header[j].count;continue;}}header[i].count+=header[pt1].count;header[i].rch=pt1;header[pt1].parent=i; //哈夫曼无重复前缀编码}for(i=0;i<n;i++){f=i;header[i].bits[0]=0; //根结点编码0while(header[f].parent!=-1){j=f;f=header[f].parent;if(header[f].lch==j){ //置左分支编码0j=strlen(header[i].bits);memmove(header[i].bits+1,header[i].bits,j+1);//依次存储连接"0""1"编码,此处语句为网络借鉴header[i].bits[0]='0';}else{ //置右分支编码1j=strlen(header[i].bits);memmove(header[i].bits+1,header[i].bits,j+1);header[i].bits[0]='1';}}}fseek(ifp,0,SEEK_SET); //从文件开始位置向前移动0字节,即定位到文件开始位置fwrite(&flength,sizeof(int),1,ofp); /*用来将数据写入文件流中,参数flength 指向欲写入的数据地址,总共写入的字符数以参数size*int来决定,返回实际写入的int数目*/fseek(ofp,8,SEEK_SET);buf[0]=0; //定义缓冲区,它的二进制表示00000000f=0;pt1=8; /*假设原文件第一个字符是"A",8位2进制为01000001,编码后为0110识别编码第一个'0',那么将其左移一位,看起来没什么变化。

哈夫曼编码算法详解

哈夫曼编码算法详解

哈夫曼编码算法详解在计算机科学中,哈夫曼编码是一种压缩算法,也叫做霍夫曼编码,是由霍夫曼(Huffman)在1952年首创的。

霍夫曼编码是一种无损压缩算法,可以对文本文件、音频文件、图像文件等各种类型的文件进行压缩。

1. 哈夫曼编码的原理哈夫曼编码是基于频率统计的思想,通过统计每个字符在文件中出现的频率,选择出现频率最高的字符,将其映射为一组比特位,出现频率较低的字符则映射为比高的比特位,从而实现对文件的压缩。

通过哈夫曼编码,可以将文件压缩到原始大小的一半甚至更小。

2. 哈夫曼编码的实现哈夫曼编码的实现需要进行几个步骤:2.1 统计字符的出现频率从文件中读取字符,统计每个字符在文件中出现的次数,可以使用一个数组或字典来保存每个字符的出现次数。

对于英文文本来说,出现频率最高的字符是空格,其次是字母“e”。

2.2 构建哈夫曼树将所有的字符按照出现频率从小到大排序,选出出现频率最小的两个字符作为左右子节点,其父节点的出现频率为左右子节点出现频率之和。

重复这个过程,直到节点数为1,这样就得到了一棵哈夫曼树。

2.3 生成哈夫曼编码从哈夫曼树的根节点开始,遍历所有的节点,将左子节点标记为0,将右子节点标记为1,将所有的叶子节点的字符和对应的哈夫曼编码保存到一个字典中。

最终得到了每个字符对应的哈夫曼编码。

2.4 进行压缩将文件中每个字符替换为对应的哈夫曼编码,然后将所有的哈夫曼编码拼接成一个二进制数,在最后不足8位的位置补零,将其存储到文件中。

这样就完成了文件的压缩。

3. 哈夫曼编码的优点哈夫曼编码具有以下优点:3.1 压缩率高由于哈夫曼编码是根据不同字符的出现频率来进行编码的,出现频率高的字符用较短的编码表示,出现频率低的字符用较长的编码表示,能够最大限度地减少文件的大小,从而达到高的压缩率。

3.2 唯一解哈夫曼编码是通过构建哈夫曼树来得到每个字符对应的编码,哈夫曼树的构建是唯一的,因此哈夫曼编码也是唯一的。

图像的无损压缩程序设计 霍夫曼编码

图像的无损压缩程序设计 霍夫曼编码

成绩评定表课程设计任务书摘要哈夫曼编码(Huffman Coding)是一种编码方式,以哈夫曼树—即最优二叉树,带权路径长度最小的二叉树,经常应用于数据压缩。

在计算机信息处理中,“哈夫曼编码”是一种一致性编码法(又称"熵编码法"),用于数据的无损耗压缩。

这一术语是指使用一张特殊的编码表将源字符(例如某文件中的一个符号)进行编码。

这张编码表的特殊之处在于,它是根据每一个源字符出现的估算概率而建立起来的(出现概率高的字符使用较短的编码,反之出现概率低的则使用较长的编码,这便使编码之后的字符串的平均期望长度降低,从而达到无损压缩数据的目的)。

本课题通过MATLAB编写适当的函数,对一个随机信源进行哈夫曼编码,得出码字,平均码长和编码效率。

从而理解信源编码的基本思想与目的以及哈夫曼编码方法的基本过程与特点,并且提高综合运用所学理论知识独立分析和解决问题的能力。

关键字:哈夫曼;信源编码;MATLAB目录1设计目的及相关知识 (1)1.1设计目的 (1)1.2图像的霍夫曼编码概念 (1)1.3Matlab图像处理通用函数 (1)2课程设计分析 (3)2.1 图像的霍夫曼编码概述 (3)2.2 图像的霍夫曼编码举例 (4)3仿真 (6)4结果及分析 (9)5附录 (12)结束语 (15)参考文献 (16)1设计目的及相关知识1.1设计目的1)了解霍夫曼编码的原理。

2)理解图像的霍夫曼编码原理,了解其应用,掌握图像的霍夫曼编码的方法。

3)对图像编码程序设计进行较深入的认识,对知识牢固掌握。

4)掌握图像霍夫曼编码的整个过程及其中的注意事项。

5)了解图像无损压缩的目的及好处。

1.2图像的霍夫曼编码概念所谓霍夫曼编码的具体方法:先按出现的概率大小排队,把两个最小的概率相加,作为新的概率和剩余的概率重新排队,再把最小的两个概率相加,再重新排队,直到最后变成1。

每次相加时都将“0”和“1”赋与相加的两个概率,读出时由该符号开始一直走到最后的“1”,将路线上所遇到的“0”和“1”按最低位到最高位的顺序排好,就是该符号的霍夫曼编码1.3 Matlab图像处理通用函数colorbar 显示彩色条语法:colorbar \ colorbar('vert') \ colorbar('horiz') \ colorbar(h) \ h=colorbar(...) \ colorbar(...,'peer',axes_handle)getimage从坐标轴取得图像数据语法:A=getimage(h) \ [x,y,A]=getimage(h) \ [...,A,flag]=getimage(h) \ [...]=getimage imshow显示图像语法:imshow(I,n) \ imshow(I,[low high]) \ imshow(BW) \ imshow(X,map) \ imshow(RGB)\ imshow(...,display_option) \ imshow(x,y,A,...) \ imshow filename \h=imshow(...)montage 在矩形框中同时显示多幅图像语法:montage(I) \ montage(BW) \ montage(X,map) \ montage(RGB) \h=montage(...)immovie创建多帧索引图的电影动画语法:mov=immovie(X,map) \ mov=immovie(RGB)subimage在一副图中显示多个图像语法:subimage(X,map) \ subimage(I) \ subimage(BW) \ subimage(RGB) \ subimage(x,y,...) \ subimage(...)truesize调整图像显示尺寸语法:truesize(fig,[mrowsmcols]) \ truesize(fig)warp 将图像显示到纹理映射表面语法:warp(X,map) \ warp(I ,n) \ warp(z,...) warp(x,y,z,...) \ h=warp(...)zoom 缩放图像语法:zoom on \ zoom off \ zoom out \ zoom reset \ zoom \ zoom xon \ zoom yon\ zoom(factor) \ zoom(fig,option)2课程设计分析2.1 图像的霍夫曼编码概述赫夫曼(Huffman)编码是1952年提出的,是一种比较经典的信息无损熵编码,该编码依据变长最佳编码定理,应用Huffman算法而产生。

最新基于霍夫曼编码实现的图像数据无损压缩程序设计文件综述

最新基于霍夫曼编码实现的图像数据无损压缩程序设计文件综述

精品资料基于霍夫曼编码实现的图像数据无损压缩程序设计文件综述........................................基于霍夫曼编码实现的图像数据无损压缩程序设计1.前言现代社会是信息社会,我们无时无刻都在跟信息打交道,如上网查阅图文资料,浏览最新的新闻,QQ 聊天或者传送文件等。

人类对信息的要求越来越丰富,希望无论何时何地都能够方便、快捷、灵活地通过文字、语音、图像以及视频等多媒体进行通信。

在早期的通信领域中,能够处理和传输的主要是文字和声音,因此,早期的计算机和通信设备的处理能力跟人类的需求有相当大的差距。

随着通信信道及计算机容量和速度的提高,如今图像信息已成为通信和计算机系统的一种处理对象,成为通信领域市场的热点之一。

可是,大数据量的图像信息会给存储器的存储容量、通信干线信道的带宽以及计算机的处理速度增加极大的压力。

单纯依靠增加存储器容量、提高通信网络带宽和计算机处理速度来解决问题,在技术和经济上都不太现实。

显然,在信道带宽、通信链路容量一定的前提下,采用编码压缩技术,减少传输数据量,是提高通信速度的重要手段。

2.正文2.1 图像压缩编码的现状和发展趋势1948年提出电视数字化后,就开始对图像压缩编码技术的研究工作,至今已有50多年的历史。

图像压缩的基本理论起源于20世纪40年代末香农的信息理论。

香农的编码定理告诉我们,在不产生任何失真的前提下,通过合理的编码,对于每一个信源符号分配不等长的码字,平均码长可以任意接近于信源的熵。

在五十年代和六十年代,图像压缩技术由于受到电路技术等的制约,仅仅停留在预测编码、亚采样以及内插复原等技术的研究,还很不成熟。

1969年在美国召开的第一届“图像编码会议”标志着图像编码作为一门独立的学科诞生了。

到了70年代和80年代,图像压缩技术的主要成果体现在变换编码技术上,矢量量化编码技术也有较大发展,有关于图像编码技术的科技成果和科技论文与日俱增,图像编码技术开始走向繁荣。

霍夫曼编码代码

霍夫曼编码代码

霍夫曼编码代码简介霍夫曼编码是一种常用的无损数据压缩算法,广泛应用于数据传输和存储中。

它通过构建一棵霍夫曼树,将出现频率较高的字符用较少的二进制位表示,从而达到压缩数据的目的。

本文将详细介绍霍夫曼编码的原理、实现方式以及编写霍夫曼编码的代码示例。

霍夫曼编码原理霍夫曼编码的核心原理是根据字符出现的频率构建一棵霍夫曼树。

树的叶子节点对应字符,叶子节点到根节点的路径上的分支标记为0或1,构成了字符的霍夫曼编码。

编码的规则是,出现频率较高的字符对应的编码较短,而出现频率较低的字符对应的编码较长。

霍夫曼编码的步骤1.统计字符的频率:遍历待压缩的数据,统计每个字符出现的次数。

2.构建霍夫曼树:将字符频率作为权值创建一棵霍夫曼树,其中频率较低的字符位于树的下层。

3.生成霍夫曼编码表:从霍夫曼树的根节点开始,向左走的路径标记为0,向右走的路径标记为1,递归生成每个字符对应的霍夫曼编码。

4.压缩数据:按照生成的编码将原始数据转换成二进制字符串,将字符串转换为字节流保存。

实现霍夫曼编码的关键数据结构在实现霍夫曼编码时,我们需要以下两个关键的数据结构: 1. 霍夫曼树:用于构建霍夫曼编码,其节点包含字符和对应的频率。

2. 霍夫曼编码表:用于存储每个字符对应的编码。

伪代码实现下面是一个简单的伪代码实现霍夫曼编码的例子:# 伪代码实现霍夫曼编码def huffman_encoding(data):# 统计字符频率freq_map = count_frequency(data)# 构建霍夫曼树huffman_tree = build_huffman_tree(freq_map)# 生成霍夫曼编码表huffman_code_table = generate_code_table(huffman_tree)# 压缩数据encoded_data = encode_data(data, huffman_code_table)return encoded_data, huffman_code_table实例演示为了更好理解霍夫曼编码的过程,我们以字符串”hello world”为例进行演示。

实验2(1)霍夫曼压缩

实验2(1)霍夫曼压缩

基于Huffman编码的文档压缩一、实验目的:(1)掌握Huffman编码。

(2)掌握文档压缩的基本原理和应用二、分组:三个人一组,自由组合三、内容:两种压缩方法1.以字母(Character)为基础的压缩1. 文本解析:将cacm.all文件分解成一个个的字母2. 字频统计:统计每个字母出现的词频3. Huffman编码:根据Huffman编码的原理,对每个字母进行编码。

给出一个编码字典。

4. 文档压缩:根据Huffman编码,压缩文件。

5. 文档还原:对压缩后的文档进行解压缩。

2. 以字(Word)为基础的压缩处理附件cacm.all文件,分为下面四步:1. 文本解析:将cacm.all文件分解成一个个的单词2. 词频统计:统计每个单词出现的词频3. Huffman编码:根据Huffman编码的原理,对每个单词进行编码。

给出一个编码字典。

4. 文档压缩:根据Huffman编码,压缩文件。

5. 文档还原:对压缩后的文档进行解压缩。

3. 比较比较三种不同的压缩方法的效率*4. (选做)以字母压缩为基础的算法除了可以对文本文件进行压缩外,还可以对二进制文件进行压缩,比如对图像、视频、可执行文件的压缩。

自己找一些这类二进制文件,比较压缩算法对不同文件的压缩效率。

四:提交内容1.源程序2.可执行程序3.实验报告(参考附件内容)4.压缩后的文档5.词频统计表和Huffman编码表:类似下面的表格(下表中的数据只是示例,以实际生成的数据为准)1.五. 其他注意事项1.两个单词由下列标点符号切分:空格句号. 问号? 感叹号! 逗号, 分号; 冒号: 左括号( 右括号) 双撇号" 单撇号' 连字符- 制表符\t 回车\n2. 以Huffman编码为基础的压缩文件应该以二进制的方式来存储,这就涉及到文件的读写操作中的“以文本方式打开文件”“以二进制方式打开文件”这两种不同的方式。

建议详细参考C语言中关于文件的读写这部分内容。

数据压缩霍夫曼编码算术编码

数据压缩霍夫曼编码算术编码

固定编码模式
1
概率统计与区间分配直接影响编码效率。
2
自适应模式
3
各符号的概率初始值都相同,但依据实际出现的符号而相应地改变。
4
两种编码模式:
jpeg、mpeg-1和mpeg-2等国际标准采用的图像压缩编码方案都是传统的“DCT+运动补偿+算术编码”模式
JPEG2000、MQ算术编码器
嵌入位平面图像编码器EZW、SPIHT和SPECK中也采用这种通用算法编码器
现有一个由5个不同符号组成的30个符号的字符串:BABACACADADABBCBABEBEDDABEEEBB
计算 该字符串的霍夫曼码 该字符串的熵 该字符串的平均码长 编码前后的压缩比
霍夫曼编码
霍夫曼编码举例1
霍夫曼编码
符号
出现的次数
log2(1/pi)
分配的代码
需要的位数
B
10
1.585
?
A
8
1948年, Shannon提出将信源依其概率降序排序, 用符号序列累积概率的二进制表示对信源的编码;
1976年, R. Pasco和J.Rissanen 分别用定长的寄存器实现了有限精度的算术编码;
1979年, Rissanen 和G.G. Langdon将算术编码系统化,并于1981年将AC推广应用到二值图像编码上,大大提高了起压缩效率;
算术编码处理过程的编码区间分配可用图解法表示: 以少代多思想:用最终求得的编码表示范围子区间的 任何值(如:0.10603),来替代被编码符号串X1X2X3X4X5
无论是否是二元信源,也不论数据的概率分 布如何,算术编码可以二进制小数表示,其平均码长可以接近无损压缩的熵极限。

图像压缩

图像压缩
LONG biYPelsPerMeter;
DWORD biClrUsed;
DWORD biClrImportant;
} BITMAPINFOHEADER, FAR *LPBITMAPINFOHEADER, *PBITMAPINFOHEADER;
3.彩色表/调色板(color table)
彩色表/调色板(color table)是单色、16色和256色图像文件所特有的,相对应的调色板大小是2、16和256,调色板以4字节为单位,每4个字节存放一个颜色值,图像的数据是指向调色板的索引。
typedef struct tagBITMAPFILEHEADER {
WORD bfType;
DWORD bfSize;
WORD bfReserved1;
WORD bfReserved2;
DWORD bfOffBits;
} BITMAPFILEHEADER, FAR *LPBITMAPFILEHEADER, *PBITMAPFILEHEADER;
可以将调色板想象成一个数组,每个数组元素的大小为4字节,假设有一256色的BMP图像的调色板数据为:
调色板[0]=黑、调色板[1]=白、调色板[2]=红、调色板[3]=蓝…调色板[255]=黄
图像数据01 00 02 FF表示调用调色板[1]、调色板[0]、调色板[2]和调色板[255]中的数据来显示图像颜色。
typedef struct tagRGBQUAD {
BYTE rgbBlue;
BYTE rgbGreen;
BYTE rgbRed;
BYTE rgbReserved;
} RGBQUAD;
4.位图数据(bitmap-data)
如果图像是单色、16色和256色,则紧跟着调色板的是位图数据ห้องสมุดไป่ตู้位图数据是指向调色板的索引序号。

lzw和霍夫曼编码

lzw和霍夫曼编码

lzw和霍夫曼编码LZW(Lempel-Ziv-Welch)编码和Huffman编码是常见的无损数据压缩算法。

它们可以将数据以更高效的方式表示,并减少数据所占用的存储空间。

虽然两种编码算法有一些相似之处,但它们的工作原理和实施方法略有不同。

1.LZW编码:LZW编码是一种基于字典的压缩算法,广泛应用于文本和图像等数据的压缩。

它的工作原理是根据已有的字典和输入数据,将连续出现的字符序列转换为对应的索引,从而减少数据的存储空间。

LZW编码的过程如下:•初始化字典,将所有可能的字符作为初始词条。

•从输入数据中读取字符序列,并检查字典中是否已有当前序列。

•如果字典中存在当前序列,则继续读取下一个字符,将该序列与下一个字符连接成一个长序列。

•如果字典中不存在当前序列,则将当前序列添加到字典中,并输出该序列在字典中的索引。

•重复以上步骤,直到输入数据全部编码完成。

LZW编码的优点是可以根据实际数据动态更新字典,适用于压缩包含重复模式的数据。

2.霍夫曼编码:霍夫曼编码是一种基于频率的前缀编码方法。

它根据字符出现的频率构建一个最优二叉树(霍夫曼树),将出现频率较高的字符用较短的二进制码表示,出现频率较低的字符用较长的二进制码表示。

霍夫曼编码的过程如下:•统计输入数据中各个字符的频率。

•使用字符频率构建霍夫曼树,频率较高的字符在树的较低层,频率较低的字符在树的较高层。

•根据霍夫曼树,为每个字符分配唯一的二进制码,保持没有一个字符的编码是另一个字符编码的前缀。

•将输入数据中的每个字符替换为相应的霍夫曼编码。

•输出霍夫曼编码后的数据。

霍夫曼编码的优点是可以根据字符频率进行编码,使高频字符的编码更短,适用于压缩频率差异较大的数据。

总的来说,LZW编码和霍夫曼编码都是常见的无损数据压缩算法,用于减少数据的存储空间。

它们的选择取决于具体的场景、数据特点和应用需求。

霍夫曼编码过程

霍夫曼编码过程

霍夫曼编码过程霍夫曼编码是一种基于字符出现频率来进行编码的方法,通常用于数据压缩。

它使用变长编码,使得高频字符拥有较短的编码,从而减小数据的存储空间。

霍夫曼编码的构建过程包括以下步骤:1. 统计字符出现频率:首先需要统计输入文本中每个字符出现的频率。

可以对输入文本进行扫描,每当遇到一个字符时,计数器加1。

通常可以使用一个频率表来记录每个字符的频率。

2. 构建霍夫曼树:霍夫曼树是一种二叉树,它的每个叶子节点都代表一个字符,并且每个节点的权重等于其子节点的权重之和。

构建霍夫曼树的过程可以使用贪心算法。

霍夫曼树的构建过程如下:- 首先,将频率表中的每个字符作为一个节点放入一个优先队列(最小堆)中。

请注意,这里的频率表中的字符不需要按频率排序。

- 从优先队列中取出频率最小的两个节点,组成一个新的内部节点。

频率越小的节点作为左孩子,频率较大的节点作为右孩子。

- 将新的节点放入优先队列中。

- 重复以上步骤,直到只剩下一个节点,即为霍夫曼树的根节点。

3. 构建霍夫曼编码表:根据霍夫曼树,可以通过遍历树的路径来确定每个字符的霍夫曼编码。

路径的左分支表示编码中的0,右分支表示1。

从根节点开始,递归遍历每个节点,并将遇到的路径编码记录下来。

构建霍夫曼编码表的过程如下:- 从根节点开始,遍历每个节点。

- 递归进入左子树时,将编码加上0;递归进入右子树时,将编码加上1。

- 当遍历到叶子节点时,将该节点对应的字符和生成的编码加入到霍夫曼编码表中。

4. 编码文本:通过使用霍夫曼编码表,可以将输入文本中的每个字符替换为对应的霍夫曼编码。

编码后的文本长度会变短,因为高频字符使用的编码长度较短。

5. 解码文本:解码文本是编码文本的逆过程。

根据霍夫曼编码表,将编码文本逐个字符转换为对应的霍夫曼编码,然后根据霍夫曼树从根节点开始遍历,直到找到叶子节点对应的字符。

将这个字符添加到解码后的文本中,然后继续遍历编码文本,直到解码完成。

霍夫曼编码的思想是通过使高频字符的编码长度较短,从而能够有效地压缩数据。

霍夫曼编码算法

霍夫曼编码算法

霍夫曼编码算法
霍夫曼编码算法是一种产生可变长度编码的无损数据压缩算法。

它由
美国数学家霍夫曼(David A. Huffman)于1952年发明,是一种非
常有效的压缩算法。

该算法通过构造一颗霍夫曼树来得出每个字符的
编码。

霍夫曼编码的基本思想是:将出现频率高的字符用短长度的编码表示,而用长编码表示出现频率低的字符。

霍夫曼编码要求编码的前缀码是
无歧义的,即任何一个字符的编码都不是另一个字符编码的前缀。

如此,当解出字符串的特定前缀之后,就可以确定该前缀所表示的唯一
字符。

霍夫曼编码压缩数据的具体步骤如下:
1. 统计出待压缩文件中每个字符出现的频率,即权值;
2. 将它们按权值从小到大排列,每个字符看作一个权重为其出现次数
的节点,构成一个节点森林;
3. 把两个权值最小的森林节点合并成一个新的树,树上节点的权值为
两个被合并的节点权值之和;
4. 重复步骤3,直到所有的节点都被合并成一棵树,即霍夫曼树;
5. 对霍夫曼树进行遍历,将从根节点到每个叶子节点的路径表示为字
符的编码;
6. 将文件中出现的字符依次用它们的编码代替,生成压缩文件。

霍夫曼编码的优点在于,能够根据文件本身的结构和不同字符的出现频率来确定每个字符的编码,从而实现更高效的压缩。

缺点在于,需要构造一棵霍夫曼树,造成一定的时间和空间开销。

同时,由于编码长度的变化,对于随机数据的压缩效果可能不如其他编码算法。

总之,霍夫曼编码是一种非常有效的无损数据压缩算法,广泛应用于文件压缩、通信、多媒体和图像压缩等领域。

图像的霍夫曼编码

图像的霍夫曼编码

实验六图像的霍夫曼编码一、实验目的:1)理解并熟练对图像进行霍夫曼编码的算法;2)进一步加深对所学数字图像处理内容的认识;3)能够利用各种软件对算法加以实现。

二、实验内容:1)对数字图像进行哈弗曼编码2)对数字图像进行算术编码3)分析所得到的结果。

三、实验原理哈夫曼(Huffman)编码是一种常用的压缩编码方法,是Huffman于1952年为压缩文本文件建立的。

它的基本原理是频繁使用的数据用较短的代码代替,较少使用的数据用较长的代码代替,每个数据的代码各不相同。

这些代码都是二进制码,且码的长度是可变的。

具体算法如下:1)首先统计出每个符号出现的频率,上例S0到S7的出现频率分别为4/14,3/14,2/14,1/14,1/14,1/14,1/14,1/14。

2)从左到右把上述频率按从小到大的顺序排列。

3)每一次选出最小的两个值,作为二叉树的两个叶子节点,将和作为它们的根节点,这两个叶子节点不再参与比较,新的根节点参与比较。

4)重复(3),直到最后得到和为1的根节点。

5)将形成的二叉树的左节点标0,右节点标1。

把从最上面的根节点到最下面的叶子节点途中遇到的0,1序列串起来,就得到了各个符号的编码。

四、实验过程1)实验流程图程序入口函数WinMa注册主窗口类MyRegisterClass主窗口实例化InitInstance消息循环分发消息响应WM_COMMAND消息调用LoadBmpFile函数加载BMP图象文件响应WM_PAINT消息在主窗口内显示bmp对工具栏选项进行处理,调用霍夫曼函数进行编码消息处理函数WndProc霍夫曼编码示意图如下:2)实验代码见实验报告附页。

五、实验结果1)打开要进行编码的图片,如下图所示:2)对图片进行霍夫曼编码,得到如下结果:六、实验总结1)通过本实验,进一步加深了对霍夫曼编码的实验原理和算法的理解和认识;2)加强了分析问题和解决问题的能力;3)熟练了软件的使用能力,提高了利用软件对数字图像进行处理的能力。

图像编程霍夫曼图像压缩重建【matlab源码】

图像编程霍夫曼图像压缩重建【matlab源码】

毕业论文(设计)题目学院学院专业学生姓名学号年级级指导教师教务处制表matlab图像编程霍夫曼图像压缩重建一、程序说明本团队长期从事matlab编程与仿真工作,擅长各类毕业设计、数据处理、图表绘制、理论分析等,程序代做、数据分析具体信息联系二、程序示例function SnapImage()imagesPath = '.\\snap_images';if ~exist(imagesPath, 'dir')mkdir(imagesPath);end[FileName,PathName,FilterIndex] = uiputfile({'*.jpg;*.tif;*.png;*.gif','All Image Files';...'*.*','All Files' },'保存截图',...'.\\snap_images\\temp.jpg');if isequal(FileName, 0) || isequal(PathName, 0)return;endfileStr = fullfile(PathName, FileName);f = getframe(gcf);f = frame2im(f);imwrite(f, fileStr);msgbox('抓图文件保存成功!', '提示信息');function SaveImage(Img)imagesPath = '.\\results';if ~exist(imagesPath, 'dir')mkdir(imagesPath);end[FileName,PathName,FilterIndex] = uiputfile({'*.jpg;*.tif;*.png;*.gif','All Image Files';...'*.*','All Files' },'保存截图',...'.\\results\\result.jpg');if isequal(FileName, 0) || isequal(PathName, 0)return;endfileStr = fullfile(PathName, FileName);imwrite(mat2gray(Img), fileStr);function S=PSNR(sss,aaa)[m n p]=size(sss);A=double(sss);B=double(aaa);sumaDif=0;maxI=m*n*max(max(A.^2));for u=1:mfor v=1:nsumaDif=sumaDif+(A(u,v)-B(u,v))^2;endendif (sumaDif==0)sumaDif=1;endS=maxI/sumaDif;S=10*log10(S);function [zvec, zi] = Mat2Huff(vec)if ~isa(vec,'uint8')fprintf('\n请确认输入uint8类型数据向量!\n');return;endvec = vec(:)';f = Frequency(vec);syminfos = find(f~=0);f = f(syminfos);[f, sind] = sort(f);syminfos = syminfos(sind);len = length(syminfos);syminfos_ind = num2cell(1:len);cw_temp = cell(len,1);while length(f)&gt;1ind1 = syminfos_ind{1};ind2 = syminfos_ind{2};cw_temp(ind1) = AddNode(cw_temp(ind1),uint8(0));cw_temp(ind2) = AddNode(cw_temp(ind2),uint8(1));f = [sum(f(1:2)) f(3:end)];syminfos_ind = [{[ind1 ind2]} syminfos_ind(3:end)]; [f,sind] = sort(f);syminfos_ind = syminfos_ind(sind);endcw = cell(256,1);cw(syminfos) = cw_temp;len = 0;for i = 1 : length(vec),len = len+length(cw{double(vec(i))+1}); endstr_temp = repmat(uint8(0),1,len);pt = 1;for index=1:length(vec)cd = cw{double(vec(index))+1};len = length(cd);str_temp(pt+(0:len-1)) = cd;pt = pt+len;endlen = length(str_temp);pad = 8-mod(len,8);if pad &gt; 0str_temp = [str_temp uint8(zeros(1,pad))]; endcw = cw(syminfos);cl = zeros(size(cw));ws = 2.^(0:51);mcl = 0;for index = 1:length(cw)len = length(cw{index});if len&gt;mclmcl = len;endif len&gt;0cd = sum(ws(cw{index}==1));cd = bitset(cd,len+1);cw{index} = cd;cl(index) = len;endendcw = [cw{:}];cols = length(str_temp)/8;str_temp = reshape(str_temp,8,cols);ws = 2.^(0:7);zvec = uint8(ws*double(str_temp));huffcodes = sparse(1,1);for index = 1:numel(cw)huffcodes(cw(index),1) = syminfos(index);endzi.pad = pad;zi.huffcodes = huffcodes;zi.ratio = cols./length(vec);zi.length = length(vec);zi.maxcodelen = mcl;function vec = Huff2Mat(zvec, zi)if ~isa(zvec,'uint8')fprintf('\n请确认输入uint8类型数据向量!\n');return;endlen = length(zvec);str_tmp = repmat(uint8(0),1,len.*8);bi = 1:8;for index = 1:lenstr_tmp(bi+8.*(index-1)) = uint8(bitget(zvec(index),bi));endstr_tmp = logical(str_tmp(:)');len = length(str_tmp);str_tmp((len-zi.pad+1):end) = [];len = length(str_tmp);vec = repmat(uint8(0),1,zi.length);vi = 1;ci = 1;cd = 0;for index = 1:lencd = bitset(cd,ci,str_tmp(index));ci = ci+1;byte = Decode(bitset(cd,ci),zi);if byte &gt; 0vec(vi) = byte-1;ci = 1;cd = 0;vi = vi+1;endendfunction InitFig(hObject,handles)axes(handles.axes1);cla; axis on; box on;set(gca, 'Color', [0.8039 0.8784 0.9686]);set(gca, 'XTickLabel', [], 'YTickLabel', [], 'XTick', [], 'YTick', []);axes(handles.axes2);cla; axis on; box on;set(gca, 'Color', [0.8039 0.8784 0.9686]);set(gca, 'XTickLabel', [], 'YTickLabel', [], 'XTick', [], 'YTick', []);set(handles.textInfo, 'String', ...'图像压缩系统,载入图像,选择压缩算法,比较压缩效果。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

clearX=imread('lena512.bmp');data=uint8(X);[zipped,info]=huffencode(data); %调用Huffman编码程序进行压缩unzipped=huffdecode(zipped,info,data);%调用Huffman编码程序进行解码%显示原始图像和经编码后的图像,显示压缩比,并计算均方根误差得erms=0,表示是Huffman是无失真编码subplot(121);imshow(data);subplot(122);imshow(unzipped);%erms=compare(data(:),unzipped(:))cr=info.ratiowhos data unzipped zippedfunction [zipped, info] = huffencode(vector)% 输入和输出都是uint8 格式% 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');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);% 生成Huffman 树,得到码字编码表while length(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;for index = 1:length(vector) %得到整个图像所有比特数len = len + length(codeword{double(vector(index))+1}); endstring = repmat(uint8(0), 1, len);pointer = 1;for index = 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);if pad > 0string = [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(codeword{index});if len > maxcodelen;maxcodelen = len;endif len > 0code = 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);for index = 1:nnz(codeword) % length(codeword) %numel(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;%函数addnode添加节点function codeword_new = addnode(codeword_old, item)codeword_new = cell(size(codeword_old));for index = 1:length(codeword_old)codeword_new{index} = [item codeword_old{index}];end%函数frequency计算各符号出现的概率function f = frequency(vector)if ~isa(vector, 'uint8')error('input argument must be a uint8 vector');endf = repmat(0, 1, 256);len = length(vector);for index = 0:255f(index+1) = sum(vector == uint8(index));endf = f./len; %归一化function vector = huffdecode(zipped, info, image)% 函数对输入矩阵vector进行Huffman解码,返回解压后的图像数据if ~isa(zipped, 'uint8')error('input argument must be be a uint8 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);string ((len-info.pad+1):end)=[];len = length(string);%开始解码weights = 2.^(0:51);vector = repmat(uint8(0), 1, info.length);vectorindex = 1;codeindex = 1;code = 0;for index = 1:lencode = bitset(code, codeindex, string(index));codeindex = codeindex+1;byte = decode(bitset(code, codeindex), info);if byte > 0vector(vectorindex) = byte-1;codeindex = 1;code = 0;vectorindex = vectorindex + 1;endendvector = reshape(vector, info.rows, info.cols);%函数decode返回码字对应的符号function byte = decode(code, info)byte = info.huffcodes(code);。

相关文档
最新文档