霍夫曼信源编码实验报告

时间:2024.5.2

实验1:霍夫曼信源编码综合设计

【实验目的】

通过本专题设计,掌握霍夫曼编码的原理和实现方法,并熟悉利用C语言进行程序设计,对典型的文本数据和图像数据进行霍夫曼编解码。

【预备知识】

1、熵的概念,霍夫曼编码原则

2、数据结构和算法设计

3、C(或C++)编程语言

【实验环境】

1、设备:计算机一台

2、软件:C程序编译器

【设计要求】

根据霍夫曼编码原则,利用C语言设计并实现霍夫曼编码和解码程序,要求能够对给出的典型文本数据和图像数据进行霍夫曼编解码,并计算相应的熵和压缩比。

【实验原理】

Huffman编码属于熵编码的方法之一,是根据信源符号出现概率的分布特性而进行的压缩编码。

Huffman编码的主要思想是:出现概率大的符号用长的码字表示;反之,出现概率小的符号用短的码字表示。

Huffman编码过程描述:

1. 初始化:

    将信源符号按出现频率进行递增顺序排列,输入集合L;

2. 重复如下操作直至L中只有1个节点:

(a) 从L中取得两个具有最低频率的节点,为它们创建一个父节点;

(b) 将它们的频率和赋给父结点,并将其插入L;

3. 进行编码 :

    从根节点开始,左子节点赋予1,右节点赋予0,直到叶子节点。

【基本定义】

1.      熵和平均编码符号长度

熵是信息量的度量方法,它表示某一事件出现的概率越小,则该事件包含的信息就越多。根据Shannon理论,信源S的熵定义为,其中是符号在S中出现的概率;表示包含在中的信息量,也就是编码所需要的位数

假设符号编码后长度为li (i=1,…,n),则平均编码符号长度L为:

2.      压缩比

设原始字符串的总长度为Lorig位,编码后的总长度为Lcoded位,则压缩比R为

       R = (Lorig - Lcoded)/ Lorig

【例子】

有一幅40个象素组成的灰度图像,灰度共有5级,分别用符号A、B、C、D和E表示,40个象素中出现灰度A的象素数有15个,出现灰度B的象素数有7个,出现灰度C的象素数有7个等等,如表1所示。如果用3个位表示5个等级的灰度值,也就是每个象素用3位表示,编码这幅图像总共需要120位。

表1 符号在图像中出现的数目

根据Shannon理论,这幅图像的熵为
H(S) = (15/40)´(40/15)+(7/40)´(40/7)+???+(5/40)´(40/5)=2.196

平均编码符号长度L为(15/40)*1+(7/40)*3+(7/40)*3+(6/40)*3+(5/40)*3 = 2.25

根据霍夫曼编码原则可以得到如下的霍夫曼编码表。

表2 霍夫曼编码举例

因而,这副图采用霍夫曼编码的压缩比R为1.3333:1(120:90)。

霍夫曼码的码长虽然是可变的,但却不需要另外附加同步代码。例如,码串中的第1位为0,那末肯定是符号A,因为表示其他符号的代码没有一个是以0开始的,因此下一位就表示下一个符号代码的第1位。同样,如果出现“110”,那么它就代表符号D。如果事先编写出一本解释各种代码意义的“词典”,即码簿,那么就可以根据码簿一个码一个码地依次进行译码。

【实验步骤】(16学时)

根据提供的示例Huffman编译码器源程序,利用VC++6.0进行编译生成可执行文件,阅读并运行程序。

1、用Microsoft Office Vision分别画出Huffman编码和译码程序流程图,写出用到的主要数据结构并加以说明。

2、在Huffman编码器合适位置加入4个函数:calcProbability,calcEntropy,calcAvgSymbolLength,calcCompressionRatio,分别计算信源各符号出现的概率、信源的熵、平均编码符号长度以及压缩比。(自定义函数的参数)

3、分析霍夫曼编译码码的计算复杂度,定量说明Huffman编码和译码哪种操作更耗时?

4、设计中遇到的问题,怎样解决问题的。在设计过程中的心得体会。

思考题:

1、霍夫曼编码是否具有唯一性?

2、个人对霍夫曼编码方式的不足之处的思考以及怎么样在进行压缩时避免这些问题。

3、分析霍夫曼编码对文本数据以及图象数据的编码效率,观察与对应信源概率分布的关系。

4、参考静止图像压缩编码国际标准JPEG,为了提高对图像编码的效率,通常要在霍夫曼编码之前进行什么操作?

5、。

【实验结果】

一.译码与编码流程图如下所示:

1.译码流程图

霍夫曼信源编码实验报告

2.编码流程图

霍夫曼信源编码实验报告

二.四个部分的程序

1.计算每个个符号出现的概率

void calcProbability(int total, SymbolFrequencies *pSF)

{

       int i;

       float prob[MAX_SYMBOLS];

       memset(prob, 0, sizeof(prob));

       for(i = 0; i < MAX_SYMBOLS; ++i)

       {

              if((*pSF)[i])

              {

                     prob[i] = (float)(*pSF)[i]->count / total;

                     printf("%c, %f\n", (*pSF)[i]->symbol, prob[i]);

              }

       }

}

2.计算熵

void calcEntrop(SymbolFrequencies *pSF)

{

       int i;

       float prob[MAX_SYMBOLS];

       double entropy;

       double difference;

       double difference1;

       double difference2;

       entropy = 0;

      

       for(i = 0; i < MAX_SYMBOLS; ++i)

       {

              difference1 = log(prob[i]);

              difference2 = log(2);

              difference = difference1/difference2;

              entropy = entropy - prob[i]*difference;

       }

              printf(" %f\n", entropy);

}

3.计算平均长度

void calcAvgSymbolLength(SymbolFrequencies *pSF, *bits[MAX_SYMBOLS])

{

       int i;

       double AvgSymbolLength;

       AvgSymbolLength = 0;

       for(i = 0; i < MAX_SYMBOLS; ++i)

       {

              AvgSymbolLength = AvgSymbolLength + prob[i]*numbytes[i];

       }

              printf(" %f\n", AvgSymbolLength);

}

4.计算压缩比

void calcCompressionRatio(int total, AvgSymbolLength)

{

       doubule Ratio;

       doubule CompressionRatio;

       Ratio = total – AvgSymbolLength* MAX_SYMBOLS;

       CompressionRatio = Ratio/total;

}

三.           分析耗时

从Huffman编码和译码的代码相比较,可以看出译码的操作更加耗时。

四.遇到的问题

       在这次实验中,由于以前并没有学过C++,所以在编程期间遇到很多基础性的问题,对于语言的运用不熟悉,所以导致在写出代码之后编译很久都不成功,但是在老师的辅导下,还是可以做出来一些成果,对于C++的运用有了一定的了解和运用。虽然在这次实验中,并没有将老师所布置的任务全部完成,但是在经过了将近三个星期的反复调试,将最基础最简单的任务完成了。其中或许有些错误,但是已经是尽了全力去完成的。

五.思考题

1.霍夫曼编码是否具有唯一性?

答:霍夫曼信源不具有唯一性,可将1与0交换。

2.参考静止图像压缩编码国际标准JPEG,为了提高对图像编码的效率,通常要在霍夫曼编码之前进行什么操作?

答:参考静止图像压缩编码国际标准JPEG,为了提高对图像编码的效率,通常要在霍夫曼编码之前进行数据压缩。

3.通过本综合设计,谈谈对“算法+数据结构=程序”的认识

答:程序是计算机指令的某种组合,控制计算机的工作流程,完成一定的逻辑功能,以实现某种任务;算法是程序的逻辑抽象,是解决某类客观问题的数学过程;在这里,数据结构具有两个层面上的涵义--逻辑结构和物理结构:客观事物自身所具有的结构特点,我们将其称之为逻辑结构。算法的确定依赖于数据结构的选择,数据结构的选择制约于算法设计的复杂程度--算法 + 数据结构 = 程序。


第二篇:霍夫曼编码的matlab实现(信源编码实验)


重庆交通大学信息科学与工程学院

综合性设计性实验报告

专 业  班 级:通信工程20121 

学        号:      631206040118   

姓        名:         王松        

实验所属课程:     信息论与编码     

实验室(中心):   软件与通信实验中心  

指 导 教 师 :         黄大荣       

  

20##年4月

霍夫曼编码的matlab实现

一、实验目的和要求。

利用哈夫曼编码进行通信可以大大提高信道的利用率,缩短信息传输的时间,降低传输成本。

本实验用Matlab语言编程实现霍夫曼(Huffman)编码。

二、实验原理

霍夫曼(Huffman)编码算法是满足前缀条件的平均二进制码长最短的编-源输出符号,而将较短的编码码字分配给较大概率的信源输出。算法是:在信源符号集合中,首先将两个最小概率的信源输出合并为新的输出,其概率是两个相应输出符号概率之和。这一过程重复下去,直到只剩下一个合并输出为止,这个最后的合并输出符号的概率为1。这样就得到了一张树图,从树根开始,将编码符号1 和0 分配在同一节点的任意两分支上,这一分配过程重复直到树叶。从树根到树叶途经支路上的编码最后就构成了一组异前置码,就是霍夫曼编码输出。

离散无记忆信源:

例如

      U           u1    u2    u3   u4   u5

     P(U)    =    0.4   0.2   0.2  0.1  0.1   

通过上表的对信源缩减合并过程,从而完成了对信源的霍夫曼编码。

三、实验步骤

分为两步,首先是码树形成过程:对信源概率进行合并形成编码码树。然后是码树回溯过程:在码树上分配编码码字并最终得到霍夫曼编码。

1、码树形成过程:将信源概率按照从小到大顺序排序并建立相应的位置索引。然后按上述规则进行信源合并,再对信源进行排序并建立新的位置索引,直到合并结束。在这一过程中每一次都把排序后的信源概率存入矩阵G中,位置索引存入矩阵Index中。这样,由排序之后的概率矩阵 G以及索引矩阵Index就可以恢复原概率矩阵P了,从而保证了回溯过程能够进行下去。

2、码树回溯过程在码树上分配编码码字并最终得到Huffman 编码。从索引矩阵M 的末行开始回溯。

(1) 在Index的末行2元素位置填入0和1。

(2) 根据该行索引1 位置指示,将索引1 位置的编码(‘1’)填入上一行的第一、第二元素位置,并在它们之后分别添加‘0’和‘1’。

(3) 将索引不为‘1’的位置的编码值(‘0’)填入上一行的相应位置(第3 列)。

(4) 以Index的倒数第二行开始向上,重复步骤(1) ~ (3),直到计算至Index的首行为止。

四、程序代码:

%取得信源概率矩阵,并进行合法性判断

clear;

P=input('请输入信源概率向量P=');

N=length(P);

for component=1:1:N

    if(P(component)<0)

     error('信源概率不能小于0');

 end

end

if((sum(P)-1)>0.0001)

    error('信源概率之和必须为1');

end

%建立各概率符号的位置索引矩阵Index,利于编码后从树根进行回溯,从而得出对应的编码

Q=P

Index=zeros(N-1,N);  %初始化Index 

for i=1:N-1 

   [Q,L]=sort(Q); 

   Index(i,:)=[L(1:N-i+1),zeros(1,i-1)];

   G(i,:)=Q;

   Q=[Q(1)+Q(2),Q(3:N),1]; %将Q中概率最小的两个元素合并,元素不足的地方补1

end

%根据以上建立的Index矩阵,进行回溯,获取信源编码

for i=1:N-1

    Char(i,:)=blanks(N*N);%初始化一个由空格符组成的字符矩阵N*N,用于存放编码

end

%从码树的树根向树叶回溯,即从G矩阵的最后一行按与Index中的索引位置的对应关系向其第一行进行编码

Char(N-1,N)='0';%G中的N-1行即最后一行第一个元素赋为0,存到Char中N-1行的N列位置

Char(N-1,2*N)='1';%G中的N-1行即最后一行第二个元素赋为1,存到Char中N-1行的2*N列位置

%以下从G的倒数第二行开始向前编码

for i=2:N-1 

   Char(N-i,1:N-1)=Char(N-i+1,N*(find(Index(N-i+1,:)==1)) -(N-2):N*(find(Index(N-i+1,:)==1)));

   %将Index后一行中索引为1的编码码字填入到当前行的第一个编码位置

   Char(N-i,N)='0'; %然后在当前行的第一个编码位置末尾填入'0'

   Char(N-i,N+1:2*N-1)=Char(N-i,1:N-1); %将G后一行中索引为1的编码码字填入到当前行的第二个编码位置

   Char(N-i,2*N)='1';  %然后在当前行的第二个编码位置末尾填入'1'

   for j=1:i-1 

 %内循环作用:将Index后一行中索引不为1处的编码按照左右顺序填入当前行的第3个位置开始的地方,最后计算到Index的首行为止

      Char(N-i,(j+1)*N+1:(j+2)*N)=Char(N-i+1,N*(find(Index(N-i+1,:)==j+1)-1)+1:N*find(Index(N-i+1,:)==j+1)); 

 end 

end 

 %Char中第一行的编码结果就是所需的Huffman 编码输出,通过Index中第一行索引将编码对应到相应概率的信源符号上。

   for i=1:N 

      Result(i,1:N)=Char(1,N*(find(Index(1,:)==i)-1)+1:find(Index(1,:)==i)*N);

  end 

  %打印编码结果

  String='信源概率及其对应的Huffman编码如下';

  disp(String);disp(P);disp(Result);

五、对比分析,通过给给定不同的信源,对结果进行分析对比验证,并得出相应分分析报告。

以[0.1,0.2,0.3,0.2,0.1,0.1]为例:

运行程序,结果如下

以[0.3 0.3 0.2 0.1 0.1]为例:

运行程序,结果如下

分析:由上图可知程序已完成了Huffman编码的功能,但是霍夫曼编码是不唯一的.因为:信源符号合并中遇到最小概率相同的情况时可任意选择来做合并;在码树分配编码码字的时候1 和0 的位置可以是任意的。

六:提交实验报告。

1、在该实验的过程中,利用一个矩阵记录每次排序前概率的所在位置,是该实验的关键,在编码的过程中利用该矩阵就能比较容易进行huffman编码。 

2、通过这个实验,对huffman编码的具体实现原理了解的更加深刻,在实验的过程中也遇到了一些问题,通过查找资料和相关书籍得到了解决,通过此次试验,了解了Huffman编码的特点,能够运用Huffman编码的基本原理及编码算法的来设计与实现程序。收获颇多,为以后更进一步学习奠定了基础, 总的来说,在完成该实验的过程中,学到了比较多的知识,包括使对一些matlab语句的掌握的更加熟练,完成一个算法必须要有一个整体的把握等等。

3、通过本次课程设计,我对二叉树和huffman编码树有了更深的了解,在做课程设计的过程中我掌握了二元huffman编码树的构造方法,哈夫曼编码是一种变长的编码方案。它由最优二叉树既哈夫曼树得到编码,码元内容为到根结点的路径中与父结点的左右子树的标识。所以哈夫曼在编码在数字通信中有着重要的意义。可以根据信源符号的使用概率的高低来确定码元的长度。既实现了信源的无失真地编码,又使得编码的效率最高。

更多相关推荐:
哈夫曼编码实验报告

哈夫曼编码器实验报告学院:计算机学院班级:计科0801班姓名:***学号:***一.实验目的练习树和哈夫曼树的有关操作,和各个算法程序,理解哈夫曼树的编码和译码二.实验环境Microsoftvisualc++三…

C语言-哈夫曼编码实验报告

福建工程学院课程设计课程数据结构题目哈夫曼编码和译码专业信息管理信息系统班级座号15号姓名林左权20xx年6月27日1实验题目哈夫曼编码和译码一要解决的问题利用哈夫曼编码进行信息通信可以大大提高信道利用率缩短信...

哈夫曼编码译码系统课程设计实验报告(含源代码C++_C语言)[1]

东北电力大学计算机科学与技术专业综合设计报告目录摘要IIAbstractII第一章课题描述111问题描述112需求分析113程序设计目标第二章设计简介及设计方案论述221设计简介222设计方案论述223概要设计...

霍夫曼编码实验报告(C++)

计算机科学与工程系一实验名称霍夫曼编码二实验环境软件环境Windows20xxMicrosoftVisualC60硬件环境P424GHz256内存IBMPC及兼容机三实验目的掌握霍夫曼编码译码原理并能够通过程序...

哈夫曼编码实验报告

数据结构实验班级软件C092姓名孙琼芳学号098586一实验目的利用哈夫曼编码进行通信可以大大提高信道利用率缩短信息传输时间降低传输成本但是这要求在发送端通过一个编码系统对待传数据预先编码在接收端将传来的数据进...

哈夫曼编码实验报告

实验报告与总结一实验目的1掌握哈夫曼编码原理2熟练掌握哈夫曼树的生成方法3理解数据编码压缩和译码输出编码的实现二实验要求实现哈夫曼编码和译码的生成算法三实验内容先统计要压缩编码的文件中的字符字母出现的次数按字符...

哈夫曼编码实验报告

北京邮电大学信息与通信工程学院数据结构实验报告实验名称实验三哈夫曼编码学生姓名牛佳宁班级20xx211107班内序号27学号10210213日期20xx年12月10日1实验要求利用二叉树结构实现赫夫曼编解码器1...

Huffman编解码实验报告

文本文件的二进制预统计Huffman编解码一实验目的1熟悉Huffman编解码算法2理解Huffman编码的最佳性二实验内容1编程思想霍夫曼Huffman编码是19xx年为文本文件而建立是一种统计编码属于无损压...

实验报告-2 Huffman编码

信息与编码课内实验报告学生姓名及学号学院班级课程名称实验题目指导教师姓名及职称理学院信息与编码Huffman编码副教授讲师实验师20xx年3月14日目录一实验目的1二实验内容1三实验要点及说明1四实现方法1五实...

信息论与编码实验报告

信息论与编码实验报告学院计算机与通信工程学院专业计算机科学与技术班级计1203班学号姓名20xx年12月29日实验一唯一可译码判别准则实验目的1进一步熟悉唯一可译码判别准则2掌握C语言字符串处理程序的设计和调试...

数据结构实验报告八—哈夫曼编译码

问题描述利用哈夫曼编码进行通信可以大大提高信道利用率缩短信息传输时间降低传输成本但是这要求在发送端通过一个编码系统对待传数据预先编码在接收端将传来的数据进行译码复原对于双工通信即可以双向传输信息的信道每端都需要...

霍夫曼编码的matlab实现(信源编码实验)

重庆交通大学信息科学与工程学院综合性设计性实验报告专业班级通信工程20xx级1班学号63120xx40118姓名王松实验所属课程信息论与编码实验室中心软件与通信实验中心指导教师黄大荣20xx年4月霍夫曼编码的m...

霍夫曼编码实验报告(37篇)