基于MATLAB的图像Huffman编码研究Word文件下载.docx
《基于MATLAB的图像Huffman编码研究Word文件下载.docx》由会员分享,可在线阅读,更多相关《基于MATLAB的图像Huffman编码研究Word文件下载.docx(16页珍藏版)》请在冰点文库上搜索。
3.5.1主流程图
3.5.2编码流程图
3.5.3解码流程图
3.3组员任务分工
王振宇:
编写主要程序,编码解码函数程序及相关子程序,修改报告及演示文稿。
龙航:
编写部分主程序及部分函数程序,撰写报告。
王一鸣:
编写部分程序,进行程序调试完善,制作演示文稿。
1.程序实现
4.1函数主程序
clc;
clear;
closeall;
X=imread('
peppers.JPG'
);
%图像灰度化
R=X(:
:
1);
G=X(:
2);
B=X(:
3);
Y=0.299*R+0.587*G+0.114*B;
subplot(1,3,1);
imshow(X);
title('
原始图像'
data=uint8(Y);
[zipped,info]=huffencode(data);
%调用Huffman编码程序进行压缩
unzipped=huffdecode(zipped,info);
%调用Huffman编码程序进行解码
%显示原始图像,灰度化图像和经编码解码后的图像
subplot(1,3,2);
imshow(data);
灰度化图像'
subplot(1,3,3);
imshow(unzipped);
Huffman编码并解码后图像'
disp('
平均码长'
L=info.avalen
压缩比'
CR=info.ratio
信息熵'
H=info.h
编码效率'
CE=info.ce
4.2编码程序
%huffencode函数对输入矩阵vector进行Huffman编码,返回编码后的数据及相关信息
function[zipped,info]=huffencode(vector)
if~isa(vector,'
uint8'
)%确定输入矩阵是uint8格式
error('
inputargumentmustbeauint8vector'
end
[m,n]=size(vector);
%求输入矩阵的行列数
vector=vector(:
)'
;
%将矩阵按列转换成一列后转至,成为一个行向量(其中存放灰度值)
f=frequency(vector);
%计算各符号出现的概率
symbols=find(f~=0);
%返回概率矩阵中非零元素的位置向量,作为符号向量
f=f(symbols);
%非零概率位置上的概率值组成非零概率行向量
[f,sortindex]=sort(f);
%将符号按照出现的概率从小到大排序,并保留非零概率向量位置索引
fs=f;
symbols=symbols(sortindex);
%读出原位置向量中的值(即概率向量中的位置),得到按概率排序后的符号向量
len=length(symbols);
%读取位置向量的长度
symbols_index=num2cell(1:
len);
%生成从1开始以1递增,1行len列的细胞型矩阵
codeword_tmp=cell(len,1);
%创建一个len行1列的细胞型变量用于存放码字
whilelength(f)>
1%生成Huffman树,得到二进制码字编码表
index1=symbols_index{1};
index2=symbols_index{2};
codeword_tmp(index1)=addnode(codeword_tmp(index1),uint8(0));
%添加节点且该分支按0标记
codeword_tmp(index2)=addnode(codeword_tmp(index2),uint8
(1));
%添加节点且该分支按1标记
f=[sum(f(1:
2))f(3:
end)];
%求出两个最小概率之和,列出其他概率,组成一个新的行向量
symbols_index=[{[index1,index2]}symbols_index(3:
%合并已编码的符号索引
[f,sortindex]=sort(f);
%将新的概率向量按照概率从小到大排序
symbols_index=symbols_index(sortindex);
%得到新的索引表
codeword=cell(256,1);
codeword(symbols)=codeword_tmp;
%各符号二进制码字按原符号位存入细胞型矩阵
len=0;
fori=1:
length(symbols)%得到各符号码长矩阵
wordlen(i)=length(codeword_tmp{i});
avawordlen=fs*wordlen'
%计算平均码长
Hlog=log2(fs)'
H=-(fs*Hlog);
%计算信息熵
forindex=1:
length(vector)%得到整个图像各点灰度值转化为二进制码字后的总比特数
len=len+length(codeword{double(vector(index))+1});
string=repmat(uint8(0),1,len);
%创建元素数与总比特数一致的行向量
pointer=1;
%定义指针变量
length(vector)%对输入图像进行编码
code=codeword{double(vector(index))+1};
%对应符号的二进制码字给code
len=length(code);
%读取码字长度
string(pointer+(0:
len-1))=code;
%将二进制码字存入行向量中
pointer=pointer+len;
%指针移移位
%将二进制编码按照每8位生成一个新字符。
len=length(string);
zp=8-mod(len,8);
ifzp>
string=[stringuint8(zeros(1,zp))];
%不足8位的在后补零
codeword=codeword(symbols);
%码字按符号概率放入列向量中
codelen=zeros(size(codeword));
%创建与列向量元素数相同的列向量
weights=2.^(0:
23);
maxcodelen=0;
length(codeword)
len=length(codeword{index});
%读二进制码字长度
iflen>
code=sum(weights(codeword{index}==1));
%计算二进制码字对应的十进制数
code=bitset(code,len+1);
%将码字最高位的上一位置1
codeword{index}=code;
codelen(index)=len;
%码字长度存入列向量中
end
codeword=[codeword{:
}];
%转化为行向量
%计算压缩后的向量
cols=length(string)/8;
string=reshape(string,8,cols);
7);
zipped=uint8(weights*double(string));
%码表存储到一个稀疏矩阵
huffcodes=sparse(1,1);
nnz(codeword)
huffcodes(codeword(index),1)=symbols(index);
%返回编码参数
info.zeropad=zp;
%info.zeropad是添加的比特数
info.huffcodes=huffcodes;
%info.huffcodes是Huffman码字表
info.length=length(vector);
%info.length是灰度化图像矩阵长度
info.rows=m;
%info.rows是灰度化图像行数
info.cols=n;
%info.cols是灰度化图像列数
info.avalen=avawordlen;
%info.ratio是平均码长
info.ratio=8/avawordlen;
%info.ratio是压缩比
info.h=H;
%info.h是信息熵
info.ce=H/avawordlen;
%info.ce是计算编码效率
%函数frequency计算各符号出现的概率
functionf=frequency(vector)
if~isa(vector,'
)%确定矩阵是uint8格式
error('
f=zeros(1,256);
%设置一个256个元素都为0的行向量
len=length(vector);
%读取输入矩阵元素个数
forindex=0:
1:
255
f(index+1)=sum(vector==index);
%统计输入图像矩阵中0至255各值出现的个数,存入一个行向量中
f=f./len;
%求各符号值出现的概率
%函数addnode添加节点确定符号码字
functioncodeword_new=addnode(codeword_old,item)
codeword_new=cell(size(codeword_old));
%前一步码字维数作为新细胞型变量的维数,用于存放码字
length(codeword_old)%确定符号对应码字
codeword_new{index}=[itemcodeword_old{index}];
4.3译码程序
%huffdecode函数对输入矩阵vector进行Huffman编码,返回解压后的图像数据
functionvector=huffdecode(zipped,info)
if~isa(zipped,'
)%确定压缩矩阵是uint8格式
len=length(zipped);
%读取压缩矩阵长度
string=repmat(uint8(0),1,len*8);
%创建全为0的行向量
bitindex=(1:
8);
len
string(bitindex+8.*(index-1))=uint8(bitget(zipped(index),bitindex));
%读取压缩矩阵中的值并转化为8位二进制按顺序放入string矩阵中
%开始解码
51);
vector=repmat(uint8(0),1,info.length);
%创建与灰度化图像行向量等长的行向量
vectorindex=1;
codeindex=1;
code=0;
len-1
code=bitset(code,codeindex,string(index));
%按位读编码码字
codeindex=codeindex+1;
%移位
byte=decode(bitset(code,codeindex),info);
%进行码字匹配,读取相对应符号
ifbyte>
0%若读取到对应符号则进行下面操作,无符号继续按位读取码字
vector(vectorindex)=byte-1;
%将符号表示的灰度值放入容器矩阵中
codeindex=1;
%重置
code=0;
vectorindex=vectorindex+1;
%容器指针移位
vector=reshape(vector,info.rows,info.cols);
%将构成的灰度矩阵按原图矩阵行列数重构,解码完成
%函数decode返回码字对应的符号
functionbyte=decode(code,info)
byte=info.huffcodes(code);
2.测试和调试
运行结果:
平均码长L=7.6057;
压缩比CR=1.0518;
信息熵H=7.5789;
编码效率CE=0.9965
平均码长L=6.9685;
压缩比CR=1.1480;
信息熵H=6.9427;
编码效率CE=0.9963
经过多次测试和调整,最终编码结果正确,解码结果正确,程序运行正确。
3.总结
感谢李雷达老师教授《数字视频技术》课程并为我们安排了这次课程设计。
通过这次课设,我们更深地熟悉和掌握了MATLAB
程序设计方法和灰度图像Huffman的编码解码过程,学会了运用MATLAB平台对图像进行处理和分析。
提高我们编程能力的同时,也让我们对编解码算法有了更深入的理解。
课程设计是我们专业课程知识综合应用的实践训练,是我们迈向社会,从事职业工作前一个必不少的过程。
在这次的课程设计中不仅检验了我们所学习的知识,也引发了我们对如何去把握一件事情,如何去做一件事情,如何完成一件事情等问题的思考。
在设计过程中,与同学分工设计,和同学们相互探讨,相互学习,相互监督,提高了团队合作能力,学到了平时在课上学不到的知识,每个人都得到了很大的进步。
通过这次数字视频技术课程设计,我们在多方面都有所提高。
这次课程设计中,综合运用了本专业所学课程的理论知识。
学会了在图像处理过程中,运用编程思维去实现某种功能或效果。
在这次设计过程中,体现出自己的能力以及综合运用知识的能力,体会到了学有所用、学以致用的兴奋感和成就感,同时也暴露出了自己平时学习的不足和薄弱环节,进而加以弥补和改正。
参考文献:
[1]戴辉,卢益民.数字视频技术[M].北京:
北京邮电大学出版社,2012.