MATLABHuffman编码

智能2112杨阳

一、目的

1. 理解信源编码的意义

2. 掌握Huffuman编码的方法及计算机实现

二、平台

MATLAB

三、内容

1、 选取一段不少于3000字的英文材料,统计各字符出现的次数,实现Huffman编码,以及对编码结果的解码

要求:

(1)输出每个字符出现的次数和编码,并存储文件(Huffman.txt)。

读取数据后,根据Huffman编码的规则完成编码,并用count函数统计每个字符出现的次数

代码:

%数据读取

txt=fopen('/Users/darellyang/Desktop/数字图像处理/sample.txt');

shuju=fscanf(txt,'%c');

%去重

selected_shuju=unique(shuju);

selected_shuju=selected_shuju';

%长度

len=length(selected_shuju);

%求出信源符号的个数

for i=1:len

    count(i)=length(strfind(shuju,selected_shuju(i)));

end

p=count./sum(count);

n=length(p);

q=p;



%构建概率矩阵

m=zeros(n-1,n);

for i=1:n-1%合并n-1次

    [q,e]=sort(q);%E是个行向量 值代表q中该位置的概率在原序列中的位置

    m(i,:)=[e(1:n-i+1),zeros(1,i-1)];

    %m的特点:第一行n个非零元素,逐行递减,n-1行2个非零元素

    q=[q(1)+q(2),q(3:n),1];

end



%构建编码矩阵

for i=1:n-1

    c(i,1:n*n)=blanks(n*n); %c矩阵特点 与m对应  每一个n块对应一个概率的符号 第一行有n个 n-1行有2个 其余为空

end

%开始编码 因为哈夫曼编码不唯一 自规定概率小的赋值1 概率大的赋值0

c(n-1,n)='1';

c(n-1,2*n)='0';

for i=2:n-1

    %被合并的前两个需要分配0和1

    index=find(m(n-i+1,:)==1);%下一行对应位置为1 则为该行较小的两个概率合并以后的总概率

    c(n-i,1:n-1)=c(n-i+1,n*(index)-(n-2):n*index);%前缀是对应的合并后概率的编码值 注意:1:n-1的维度和取的前缀的维度要一致

    c(n-i,n)='1';

    c(n-i,n+1:2*n-1)=c(n-i,1:n-1); %合并为同一个概率 前缀相同

    c(n-i,2*n)='0';

   

    %未合并的 从每一行第三个开始编码 无需新分配0 1 直接继承上一个节点的编码

    for j=1:i-1

        index=find(m(n-i+1,:)==j+1);%从index=2开始到index=i结束 i=3 即n-3行 就是index从2到3

         c(n-i,(j+1)*n+1:(j+2)*n)=c(n-i+1,n*(index-1)+1:n*index);

    end

end

for i=1:n

    index=find(m(1,:)==i);

    h(i,1:n)=c(1,n*(index-1)+1:index*n); %将与输入概率对应的编码放入h中

    is0=abs(h(i,:));%abs()将字符变为ASCII码 空为32

    len(i)=length(find(is0~=32)); %非空符号的个数为码长

end



disp('编码结果');

[selected_shuju,h]

disp('平均码长');

e=sum(p.*len)   %计算平均码长

xinxiliang=sum(p.*log2(1./p));    %计算平均信息量

disp('平均信息量');

disp([num2str(xinxiliang),'bit/sym']);     

disp('编码效率');

eta=(sum(p.*log2(1./p)))./e                        %计算编码效率



%将结果写入文件中

txt2=fopen('/Users/darellyang/Desktop/数字图像处理/Huffman.txt','w+','n','GB2312');

fwrite(txt2,"symbols:   ");

fprintf(txt2,'\n');

for i=1:length(selected_shuju)

    fwrite(txt2,selected_shuju(i));

    fwrite(txt2,':  ');

    %fwrite(txt2,num2str(p(i)));

    fwrite(txt2,num2str(count(i)));

    fprintf(txt2,'\n');

end

fprintf(txt2,'\n');



fwrite(txt2,"Huffman_Result:  ");

fprintf(txt2,'\n');



for i=1:length(selected_shuju)

    fwrite(txt2,[selected_shuju(i)]);

    fwrite(txt2,':  ');

    for j=1:length(h)

        fwrite(txt2,h(i,j));

    end

    fprintf(txt2,'\n');

end

fwrite(txt2,'averge_lenth:  ');

fwrite(txt2,num2str(sum(p.*len)));

fprintf(txt2,'\n');

fwrite(txt2,'averge_bit:  ');

fwrite(txt2,[num2str(xinxiliang),'bit/sym']);

fprintf(txt2,'\n');

fwrite(txt2,'eta:  ');

fwrite(txt2,num2str(eta));

fclose(txt2);

结果:

2、在Huffman编码后,英文文章编码结果保存到文件中(code.dat),编码结果必须是二进制形式,即0 1的信息用比特位表示,不能用字符‘0’和‘1’表示(*)。

转为Huffman编码后满足二进制条件,保存到code.dat中即可

代码:

%文本编码和译码

%文本编码结果

txt3=fopen('/Users/darellyang/Desktop/数字图像处理/bianma.txt','w+');

txt3=fopen('code.dat','w+');

RESULT=[selected_shuju,h];

for i=1:length(shuju)

    for j=1:length(selected_shuju)

        if shuju(i)==selected_shuju(j)

            for o=1:length(h)

                if h(j,o)~=' '

                    fwrite(txt3,h(j,o));

                end

            end

            fwrite(txt3,' ');

        end

    end

end

fclose(txt3);

结果:

3、实现解码功能。

根据Huffman编码的规则解码即可

代码:

%文本解码

txt4=fopen('/Users/darellyang/Desktop/数字图像处理/jiema.txt','w+');

txt3=fopen('/Users/darellyang/Desktop/数字图像处理/bianma.txt','r');

bianma_code=fscanf(txt3,'%c');

s='';

plll=0

%开始解码:

for i=1:length(bianma_code)

    if bianma_code(i)==' '

        flag=1;

        for j=1:length(h)

            flag=1;

            for m=1:length(h)

                if(h(j,m)==' ')

                    plll=plll+1;

                    continue;

                end

                if(length(h)-plll~=length(s))

                    flag=0;

                    break;

                end

                for o=m:length(h)%比较每个字符串是否对应相等

                    if h(j,o)~=s(o-plll)

                            flag=0;

                    end

                end

            end

            plll=0;

            if(flag==1)

                fwrite(txt4,selected_shuju(j));

            end

        end

         s='';

    end

    if(bianma_code(i)~=' ')

        s=[s,bianma_code(i)];

    end

end

fclose(txt4);

fclose(txt3);

四、总结

对数字图像处理有了新的理解和认识,我对霍夫曼编码有了更深的了解,在做作业的过程中我掌握了二元霍夫曼编码树的构造方法。哈夫曼编码是一种变长的无失真编码方案。哈夫曼在编码在数字通信中有着重要的意义。可以根据信源符号的使用概率的高低来确定码元的长度。既实现了信源的无失真地编码,又使得编码的效率最高。此外,在实验的过程中也遇到了一些问题,通过查找资料和相关书籍得到了解决。通过此次作业,我了解了霍夫曼编码的特点,能够运用霍夫曼编码的基本原理及编码算法的来设计与实现程序。包括使对一些Matlab语句的掌握得更加熟练。我受益匪浅,为以后更进一步深入学习奠定了基础。总的来说收获满满。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值