huffman编码的matlab实现
matlab 霍夫曼编码
matlab 霍夫曼编码一、背景介绍二、霍夫曼编码原理三、matlab实现霍夫曼编码1. 建立霍夫曼树2. 构建编码表3. 压缩文件4. 解压文件四、应用举例一、背景介绍在信息传输和存储中,数据的压缩是一个重要的问题。
其中,霍夫曼编码是一种常用的无损压缩算法,通过对不同字符出现频率进行编码,可以将数据压缩到较小的空间中。
在matlab中,可以通过代码实现对数据的霍夫曼编码。
二、霍夫曼编码原理1. 需要进行压缩的数据由若干个字符组成。
2. 统计每个字符出现的频率,并根据频率构建霍夫曼树。
3. 根据霍夫曼树构建每个字符对应的编码表。
4. 将原始数据中每个字符按照对应的编码表进行编码,并将所有编码拼接为一个字符串。
5. 将字符串转换为二进制数列,并将其写入文件中。
解压时,需要读取二进制数列,并按照相应的编码表进行解码还原原始数据。
三、matlab实现霍夫曼编码1. 建立霍夫曼树在matlab中,可以通过以下代码实现霍夫曼树的构建:```matlabfunction [T, f] = huffmantree(p)n = length(p);f = p;T = zeros(n-1, 3);for i=1:n-1[f, j] = sort(f);T(i, 1:2) = j(1:2);T(i, 3) = f(1) + f(2);f(2) = T(i, 3);end```其中,p为每个字符出现的频率,n为字符数。
函数返回的T为霍夫曼树的结构矩阵,f为每个节点的权值。
2. 构建编码表在得到霍夫曼树之后,可以通过以下代码构建每个字符对应的编码表:```matlabfunction codebook(T)n = size(T, 1) + 1;codebook = cell(n, 2);for i=1:ncodebook{i, 1} = i;endfor i=1:n-1j = T(i, 1:2);for k=1:length(j)codebook{j(k), 2}=[codebook{j(k), 2},num2str(mod(k-1,2))]; if ~isempty(codebook{j(k), 2})codebook{j(k), 3}=[codebook{j(k), 3},i];elsecodebook{j(k), 3}=i;endendend```其中,codebook为编码表,第一列为字符编号,第二列为对应的编码。
编写matlab函数实现huffman编码的算法
在区域内的随机变量的所有值都被量化为第 i 个量化级数,用 X i 来表示,这就意 味着:
x Ri ( x) xi
显而易见,这类量化引入了失真,其均方误差为:
d i 1 ( x xi ) 2 f x( x)dx
这称为 Kraft 不等式。
q
i 1
r li 1
(8)
由上式可知,给定 r 和 q,只要允许码字长度可以足够长,则码长总可以满 足 Kraft 不等式而得到即时码,Kraft 不等式指出了即时码的码长必须满足的条 件。后来 McMillan 证明对于唯一可译码得码长也必须满足此不等式。在码长的 选择上唯一可译码并不比即时码有更宽松的条件。对于唯一可译码,该不等式又 称为 McMillan 不等式。 唯一可译码存在的充要条件是:
展信源进行编码, 当 N 趋向于无穷时, 平均码长可以趋进该极限值。 还可以证明, 如果我们不确切知道信源的概率分布,我们用估计的概率分布去进行编码时,平 均码长会加长,但是如果估计的偏差不大的话,平均码长也不会增加太多。 2.4 无失真编码算法 2.4.1 无失真信源编码定理 设单符号、离散、无记忆信源的熵为 H(S),若用二进制码对其做变字长、非 续长编码,一定可以找到一种编码方式,其平均码长满足:
q
i 1
r li 1
(9)
其中 r 为码符号个数,为码字长度,q 为信源符号个数 无失真变长信源编码定理 离散无记忆信源 S 的 N 次扩展信源 S N ,其熵为 H (S N ) ,并且编码器的码元 符号集为 A : {a1 , a2 ,..., aq } 对信源 S N 进行编码,总可以找到一种编码方法,构成唯 一可译码,使信源 S 中每个符号 Si 所需要的平均码长满足
信息论与编码课程作业_huffman编码的matlab_实现
信息论与编码课程作业——霍夫曼编码求信源熵和存储前后的信息量的变化一:设计目的:1、学习离散信源平均信息量的计算方法。
2、理解和掌握huffman 编码的基本原理,实现对信源符号的huffman 编码3、熟悉 Matlab 编程; 二:设计原理和思路1.信源熵的计算:公式: 21()log a I a p = Matlab 实现:I=log2(1/p) 或I=-log2(p) 熵(平均自信息)的计算公式22111()log log qq i i i i i i H x p p p p ====-∑∑Matlab 实现:HX=sum(-x.*log2(x));或者h=h-x(i)*log2(x(i));2.霍夫曼编码原理;分为两步,首先是码树形成过程:对信源概率进行合并形成编码码树。
然后是码树回溯过程:在码树上分配编码码字并最终得到Huffman 编码。
1、码树形成过程:将信源概率按照从小到大顺序排序并建立相应的位置索引。
然后按上述规则进行信源合并,再对信源进行排序并建立新的位置索引,直到合并结束。
在这一过程中每一次都把排序后的信源概率存入矩阵p 中,位置索引存入矩阵m 中。
这样,由排序之后的概率矩阵 p 以及索引矩阵m 就可以恢复原概率矩阵P 了,从而保证了回溯过程能够进行下去。
2、码树回溯过程:在码树上分配编码码字并最终得到Huffman 编码。
从索引矩阵M 的末行开始回溯。
(1) 在p 的末行2元素位置填入0和1。
(2) 根据该行索引1位置指示,将索引1位置的编码(‘1’)填入上一行的第一、第二元素位置,并在它们之后分别添加‘0’和‘1’。
(3) 将索引不为‘1’的位置的编码值(‘0’)填入上一行的相应位置(第3 列)。
(4) 以m的倒数第二行开始向上,重复步骤(1) ~ (3),直到计算至m的首行为止。
三:设计代码:>> clear all;format longdisp(strcat('信息论与编码课程作业——霍夫曼编码求信源熵和存储前后的信息量的变化',13));histgram=zeros(1,255);[c,map]=imread('C:\Documents and Settings\Administrator\桌面\infomation\lenna.bmp');x=rgb2gray(c);[a,b]=size(x);for i=1:afor j=1:bk=x(i,j);histgram(k)=histgram(k)+1;endendf=histgram/a/b;symbols=find(f~=0); %灰度值p=f(symbols); %概率L=length(p);pp=p;%霍夫曼编码m=zeros(L-1,L);for i=1:L-1[p,mark]=sort(p);m(L-i,1:L-i+1)=mark(1:L-i+1);p=[p(1)+p(2),p(3:L),1];endc=cell(L-1,L);c(1,1)={'0'};c(1,2)={'1'};for i=2:L-1;ind=find(m(i-1,:)==1);temp=char(c(i-1,ind));c(i,1)={[temp,'0']};c(i,2)={[temp,'1']};snc=find(m(i-1,:)~=1);for j=3:i+1;con=snc(j-2);c(i,j)=c(i-1,con);endendcodeL=[];averge_long=0;H1=0;disp(strcat('灰度值',32,32,32,'概率',32,32,32,32,32,32,32,32,32,'霍夫曼编码:'));for i=1:L;ind=find(m(L-1,:)==i);code=char(c(L-1,ind));codeLength(i)=length(code);averge_long=averge_long+pp(i)*codeLength(i);H1=H1+pp(i)*log2(1/pp(i));disp(strcat(32,num2str(symbols(i)),32,32,32,num2str(pp(i)),32,32, code));enddisp(strcat('信源熵=',num2str(H1),32,32,32,32,'平均码字长度=',num2str(averge_long),32,32,32,32,32,'压缩比=',num2str(8/averge_long)));四:设计运行结果:信息论与编码课程作业——霍夫曼编码求信源熵和存储前后的信息量的变化灰度值概率霍夫曼编码:30 1.5259e-005 101000111100001031 1.5259e-005 101000111100001136 1.5259e-005 101000111100000037 1.5259e-005 101000111100000139 6.1035e-005 1010001111000140 7.6294e-005 1110010101001041 6.1035e-005 0111010111011042 6.1035e-005 0111010111011143 9.1553e-005 1110010101001144 0.00018311 111011101010145 0.00021362 00111101101146 0.00022888 01110101111047 0.00024414 01110101111148 0.00039673 0011110110049 0.00048828 1010001110050 0.00065613 1110010101151 0.00090027 011101011052 0.00086975 001111011153 0.0013123 111001011054 0.0013733 111011101155 0.0015411 00010101156 0.0018005 01110101057 0.0025177 11010001158 0.0036621 0111111059 0.0033722 0101111060 0.0046539 1100110161 0.0055847 1111010162 0.0061188 001001063 0.0080261 100111064 0.0075226 100001165 0.0083466 101010166 0.0088806 101111167 0.0092773 110011168 0.0095367 110101069 0.0086517 101101070 0.0084229 101011071 0.0075378 100010172 0.0071564 011011173 0.0061493 001001174 0.0056 1111011075 0.0053864 1110110076 0.0045319 1100011177 0.0043488 1011000178 0.0042114 1010111079 0.0039063 1000111180 0.0041199 1010100181 0.0035706 0110101182 0.0039368 1001011083 0.0037537 1000010084 0.003479 0110101085 0.0036011 0111000186 0.0033417 0101101087 0.0032501 0100110088 0.0034027 0110000189 0.0031128 0011010090 0.0031433 0011110091 0.0036774 0111111192 0.0041046 1010011094 0.0038452 1000111095 0.004364 1011100096 0.0037842 1000110097 0.0037079 1000001198 0.0033722 0101111199 0.0040741 10100001 100 0.0040741 10100010 101 0.0038147 10001101 102 0.0040588 10011111 103 0.0041046 10100111 104 0.004364 10111001 105 0.0048218 11010111 106 0.0052185 11100100 107 0.0049591 11011010 108 0.005188 11100001 109 0.0047455 11010110 110 0.0052032 11100011 111 0.0054474 11110100 112 0.0057526 11111011 113 0.0065308 0100111 114 0.0079346 1001100 115 0.010223 1101111116 0.0095825 1101100 117 0.0089417 1100000 118 0.0086975 1011011 119 0.0081787 1010010 120 0.007782 1001001121 0.0066376 0101011 122 0.0059357 11111111 123 0.0056458 11110111 124 0.0051575 11100000 125 0.0052948 11101001 126 0.005188 11100010 127 0.0059814 0000001 128 0.0058594 11111101 129 0.0065613 0101010 130 0.0062561 0011011 131 0.006897 0110100132 0.0072479 0111011 133 0.0073242 0111110 134 0.007309 0111101135 0.0075226 1000100 136 0.0077515 1001000138 0.008606 1011001139 0.0091095 1100100 140 0.012115 000010141 0.012115 000011142 0.012741 001110143 0.012329 001100144 0.010941 1111001145 0.010147 1101110146 0.0089417 1100001 147 0.0088043 1011101 148 0.0091095 1100101 149 0.010712 1110101150 0.011337 1111100151 0.010513 1110011152 0.012878 010000153 0.012268 001010154 0.013138 010100155 0.012238 001000156 0.012939 010001157 0.012115 000100158 0.012955 010010159 0.012207 000111160 0.011993 000001161 0.013916 011001162 0.012177 000110163 0.012299 001011164 0.0094604 1101001 165 0.0089874 1100010 166 0.0088501 1011110 167 0.0056915 11111010 168 0.0059357 0000000 169 0.0071716 0111001 170 0.0057678 11111100 171 0.0054016 11101111 172 0.0054169 11110001 173 0.0058746 11111110 174 0.0072937 0111100 175 0.0070953 0110110 176 0.006424 0011111177 0.0061035 0001011 178 0.0054016 11110000 179 0.0053864 11101101 180 0.0046692 11010000182 0.0036774 10000000183 0.0033875 01100000184 0.0033264 01011000185 0.0031281 00110101186 0.0035706 01110000187 0.0033264 01011001188 0.0033569 01011011189 0.0036011 01110100190 0.0040436 10011110191 0.0034485 01100010192 0.0036774 10000001193 0.0032654 01001101194 0.0034485 01100011195 0.003006 00010100196 0.0033722 01011100197 0.0036774 10000010198 0.0042419 10110000199 0.0045166 11000110200 0.0041046 10101000201 0.0052643 11101000202 0.0050354 11011011203 0.0045319 11001100204 0.0039825 10011010205 0.0040588 10100000206 0.0039673 10010111207 0.0037537 10000101208 0.0033722 01011101209 0.0026703 111011100210 0.0022125 110100010211 0.0018768 101000110212 0.0015259 000101010213 0.0013428 1110010111214 0.0012665 1110010100215 0.0007782 0011110100216 0.00079346 0011110101217 0.00061035 10100011111218 0.00054932 10100011101219 0.00065613 11101110100220 0.00035095 111011101011 221 0.00033569 111001010101 222 0.00030518 101000111101 223 0.00021362 011101011100 224 0.00016785 1110111010100225 0.00019836 001111011010226 0.00015259 1110010101000227 0.00010681 0111010111010228 6.1035e-005 10100011110010230 3.0518e-005 101000111100110231 1.5259e-005 10100011110011110232 1.5259e-005 10100011110011111233 1.5259e-005 1010001111001110信源熵=7.2193 平均码字长度=7.2492 压缩比=1.1036五:设计新得体会:通过这学期对信息论和编码的学习,以及这次的设计,使我了解了很多东西,也使以前所学的知识得以巩固!,通过这次的设计,进一步学习了离散信源平均信息量、平均码长和压缩比的计算方法。
(完整word版)huffman编码的matlab实现
Huffman编码的matlab实现一、信源编码介绍为了减少信源输出符号序列中的剩余度、提高符号的平均信息量,对所施行的变换。
具体说,就是针对信源输出符号序列的统计特性来寻找某种方法,把信源输出符号序列变换为最短的码字序列,使后者的各码元所载荷的平均信息量最大,同时又能保证无失真地恢复原来的符号序列。
既然信源编码的基本目的是提高码字序列中码元的平均信息量,那么,一切旨在减少剩余度而对信源输出符号序列所施行的变换或处理,都可以在这种意义下归入信源编码的范畴,例如过滤、预测、域变换和数据压缩等。
当然,这些都是广义的信源编码。
一般来说,减少信源输出符号序列中的剩余度、提高符号平均信息量的基本途径有两个:①使序列中的各个符号尽可能地互相独立;②使序列中各个符号的出现概率尽可能地相等。
前者称为解除相关性,后者称为概率均匀化。
信源编码的一般问题可以表述如下:信源编码若某信源的输出为长度等于M的符号序列集合式中符号A为信源符号表,它包含着K个不同的符号,A={ɑk|k=1,…,K},这个信源至多可以输出K M个不同的符号序列。
记‖U‖=KM。
所谓对这个信源的输出信源编码进行编码,就是用一个新的符号表B的符号序列集合V来表示信源输出的符号序列集合U。
若V的各个序列的长度等于 N,即式中新的符号表B共含L个符号,B={b l|l=1,…,L}。
它总共可以编出L N个不同的码字。
类似地,记‖V‖=LN。
为了使信源的每个输出符号序列都能分配到一个独特的码字与之对应,至少应满足关系‖V‖=L N≥‖U‖=KM或者N/M≥log K/log L下面的几个编码定理,提供了解决这个矛盾的方法。
它们既能改善信息载荷效率,又能保证码字唯一可译。
离散无记忆信源的定长编码定理对于任意给定的ε>0,只要满足条件N/M≥(H(U)+ε)/log L那么,当M足够大时,上述编码几乎没有失真;反之,若这个条件不满足,就不可能实现无失真的编码。
matlab霍夫曼编码函数
matlab霍夫曼编码函数Matlab是一个广泛应用于科学计算和工程领域的高级计算机语言和环境。
它提供了各种函数和工具箱,可用于解决各种数学问题和实现不同的算法。
霍夫曼编码是一种数据压缩算法,它通过将频率最高的字符编码为较短的比特串,从而实现对数据的有效压缩。
在本文中,我们将介绍如何在Matlab中实现霍夫曼编码函数。
首先,我们需要了解霍夫曼编码的基本原理。
该算法基于字符出现的频率构建一个霍夫曼树,其中出现频率较高的字符位于树的较低层,而出现频率较低的字符位于树的较高层。
然后,通过从根节点到每个字符的路径上的比特串表示字符的编码。
这样,频率较高的字符将使用较短的比特串编码,而频率较低的字符将使用较长的比特串编码。
在Matlab中实现霍夫曼编码,我们首先需要计算每个字符在给定数据中的出现频率。
我们可以使用Matlab提供的`histcounts`函数来实现这一点。
`histcounts`函数将数据分成一定数量的称为“bins”的区间,并计算每个区间中的数据的频数。
matlabdata = 'abcdefgh'; 给定的数据frequencies = histcounts(data, unique(data)); 计算每个字符的频数上述代码首先定义了一个包含字符的字符串,然后使用`unique`函数获取字符串中的唯一字符。
然后,`histcounts`函数基于这些唯一字符计算每个字符的频数,并将结果存储在名为“frequencies”的数组中。
下一步是构建霍夫曼树。
我们可以使用以下步骤来实现此操作:1. 创建一个含有所有字符频数的结点集合,并按照频率从低到高对结点排序。
2. 从频率最低的两个结点中创建一个新的父节点,并将这个父节点的频率设置为这两个结点的频率之和。
将这个新的父节点添加到结点集合中,并删除这两个被合并的结点。
3. 重复步骤2,直到只剩下一个节点为止。
这个节点将成为霍夫曼树的根节点。
霍夫曼编码的MATLAB实现(完整版).pdf
%哈夫曼编码的 MATLAB 实现(基于 0、1 编码):clc;clear;A=[0.3,0.2,0.1,0.2,0.2];A=fliplr(sort(A));%T=A;信源消息的概率序列按降序排列[m,n]=size(A);B=zeros(n,n-1);% 空的编码表(矩阵)for i=1:nB(i,1)=T(i);%end生成编码表的第一列r=B(i,1)+B(i-1,1);%最后两个元素相加T(n-1)=r;T(n)=0;T=fliplr(sort(T));t=n-1;for j=2:n-1%生成编码表的其他各列for i=1:tB(i,j)=T(i);endK=find(T==r);B(n,j)=K(end);%%该列的位置从第二列开始,每列的最后一个元素记录特征元素在r=(B(t-1,j)+B(t,j));%T(t-1)=r;最后两个元素相加T(t)=0;T=fliplr(sort(T));t=t-1;end B;%输出编码表END1=sym('[0,1]');%给最后一列的元素编码END=END1;t=3;d=1;for j=n-2:-1:1%从倒数第二列开始依次对各列元素编码for i=1:t-2if i>1 & B(i,j)==B(i-1,j)d=d+1;elsed=1;end B(B(n,j+1),j+1)=-1;temp=B(:,j+1);x=find(temp==B(i,j));END(i)=END1(x(d));endy=B(n,j+1);END(t-1)=[char(END1(y)),'0'];END(t)=[char(END1(y)),'1'];t=t+1;END1=END;endA% 排序后的原概率序列END% 编码结果for i=1:n[a,b]=size(char(END(i)));L(i)=b;endavlen=sum(L.*A)% 平均码长H1=log2(A);H=-A*(H1')% 熵P=H/avlen%编码效率2。
信息论与编码课程作业_huffman编码的matlab_实现
信息论与编码课程作业_huffman编码的matlab_实现信息论与编码课程作业——霍夫曼编码求信源熵和存储前后的信息量的变化一:设计目的:1、学习离散信源平均信息量的计算方法。
2、理解和掌握huffman 编码的基本原理,实现对信源符号的huffman 编码3、熟悉 Matlab 编程;二:设计原理和思路1.信源熵的计算:公式: 21()log a I a p = Matlab 实现:I=log2(1/p) 或I=-log2(p) 熵(平均自信息)的计算公式22111()log log qq i i i i i i H x p p p p ====-∑∑Matlab 实现:HX=sum(-x.*log2(x));或者h=h-x(i)*log2(x(i));2.霍夫曼编码原理;分为两步,首先是码树形成过程:对信源概率进行合并形成编码码树。
然后是码树回溯过程:在码树上分配编码码字并最终得到Huffman 编码。
1、码树形成过程:将信源概率按照从小到大顺序排序并建立相应的位置索引。
然后按上述规则进行信源合并,再对信源进行排序并建立新的位置索引,直到合并结束。
在这一过程中每一次都把排序后的信源概率存入矩阵p 中,位置索引存入矩阵m 中。
这样,由排序之后的概率矩阵 p 以及索引矩阵m 就可以恢复原概率矩阵P 了,从而保证了回溯过程能够进行下去。
2、码树回溯过程:在码树上分配编码码字并最终得到Huffman 编码。
从索引矩阵M 的末行开始回溯。
(1) 在p 的末行2元素位置填入0和1。
(2) 根据该行索引1位置指示,将索引1位置的编码(‘1’)填入上一行的第一、第二元素位置,并在它们之后分别添加‘0’和‘1’。
(3) 将索引不为‘1’的位置的编码值(‘0’)填入上一行的相应位置(第3 列)。
(4) 以m的倒数第二行开始向上,重复步骤(1) ~(3),直到计算至m的首行为止。
三:设计代码:>> clear all;format longdisp(strcat('信息论与编码课程作业——霍夫曼编码求信源熵和存储前后的信息量的变化',13));histgram=zeros(1,255);[c,map]=imread('C:\Documents and Settings\Administrator\桌面\infomation\lenna.bmp');x=rgb2gray(c);[a,b]=size(x);for i=1:afor j=1:bk=x(i,j);histgram(k)=histgram(k)+1;endendf=histgram/a/b;symbols=find(f~=0); %灰度值p=f(symbols); %概率L=length(p);pp=p;%霍夫曼编码m=zeros(L-1,L);for i=1:L-1[p,mark]=sort(p);m(L-i,1:L-i+1)=mark(1:L-i+1);p=[p(1)+p(2),p(3:L),1];endc=cell(L-1,L);c(1,1)={'0'};c(1,2)={'1'};for i=2:L-1;ind=find(m(i-1,:)==1);temp=char(c(i-1,ind));c(i,1)={[temp,'0']};c(i,2)={[temp,'1']};snc=find(m(i-1,:)~=1);for j=3:i+1;con=snc(j-2);c(i,j)=c(i-1,con);endendcodeL=[];averge_long=0;H1=0;disp(strcat('灰度值',32,32,32,'概率',32,32,32,32,32,32,32,32,32,'霍夫曼编码:'));for i=1:L;ind=find(m(L-1,:)==i);code=char(c(L-1,ind));codeLength(i)=length(code);averge_long=averge_long+pp(i)*codeLength(i);H1=H1+pp(i)*log2(1/pp(i));disp(strcat(32,num2str(symbols(i)),32,32,32,num2str(pp(i)),3 2,32, code));enddisp(strcat('信源熵=',num2str(H1),32,32,32,32,'平均码字长度=',num2str(averge_long),32,32,32,32,32,'压缩比=',num2str(8/averge_long)));四:设计运行结果:信息论与编码课程作业——霍夫曼编码求信源熵和存储前后的信息量的变化灰度值概率霍夫曼编码:30 1.5259e-005 101000111100001031 1.5259e-005 101000111100001136 1.5259e-005 101000111100000037 1.5259e-005 101000111100000139 6.1035e-005 1010001111000140 7.6294e-005 1110010101001041 6.1035e-005 0111010111011042 6.1035e-005 0111010111011143 9.1553e-005 1110010101001144 0.00018311 111011101010145 0.00021362 00111101101146 0.00022888 01110101111047 0.00024414 01110101111148 0.00039673 0011110110049 0.00048828 1010001110050 0.00065613 1110010101151 0.00090027 011101011052 0.00086975 001111011153 0.0013123 111001011054 0.0013733 111011101156 0.0018005 01110101057 0.0025177 11010001158 0.0036621 0111111059 0.0033722 0101111060 0.0046539 1100110161 0.0055847 1111010162 0.0061188 001001063 0.0080261 100111064 0.0075226 100001165 0.0083466 101010166 0.0088806 101111167 0.0092773 110011168 0.0095367 110101069 0.0086517 101101070 0.0084229 101011071 0.0075378 100010172 0.0071564 011011173 0.0061493 001001174 0.0056 1111011075 0.0053864 1110110076 0.0045319 1100011177 0.0043488 1011000178 0.0042114 1010111079 0.0039063 1000111180 0.0041199 1010100181 0.0035706 0110101182 0.0039368 1001011083 0.0037537 1000010084 0.003479 0110101086 0.0033417 0101101087 0.0032501 0100110088 0.0034027 0110000189 0.0031128 0011010090 0.0031433 0011110091 0.0036774 0111111192 0.0041046 1010011094 0.0038452 1000111095 0.004364 1011100096 0.0037842 1000110097 0.0037079 1000001198 0.0033722 0101111199 0.0040741 10100001 100 0.0040741 10100010 101 0.0038147 10001101 102 0.0040588 10011111 103 0.0041046 10100111 104 0.004364 10111001 105 0.0048218 11010111 106 0.0052185 11100100 107 0.0049591 11011010 108 0.005188 11100001 109 0.0047455 11010110 110 0.0052032 11100011 111 0.0054474 11110100 112 0.0057526 11111011 113 0.0065308 0100111 114 0.0079346 1001100 115 0.010223 1101111116 0.0095825 1101100 117 0.0089417 1100000 118 0.0086975 1011011 119 0.0081787 1010010 120 0.007782 1001001121 0.0066376 0101011 122 0.0059357 11111111 123 0.0056458 11110111 124 0.0051575 11100000 125 0.0052948 11101001 126 0.005188 11100010 127 0.0059814 0000001 128 0.0058594 11111101 129 0.0065613 0101010 130 0.0062561 0011011 131 0.006897 0110100132 0.0072479 0111011 133 0.0073242 0111110 134135 0.0075226 1000100 136 0.0077515 1001000138 0.008606 1011001139 0.0091095 1100100 140 0.012115 000010141 0.012115 000011142 0.012741 001110143 0.012329 001100144 0.010941 1111001145 0.010147 1101110146 0.0089417 1100001 147 0.0088043 1011101 148 0.0091095 1100101 149 0.010712 1110101150 0.011337 1111100151 0.010513 1110011152 0.012878 010000153 0.012268 001010154 0.013138 010100155 0.012238 001000156 0.012939 010001157 0.012115 000100158 0.012955 010010159 0.012207 000111160 0.011993 000001161 0.013916 011001162 0.012177 000110163 0.012299 001011164 0.0094604 1101001 165 0.0089874 1100010 166 0.0088501 1011110 167 0.0056915 11111010 168 0.0059357 0000000 169 0.0071716 0111001 170 0.0057678 11111100 171 0.0054016 11101111 172 0.0054169 11110001 173 0.0058746 11111110 174 0.0072937 0111100 175 0.0070953 0110110 176177 0.0061035 0001011 178 0.0054016 11110000 179 0.0053864 11101101 180 0.0046692 11010000182 0.0036774 10000000183 0.0033875 01100000184 0.0033264 01011000185 0.0031281 00110101186 0.0035706 01110000187 0.0033264 01011001188 0.0033569 01011011189 0.0036011 01110100190 0.0040436 10011110191 0.0034485 01100010192 0.0036774 10000001193 0.0032654 01001101194 0.0034485 01100011195 0.003006 00010100196 0.0033722 01011100197 0.0036774 10000010198 0.0042419 10110000199 0.0045166 11000110200 0.0041046 10101000201 0.0052643 11101000202 0.0050354 11011011203 0.0045319 11001100204 0.0039825 10011010205 0.0040588 10100000206 0.0039673 10010111207 0.0037537 10000101208 0.0033722 01011101209 0.0026703 111011100210 0.0022125 110100010211 0.0018768 101000110212 0.0015259 000101010213 0.0013428 1110010111214 0.0012665 1110010100215 0.0007782 0011110100216 0.00079346 0011110101217 0.00061035 10100011111218 0.00054932 10100011101219 0.00065613 11101110100220 0.00035095 111011101011 221 0.00033569 111001010101 222 0.00030518 101000111101 223 0.00021362 011101011100 224 0.00016785 1110111010100225 0.00019836 001111011010226 0.00015259 1110010101000227 0.00010681 0111010111010228 6.1035e-005 10100011110010230 3.0518e-005 101000111100110231 1.5259e-005 10100011110011110232 1.5259e-005 10100011110011111233 1.5259e-005 1010001111001110信源熵=7.2193 平均码字长度=7.2492 压缩比=1.1036五:设计新得体会:通过这学期对信息论和编码的学习,以及这次的设计,使我了解了很多东西,也使以前所学的知识得以巩固!,通过这次的设计,进一步学习了离散信源平均信息量、平均码长和压缩比的计算方法。
霍夫曼编码matlab
霍夫曼编码matlab在Matlab中实现霍夫曼编码可以通过以下步骤完成:1. 构建霍夫曼树,首先,你需要根据输入的数据统计每个符号出现的频率。
然后,使用这些频率构建霍夫曼树。
你可以使用Matlab中的数据结构来表示霍夫曼树,比如使用结构体或者类来表示节点。
2. 生成霍夫曼编码,一旦构建了霍夫曼树,你可以通过遍历树的方式生成每个符号对应的霍夫曼编码。
这可以通过递归或者迭代的方式实现。
3. 对数据进行编码和解码,使用生成的霍夫曼编码对输入的数据进行编码,然后再对编码后的数据进行解码。
这可以帮助你验证霍夫曼编码的正确性。
以下是一个简单的示例代码,用于在Matlab中实现霍夫曼编码: matlab.% 假设有一个包含符号频率的向量 freq 和对应符号的向量symbols.% 构建霍夫曼树。
huffTree = hufftree(freq);% 生成霍夫曼编码。
huffCodes = huffenco(symbols, huffTree);% 对数据进行编码。
data = [1 0 1 1 0 1 1 1]; % 你的输入数据。
encodedData = huffenco(data, huffCodes);% 对数据进行解码。
decodedData = huffmandeco(encodedData, huffTree);需要注意的是,以上代码仅为简单示例,实际应用中可能需要根据具体情况进行调整和完善。
同时,对于大规模数据的处理,也需要考虑到内存和性能方面的优化。
希望这个简单的示例能够帮助你在Matlab中实现霍夫曼编码。
matlab二进制霍夫曼编码
matlab二进制霍夫曼编码二进制霍夫曼编码是一种用于数据压缩的编码技术,可以提供有效的压缩率和快速的编解码速度。
作为一种常用的压缩方法,它在很多领域都有广泛的应用,如图像和音频压缩以及通信系统中的数据传输等。
在MATLAB中,我们可以使用现成的函数库和工具来实现二进制霍夫曼编码。
首先,需要将待压缩的数据转化为二进制形式。
然后,使用MATLAB中的`huffmandict()`函数来创建霍夫曼编码字典,该字典包含了每个符号对应的霍夫曼编码。
接下来,使用`huffmanenco()`函数将二进制数据编码成霍夫曼编码。
最后,使用`huffmandeco()`函数将霍夫曼编码解码为原始数据。
下面以一个简单的示例来说明如何使用MATLAB实现二进制霍夫曼编码。
假设我们有一个包含10个二进制符号的数据,每个符号的概率分别为{0.18, 0.15, 0.12, 0.1, 0.1, 0.07, 0.06, 0.06,0.05, 0.05}。
首先,我们需要创建霍夫曼字典,代码如下:```matlabsymbols = [0:9]; % 符号集合probabilities = [0.18, 0.15, 0.12, 0.1, 0.1, 0.07, 0.06, 0.06, 0.05, 0.05]; % 符号概率dict = huffmandict(symbols, probabilities); % 创建霍夫曼字典```然后,我们可以使用以下代码将二进制数据编码为霍夫曼编码:```matlabdata = [1, 7, 9, 9, 5, 4, 7, 3, 2, 0]; % 待编码数据encodedData = huffmanenco(data, dict); % 编码数据```最后,我们可以使用以下代码将霍夫曼编码解码为原始数据:```matlabdecodedData = huffmandeco(encodedData, dict); % 解码数据```通过上述步骤,我们可以使用MATLAB实现二进制霍夫曼编码。
huffman编码用matlab的实现
Huffman编码用MTLAB的实现及编码注释一、实验目的1、学习Matlab软件的使用和编程;2、进一步深入理解Huffman编码算法的原理;3、提高独立进行算法编程的能力.二、实验环境硬件:计算机软件:Windows 2003和MATLAB编程环境。
三、实验内容1、用Matlab实现Huffman编码算法程序;2、要求程序输出显示所有的码字以及编码效率;3、设计简单的输入界面(可以是简单的文字提示信息),程序运行时提示用户输入代表信源符号概率的向量;要对用户输入的概率向量进行合法性检查。
四、实验原理1、二进制Huffman编码的基本原理及算法(1)把信源符号集中的所有符号按概率从大到小排队。
(2) 取概率最小的两个符号作为两片叶子合并(缩减)到一个节点.(3)视此节点为新符号,其概率等于被合并(缩减)的两个概率之和,参与概率排队.(4)重复(2)(3)两步骤,直至全部符号都被合并(缩减)到根。
(5) 从根出发,对各分枝标记0和1。
从根到叶的路径就给出了各个码字的编码和码长。
2、程序设计的原理(1)程序的输入:以一维数组的形式输入要进行huffman编码的信源符号的概率,在运行该程序前,显示文字提示信息,提示所要输入的概率矢量;然后对输入的概率矢量进行合法性判断,原则为:如果概率矢量中存在小于0的项,则输入不合法,提示重新输入;如果概率矢量的求和大于1,则输入也不合法,提示重新输入。
(2)huffman编码具体实现原理:1>在输入的概率矩阵p正确的前提条件下,对p进行排序,并用矩阵L记录p排序之前各元素的顺序,然后将排序后的概率数组p的前两项,即概率最小的两个数加和,得到新的一组概率序列,重复以上过程,最后得到一个记录概率加和过程的矩阵p以及每次排序之前概率顺序的矩阵a。
2〉新生成一个n—1行n列,并且每个元素含有n个字符的空白矩阵,然后进行huffman编码:将c矩阵的第n-1行的第一和第二个元素分别令为0和1(表示在编码时,根节点之下的概率较小的元素后补0,概率较大的元素后补1,后面的编码都遵守这个原则)然后对n-i—1的第一、二个元素进行编码,首先在矩阵a中第n-i行找到值为1所在的位置,然后在c矩阵中第n-i行中找到对应位置的编码(该编码即为第n-i—1行第一、二个元素的根节点),则矩阵c的第n—i行的第一、二个元素的n-1的字符为以上求得的编码值,根据之前的规则,第一个元素最后补0,第二个元素最后补1,则完成该行的第一二个元素的编码,最后将该行的其他元素按照“矩阵c中第n-i行第j+1列的值等于对应于a矩阵中第n—i+1行中值为j+1的前面一个元素的位置在c矩阵中的编码值”的原则进行赋值,重复以上过程即可完成huffman编码。
matlab哈夫曼编码
matlab哈夫曼编码哈夫曼编码是一种常见的数据压缩算法,可以将数据压缩至原始数据的一小部分,从而减少存储空间和传输时间。
Matlab提供了内置函数来实现哈夫曼编码。
1. 哈夫曼树的构建在Matlab中,可以使用huffmandict函数来构建哈夫曼树。
该函数接受一个包含符号和它们对应权重的向量作为输入,并返回一个包含每个符号对应编码的字典。
例如,要将字符串"hello world"进行编码,可以使用以下代码:```s = 'hello world';symbols = unique(s);freq = hist(s,symbols);dict = huffmandict(symbols,freq);```其中,unique函数用于获取字符串中唯一的符号集合,hist函数用于计算每个符号出现的频率。
huffmandict函数则用于构建哈夫曼树并生成字典。
2. 数据压缩有了哈夫曼字典后,就可以将原始数据进行压缩。
在Matlab中,可以使用huffmanenco函数来进行数据压缩。
该函数接受一个包含原始数据的向量和之前生成的哈夫曼字典作为输入,并返回一个包含压缩后二进制数据的向量。
例如,在上面例子中生成的字典下,可以将字符串"hello world"进行压缩:```encoded = huffmanenco(s,dict);```3. 数据解压对于压缩后的数据,可以使用huffmandeco函数进行解压。
该函数接受一个包含压缩后二进制数据的向量和之前生成的哈夫曼字典作为输入,并返回一个包含解压后原始数据的向量。
例如,在上面例子中生成的字典下,可以将上一步得到的压缩数据进行解压:```decoded = huffmandeco(encoded,dict);```4. 完整代码综合以上步骤,可以得到完整的Matlab代码:```s = 'hello world';symbols = unique(s);freq = hist(s,symbols);dict = huffmandict(symbols,freq);encoded = huffmanenco(s,dict);decoded = huffmandeco(encoded,dict);```其中,s是待编码字符串,symbols是符号集合,freq是每个符号出现频率。
霍夫曼编码的matlab实现
霍夫曼编码的matlab实现霍夫曼编码的matlab实现一、实验内容:用Matlab语言编程实现霍夫曼(Huffman)编码。
二、实验原理及编码思想: 霍夫曼(Huffman)编码算法是满足前缀条件的平均二进制码长最短的编-源输出符号,而将较短的编码码字分配给较大概率的信源输出。
算法是:在信源符号集合中,首先将两个最小概率的信源输出合并为新的输出,其概率是两个相应输出符号概率之和。
这一过程重复下去,直到只剩下一个合并输出为止,这个最后的合并输出符号的概率为1。
这样就得到了一张树图,从树根开始,将编码符号1 和0 分配在同一节点的任意两分支上,这一分配过程重复直到树叶。
从树根到树叶途经支路上的编码最后就构成了一组异前置码,就是霍夫曼编码输出。
以本教材P36例题3-2信源为例:离散无记忆信源:U u1 u2 u3 u4 u5P(U) = 0.4 0.2 0.2 0.1 0.1解:概率信符s编码过程 i P(s) i码字W i第一次第二次第三次1W=0 0.4 0.6 S0.4 0.4 11A(1) 1 W=10 S0.4 0.2 0.2 22 0 0.4 1 W=111 S 0.2 0.2 330 0.2 1 W=1101 S 0.1 440.2 0W=1100 S 0.1 550通过上表的对信源缩减合并过程,从而完成了对信源的霍夫曼编码。
三、程序设计思路分为两步,首先是码树形成过程:对信源概率进行合并形成编码码树。
然后是码树回溯过程:在码树上分配编码码字并最终得到霍夫曼编码。
1、码树形成过程:将信源概率按照从小到大顺序排序并建立相应的位置索引。
然后按上述规则进行信源合并,再对信源进行排序并建立新的位置索引,直到合并结束。
在这一过程中每一次都把排序后的信源概率存入矩阵G中,位置索引存入矩阵Index中。
这样,由排序之后的概率矩阵 G以及索引矩阵Index就可以恢复原概率矩阵P了,从而保证了回溯过程能够进行下去。
赫夫曼编码matlab实现
赫夫曼编码matlab实现赫夫曼编码(Huffman coding)是一种常用的数据压缩算法,通过将出现频率较高的字符用较短的编码表示,从而达到减少存储空间和传输数据量的目的。
本文将针对赫夫曼编码的实现进行详细介绍,并使用MATLAB语言进行具体实现。
文章将按照以下步骤逐一解释赫夫曼编码的实现过程,并给出MATLAB代码的编写。
1. 理解赫夫曼编码赫夫曼编码是一种前缀编码,即每个字符的编码都不是其他字符编码的前缀。
这种编码方式使得解码时不需要回溯,从而提高了效率。
赫夫曼编码的实现主要涉及两个步骤:构建哈夫曼树和生成编码表。
2. 构建哈夫曼树构建哈夫曼树是赫夫曼编码的第一步。
根据所需压缩的数据,统计每个字符出现的频率,并将频率作为节点权值构建一颗权值最小的二叉树。
构建哈夫曼树的步骤如下:a. 对于每个字符,统计其出现的频率。
b. 创建一个节点集合,将每个频率作为节点的权值,将所有字符节点加入集合。
c. 从节点集合中选取两个权值最小的节点合并,在新节点的左右子树上分别标记0和1。
d. 将新节点加入节点集合,重复上述步骤,直至节点集合中只剩下一个节点,此节点即为哈夫曼树的根节点。
3. 生成编码表生成编码表是赫夫曼编码的第二步。
在构建好哈夫曼树后,通过遍历哈夫曼树上的每个叶子节点,从根节点到叶子节点的路径上的左右分支分别表示0和1的编码,将每个字符对应的编码存储在编码表中。
4. 实现赫夫曼编码的MATLAB代码使用MATLAB语言可以方便地实现赫夫曼编码算法。
以下是一个简单的赫夫曼编码的MATLAB代码示例:function [codes, tree] = huffman_encode(text)freq = histcounts(text);chars = unique(text);nodes = cell(length(chars), 1);for i = 1:length(chars)nodes{i} = struct('Symbol', chars(i), 'Frequency', freq(i), 'Code', '');endwhile length(nodes) > 1[value, idx] = sort(cellfun(@(x) x.Frequency, nodes));node1 = nodes{idx(1)};node2 = nodes{idx(2)};newNode = struct('Symbol', '', 'Frequency', node1.Frequency + node2.Frequency, 'Code', '');newNode.Left = node1;newNode.Right = node2;nodes(idx(2)) = [];nodes(idx(1)) = [];nodes{end + 1} = newNode;endtree = nodes{1};assign_codes(tree, '');for i = 1:length(chars)idx = find(cellfun(@(x) strcmp(x.Symbol, chars(i)), nodes));codes{i, 1} = chars(i);codes{i, 2} = nodes{idx}.Code;endendfunction assign_codes(node, code)if ~isempty(node.Left)assign_codes(node.Left, strcat(code, '0'));endif ~isempty(node.Right)assign_codes(node.Right, strcat(code, '1'));endif isempty(node.Left) && isempty(node.Right) node.Code = code;endend5. 示例测试可以使用一段文本进行测试,例如:text = 'this is an example for huffman encoding'; codes = huffman_encode(text);disp(codes);运行结果将输出每个字符的编码,如:' ' '1101''a' '111''c' '1001''d' '01001''e' '11''f' '0101''g' '00100''h' '000''i' '101''l' '00111''m' '01100''n' '1000''o' '00110''p' '00101''r' '01000''s' '10001''t' '0101''x' '01101'通过以上步骤,我们可以成功地实现赫夫曼编码的MATLAB实现。
matlab 哈夫曼编码
matlab 哈夫曼编码哈夫曼编码是一种可变长度的编码方式,它可以将一组可能不等概率出现的字符序列压缩成一个二进制编码的表示方式,以达到数据压缩的目的。
在哈夫曼编码中,出现频率越高的字符所对应的编码越短,反之越长。
需要注意的是,将字符压缩成的二进制编码只能满足单词不重复的情况下才能唯一的解码出来,因此在实际应用中还需要对编码进行强制分界,以保证无二义性。
在Matlab中进行哈夫曼编码可以使用built-in函数'huffmandict'和'huffmanenco'来完成。
其中'huffmandict'函数根据字符和频率信息来生成哈夫曼字典,'huffmanenco'函数将读入的原始数据运用哈夫曼编码压缩成一个码字,也可以使用'huffmandeco'函数将压缩后的数据解码。
下面我给出一个简单的演示,解释如何使用Matlab实现哈夫曼编码过程。
假设我们要压缩的原始数据如下:matlabcharList = ['a', 'b', 'c', 'd', 'e', 'f'];probList = [0.2, 0.15, 0.1, 0.12, 0.3, 0.13];data = ['a', 'c', 'b', 'a', 'e', 'b', 'f', 'e', 'f', 'c', 'c', 'a', 'd', 'a', 'b', 'e'];首先我们需要生成一个哈夫曼字典:matlabhuffDictionary = huffmandict(charList, probList);这里的'huffmandict'函数通过输入字符符号和对应概率的向量,生成一个哈夫曼字典。
Huffman编码(哈夫曼编码)的Matlab实现
clear 【1 】all fprintf('Reading data...')data=imread('cameraman.tif');data=uint8(data);%读入数据,并将数据限制为uint8 fprintf('Done!\n')%编码紧缩fprintf('compressing data...');[zipped,info]=norm2huff(data);fprintf('Done!\n')%解紧缩fprintf('compressing data...');unzipped=huff2norm(zipped,info);fprintf('Done!\n')%测试是否无掉真isOK=isequal(data(:),unzipped(:))%显示紧缩后果whos datazippedunzippedfunction [zipped,info]=norm2huff(vector)if~isa(vector,'uint8'),error('input argument must be a uint8 vector') endvector=vector(:)';%将输入向量转换为行向量f=frequency(vector);%盘算个元素消失的概率simbols=find(f~=0);f=f(simbols);%将元素按消失的概率分列[f,sortindex]=sot(f);simbols=simbols(sortindex);%产生码字 generate the codeword as the 52 bits of a doublelen=length(simbols);simbols_index=num2cell(1:len);codeword_tmp=cell(len,1);while length(f)>1,index1=simbols_index{1};index2=simbols_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)];simbols_index=[{[index1 index2]} simbols_index(3:end)];%将数据从新分列,是两个节点的频率尽量与前一个节点的频率想当resort datainordertohavetwonodeswithlowerfrequencyasfirst to[f,sortindex]=sort(f);simbols_index=simbols_index(sortindex);end%对应响应的元素与码字codeword=cell(256:1);codeword(simbols)=codeword_tmp;%盘算总的字符串长度len=0;for index=1:length(vector),len=len+length(codeword{double(vector(index))+1}); end%产生01序列string=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;end%假如须要,加零len=length(string);pad=8-mod(len,8);if pad>0,string=[string uint8(zeros(1,pad))];end%保管现实有效的码字codeword=codeword(simbols);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>0,code=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);% init sparse matrixfor index=1:numel(codeword),huffcodes(codeword(index),1)=simbols(index); end%产生信息构造体info.pad=pad;info.ratio=cols./length(vector);info.length=length(vector);info.maxcodelen=maxcodelen;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}];endfunction vector=huff2norm(zipped,info)%HUFF2NORM Huffman 解码器%HUFF2NORM(X,INFO)依据信息体构造 info 返回向量 zipped 的解码成果%%矩阵参数以X(:)情势输入if~isa(zipped,'uint8'),error('input argument must be a uint8 vector')end%产生01序列len=length(zipped);string=repmat(uint8(0),1,len.*8);bitindex=1:8;for index+1:len,string(bitindex+8.*(index-1))=uint8(bitget(zipped(index),bitindex)); end%调剂字符串string=logical(string(:)');% remove 0 paddinglen=length(string);%解码weights=2.^(0:51);vector=repmat(uint8(0),1,info,length);vectorindex=1;codeindex=1;code=0;for index=1:len,code=bitset(code,codeindex,string(index));]codeindex=codeindex+1;byte=decode(bitset(code,codeindex),info);if byte>0,%vector(vectorindex)=byte-1;codeindex=1;code=0;vectorindex=vectorindex+1;endendfunction byte=decode(code,info)byte=info.huffcodes(code);function f=frequency(vector)%FREQUENCY 盘算元素消失概率if~isa(vector,'uint8'),error('input argument must be a uint8 vector') endf=repmat(0,1,256);%扫描向量len=length(vector);for index=0:256,%f(index+1)=sum(vector==uint8(index)); end%归一化f=f./len;。
huffman编码的matlab实现
%生成一个n-1行n列的数组
概率数组q进行从小至大的排序,并且用l数组返回一个数组,该数组表示概率数组q 排序前的顺序编号
%由数组l构建一个矩阵,该矩阵表明概率合并时的顺序,用于后面的编码
%将排序后的概率数组q的前两项,即概率最小的两个数加和,得到新的一组概率序列
end for i=1:n-1
%生成一个n-1行n列,并且每个元素的的长度为n的空白数组,c矩阵用于进行huffman编码,并且在编 码中与a矩阵有一定的对应关系
c(n-i,(j+1)*n+1:(j+2)*n)=c(n-i+1,n*(find(a(n-i+1,:)==j+1)-1)+1:n*find(a(ni+1,:)==j+1)) %矩阵c中第n-i行第j+1列的值等于对应于a矩阵中第n-i+1行中值为j+1的前面一
个元素的位置在c矩阵中的编码值
end end for i=1:n
霍夫曼编码方法的具体过程是:首先把信源的各个输出符 号序列按概率递降的顺序排列起来,求其中概率最小的两个序 列的概率之和,并把这个概率之和看作是一个符号序列的概 率,再与其他序依概率递降顺序排列(参与求概率之和的这 两个序列不再出现在新的排列之中),然后,对参与概率求和 的两个符号序列分别赋予二进制数字0和1。继续这样的操作, 直到剩下一个以1为概率的符号序列。最后,按照与编码过程 相反的顺序读出各个符号序列所对应的二进制数字组,就可分 别得到各该符号序列的码字。
%完成huffman码字的分配
ind(a(1,:)==i)*n) %用h表示最后的huffman编码,矩阵h的第i行的元素对应于矩阵c的第一行的第i个元素
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
Huffman编码的matlab实现
一、信源编码介绍
为了减少信源输出符号序列中的剩余度、提高符号的平均信息量,对所施行的变换。
具体说,就是针对信源输出符号序列的统计特性来寻找某种方法,把信源输出符号序列变换为最短的码字序列,使后者的各码元所载荷的平均信息量最大,同时又能保证无失真地恢复原来的符号序列。
既然信源编码的基本目的是提高码字序列中码元的平均信息量,那么,一切旨在减少剩余度而对信源输出符号序列所施行的变换或处理,都可以在这种意义下归入信源编码的范畴,例如过滤、预测、域变换和数据压缩等。
当然,这些都是广义的信源编码。
一般来说,减少信源输出符号序列中的剩余度、提高符号平均信息量的基本途径有两个:①使序列中的各个符号尽可能地互相独立;②使序列中各个符号的出现概率尽可能地相等。
前者称为解除相关性,后者称为概率均匀化。
信源编码的一般问题可以表述如下:
信源编码
若某信源的输出为长度等于M的符号序列集合式中符号A为信源符号表,它包含着K个不同的符号,A={ɑk|k=1,…,K},这个信源至多可以输出K M个不同的符号序列。
记‖U‖=KM。
所谓对这个信源的输出
信源编码
进行编码,就是用一个新的符号表B的符号序列集合V来表示信源输出的符号序列集合U。
若V的各个序列的长度等于 N,即式中新的符号表B共含L个符号,B={b l|l=1,…,L}。
它总共可以编出L N个不同的码字。
类似地,记‖V‖=LN。
为了使信源的每个输出符号序列都能分配到一个独特的码字与之对应,至少应满足关系‖V‖=L N≥‖U‖=KM或者N/M≥log K/log L
下面的几个编码定理,提供了解决这个矛盾的方法。
它们既能改善信息载荷效率,又能保证码字唯一可译。
离散无记忆信源的定长编码定理
对于任意给定的ε>0,只要满足条件N/M≥(H(U)+ε)/log L
那么,当M足够大时,上述编码几乎没有失真;反之,若这个条件不满足,就不可能实现无失真的编码。
式中H(U)是信源输出序列的符号熵。
信源编码
通常,信源的符号熵H(U)<log K,因此,上述条件还可以表示为【H(U)+ε】/log L≤N/M≤log K/log L特别,若有K=L,那么,只要H(U)<log K,就可能有N<M,
从而提高信息载荷的效率。
由上面这个条件可以看出,H(U)离log K越远,通过编码所能获得的效率改善就越显著。
实质上,定长编码方法提高信息载荷能力的关键是利用了渐近等分性,通过选择足够大的M,把本来各个符号概率不等[因而H(U)<log K]的信源输出符号序列变换为概率均匀的典型序列,而码字的唯一可译性则由码字的定长性来解决。
离散无记忆信源的变长编码定理
变长编码是指V的各个码字的长度不相等。
只要V中各个码字的长度Ni(i=1,…,‖V‖)满足克拉夫特不等式这‖V‖个码字就能唯一地正确划分和译码。
离散无记忆信源的变长编码定理指出:若离散无记忆信源的输出符号序列为,式中A={ɑk|k=1,…,K},符号熵为H(U),对U进行唯一可译的变长编码,编码字母表B的符号数为L,即B={b l|l=1,…,L},那么必定存在一种编码方法,使编出的码字Vi=(v i1,…,v iNi),(i=1,…,‖V‖),具有平均长度嚻:M H(U)/log L≤嚻<M H(U)/log L+1
若L=K,则当H(U)<log K=log L时,必有嚻<M;H(U)离log K越远,则嚻越小于M。
具体实现唯一可译变长编码的方法很多,但比较经典的方法还是仙农编码法、费诺编码法和霍夫曼编码法。
其他方法都是这些经典方法的变形和发展。
所有这些经典编码方法,都是通过以短码来表示常出现的符号这个原则来实现概率的均匀化,从而得到高的信息载荷效率;同时,通过遵守克拉夫特不等式关系来实现码字的唯一可译。
以上几个编码定理,在有记忆信源或连续信源的情形也有相应的类似结果。
在实际工程应用中,往往并不追求无差错的信源编码和译码,而是事先规定一个译码差错率的容许值,只要实际的译码差错率不超过这个容许值即认为满意(见信息率-失真理论和多用户信源编码)。
二、Huffman编码
霍夫曼编码方法的具体过程是:首先把信源的各个输出符号序列按概率递降的顺序排列起来,求其中概率最小的两个序列的概率之和,并把这个概率之和看作是一个符号序列的概率,再与其他序列依概率递降顺序排列(参与求概率之和的这两个序列不再出现在新的排列之中),然后,对参与概率求和的两个符号序列分别赋予二进制数字0和1。
继续这样的操作,直到剩下一个以1为概率的符号序列。
最后,按照与编码过程相反的顺序读出各个符号序列所对应的二进制数字组,就可分别得到各该符号序列的码字。
三、Huffman编码的Matlab源程序
1、Huffman源程序
p=input('please input a number:') %提示输入界面
n=length(p);
for i=1:n
if p(i)<0
fprintf('\n The probabilities in huffman can not less than 0!\n');
p=input('please input a number:') %如果输入的概率数组中有小于0的值,则重新输入
概率数组
end
end
if abs(sum(p)-1)>0
fprintf('\n The sum of the probabilities in huffman can more than 1!\n');
p=input('please input a number:') %如果输入的概率数组总和大于1,则重新输入概
率数组
end
q=p;
a=zeros(n-1,n); %生成一个n-1行n列的数组
for i=1:n-1
[q,l]=sort(q) %对概率数组q进行从小至大的排序,并且用l数组返回一个
数组,该数组表示概率数组q排序前的顺序编号a(i,:)=[l(1:n-i+1),zeros(1,i-1)] %由数组l构建一个矩阵,该矩阵表明概率合并时的顺序,用
于后面的编码
q=[q(1)+q(2),q(3:n),1]; %将排序后的概率数组q的前两项,即概率最小的两个数加和,
得到新的一组概率序列
end
for i=1:n-1
c(i,1:n*n)=blanks(n*n); %生成一个n-1行n列,并且每个元素的的长度为n的空白数组,c矩
阵用于进行huffman编码,并且在编码中与a矩阵有一定的对应关系end
c(n-1,n)='0'; %由于a矩阵的第n-1行的前两个元素为进行huffman编码加和运算时所得的最c(n-1,2*n)='1'; 后两个概率,因此其值为0或1,在编码时设第n-1行的第一个空白字符为0,
第二个空白字符1。
for i=2:n-1
c(n-i,1:n-1)=c(n-i+1,n*(find(a(n-i+1,:)==1))-(n-2):n*(find(a(n-i+1,:)==1))) %矩阵c的第n-i的
第一个元素的n-1的字符赋值为对应于a矩阵中
第n-i+1行中值为1的位置在c矩阵中的编码值
c(n-i,n)='0' %根据之前的规则,在分支的第一个元素最后补0
c(n-i,n+1:2*n-1)=c(n-i,1:n-1) %矩阵c的第n-i的第二个元素的n-1的字符与第n-i行的第一个元素
的前n-1个符号相同,因为其根节点相同
c(n-i,2*n)='1' %根据之前的规则,在分支的第一个元素最后补1
for j=1:i-1
c(n-i,(j+1)*n+1:(j+2)*n)=c(n-i+1,n*(find(a(n-i+1,:)==j+1)-1)+1:n*find(a(n-i+1,:)==
j+1)) %矩阵c中第n-i行第j+1列的值等于对应于a矩阵中第n-i+1行中值为j+1的前面一
个元素的位置在c矩阵中的编码值
end
end %完成huffman码字的分配
for i=1:n
h(i,1:n)=c(1,n*(find(a(1,:)==i)-1)+1:find(a(1,:)==i)*n) %用h表示最后的huffman编码,矩阵h
的第i行的元素对应于矩阵c的第一行的第i个元素ll(i)=length(find(abs(h(i,:))~=32)) %计算每一个huffman编码的长度
end
l=sum(p.*ll); %计算平均码长
fprintf('\n huffman code:\n');
h
hh=sum(p.*(-log2(p))); %计算信源熵
fprintf('\n the huffman effciency:\n');
t=hh/l %计算编码效率
2、程序运行结果
四、结论
Huffman编码的特殊之处在于,它是根据每一个源字符出现的估算概率而建立起来的,就是说出现概率高的字符使用较短的编码,反之出现概率低的则使用较长的编码,这便使编码之后的字符串的平均期望长度降低,从而达到无损压缩数据的目的。