图像课设Huffman编码

      它是一种编码方式,哈夫曼编码是可变字长编码(VLC)的一种。 Huffman于1952年提出一种编码方法,该方法完全依据字符出现概率来构造异字头的平均长 度最短的码字,有时称之为最佳编码,一般就叫作Huffman编码。 以哈夫曼树─即最优二叉树,带权路径长度最小的二叉树,经常应用于数据压缩。 在计算机信息处理中,“哈夫曼编码”是一种一致性编码法(又称"熵编码法"),用于数据的无损耗压缩。这一术语是指使用一张特殊的编码表将源字符(例如某文件中的一个符号)进行编码。这张编码表的特殊之处在于,它是根据每一个源字符出现的估算概率而建立起来的(出现概率高的字符使用较短的编码,反之出现概率低的则使用较长的编码,这便使编码之后的字符串的平均期望长度降低,从而达到无损压缩数据的目的)。这种方法是由David.A.Huffman发展起来的。 例如,在英文中,e的出现概率很高,而z的出现概率则最低。当利用哈夫曼编码对一篇英文进行压缩时,e极有可能用一个位(bit)来表示,而z则可能花去25个位(不是26)。用普通的表示方法时,每个英文字母均占用一个字节(byte),即8个位。二者相比,e使用了一般编码的1/8的长度,z则使用了3倍多。倘若我们能实现对于英文中各个字母出现概率的较准确的估算,就可以大幅度提高无损压缩的比例。

clear

load woman;                      %读入图像数据

%X=imread('girl.bmp','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.ratio

whos data unzipped zipped

%huffencode函数对输入矩阵vector进行Huffman编码,返回%编码后的向量(压缩后数据)及相关信息

function [zipped,info]=huffencode(vector)

%输入和输出都是unit8格式

%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);

while length(f)>1     %生产Huffman树,得到码字编码表

    index1=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);

end

codeword=cell(256,1);

codeword(symbols)=codeword_tmp;

len=0;

for index=1:length(vector)  %得到整个图像所有比特数

    len=len+length(codeword{double(vector(index))+1});

end

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);      

%非8整数倍时,最后补pad个0

if pad>0

    string=[string uint8(zeros(1,pad))];

end

codeword=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;

    end

    if len>0

        code=sum(weights(codeword{index}==1));

        code=bitset(code,len+1);

        codeword{index}=code;

        codelen(index)=len;

    end

end

codeword=[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)

    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编码,

%返回解压后的图像数据

function vector=huffdecode(zipped,info,image)

if~isa(zipped,'uint8')

    error('input argument must be a uint8 vector');

end

%产生0,1序列,每位占一个字节

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(:)');

len=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;

    end

end

%vector=reshape(vector,info.rows,info.cols);

%函数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');

end

f=repmat(0,1,256);

len=length(vector);

for index=0:255

    f(index+1)=sum(vector==uint8(index));

end

f=f./len;

%函数decode返回码字对应的符号

function byte=decode(code,info)

byte=info.huffcodes(code);

  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
Huffman编码是一种常用的数据压缩技术,通过使用变长编码来表示不同的符号,根据符号出现的频率来确定其编码长度,从而实现对数据的高效压缩。在进行Huffman编码时,首先需要对待编码的符号根据其出现频率进行排序,然后构建一棵Huffman树,通过不断合并出现频率最小的两个节点来构建树,最终得到每个符号的Huffman编码。在译码时,根据已知的Huffman编码和对应的Huffman树来进行逆向解码,还原出原始的符号序列。 对于Huffman编码和译码的课设,可以从以下几个方面展开设计和实现:首先,需要实现Huffman编码算法,包括对符号频率的统计、生成Huffman树以及生成编码的过程。其次,需要实现Huffman译码的算法,包括根据编码Huffman树还原出原始的符号序列。在课设中还可以涉及到对Huffman编码进行压缩和解压缩的实际应用,通过对比压缩前后的数据大小来验证Huffman编码的有效性。同时,还可以对不同的数据集进行测试,评估Huffman编码在不同数据情况下的压缩效果和译码性能。最后,课设还可以引导学生对Huffman编码的改进和优化进行探讨,如采用适用于不同数据分布的动态Huffman编码。 通过完成Huffman编码和译码的课设,学生能够全面了解并掌握Huffman编码的原理、实现和应用,提升算法设计和分析能力,同时也能够加深对数据压缩技术的理解和认识。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

fpga和matlab

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值