像图统计编码演示程序的设计毕业设计.docx
《像图统计编码演示程序的设计毕业设计.docx》由会员分享,可在线阅读,更多相关《像图统计编码演示程序的设计毕业设计.docx(22页珍藏版)》请在冰豆网上搜索。
像图统计编码演示程序的设计毕业设计
毕业论文(设计)
题目:
图像统计编码演示程序的设计
学制:
4年
专业:
通信工程
摘要
(1)
关键词
(1)
1matlab简介
(1)
1.1matlab概述
(1)
1.2MATLAB在数字图像处理中的应用
(2)
2数字图像处理(3)
2.1概述(3)
2.2图像统计编码(3)
2.2.1霍夫曼编码(3)
2.2.2霍夫曼编码算法(4)
3图像统计编码程序设计(5)
3.1总体方案设计(5)
3.1.1系统运行环境(5)
3.1.2功能模块划分(5)
3.1.3系统方框图(6)
3.2各模块功能实现程序(7)
4测试和调试(21)
4.1霍夫曼编码实现效果(21)
4.2算术编码的结果(23)
6总结(25)
参考文献(25)
Abstract(26)
图像统计编码演示程序的设计
作者:
xxx
指导老师:
xxx
摘要:
数字图像处理是一门新兴技术,随着计算机硬件的发展,数字图像的实时处理已经成为可能,由于数字图像处理的各种算法的出现,使得其处理速度越来越快,能更好的为人们服务。
数字图像处理是一种通过计算机采用一定的算法对图形图像进行处理的技术。
数字图像处理技术已经在各个领域上都有了比较广泛的应用。
图像处理的信息量很大,对处理速度的要求也比较高。
MATLAB强大的运算和图形展示功能,使图像处理变得更加的简单和直观。
本文介绍了MATLAB语言的特点,基于MATLAB的数字图像处理环境,介绍了如何利用MATLAB及其图像处理工具箱进行数字图像处理,并通过一些例子来说明利用MATLAB图像处理工具箱进行图像处理的方法。
主要论述了利用MATLAB实现图像编码等图像处理。
关键词:
MATLAB;数字图像处理;图像统计编码;霍夫曼编码
1MATLAB简介
1.1MATLAB概述
MATLAB是MATrixLABoratory(“矩阵实验室”)的缩写,是由美国MathWorks公司开发的集数值计算、符号计算和图形可视化三大基本功能于一体的,功能强大、操作简单的语言。
是国际公认的优秀数学应用软件之一。
MATLAB的基本数据单位是矩阵,它的指令表达式与数学,工程中常用的形式十分相似,故用MATLAB来解算问题要比用C,FORTRAN等语言完相同的事情简捷得多。
MATLAB包括拥有数百个内部函数的主包和三十几种工具包(Toolbox).工具包又可以分为功能性工具包和学科工具包.功能工具包用来扩充MATLAB的符号计算,可视化建模仿真,文字处理及实时控制等功能.学科工具包是专业性比较强的工具包,控制工具包,信号处理工具包,通信工具包等都属于此类.
开放性使MATLAB广受用户欢迎.除内部函数外,所有MATLAB主包文件和各种工具包都是可读可修改的文件,用户通过对源程序的修改或加入自己编写程序构造新的专用工具包.
1.2MATLAB在数字图像处理中的应用
图像处理工具包是由一系列支持图像处理操作的函数组成的。
所支持的图像处理操作有:
图像的几何操作、邻域和区域操作、图像变换、图像恢复与增强、线性滤波和滤波器设计、变换(DCT变换等)、图像分析和统计、二值图像操作等。
下面就MATLAB在图像处理中各方面的应用分别进行介绍。
(1)图像文件格式的读写和显示。
MATLAB提供了图像文件读入函数imread(),用来读取如:
bmp、tif、tiffpcx、jpg、gpeg、hdf、xwd等格式图像文;图像写出函数imwrite(),还有图像显示函数image()、imshow()等等。
(2)图像处理的基本运算。
MATLAB提供了图像的和、差等线性运算,以及卷积、相关、滤波等非线性算。
例如,conv2(I,J)实现了I,J两幅图像的卷积。
(3)图像变换。
MATLAB提供了一维和二维离散傅立叶变换(DFT)、快速傅立叶变换(FFT)、离散余弦变换(DCT)及其反变换函数,以及连续小波变换(CWT)、离散小波变换(DWT)及其反变换。
(4)图像的分析和增强。
针对图像的统计计算MATLAB提供了校正、直方图均衡、中值滤波、对比度调整、自适应滤波等对图像进行的处理。
(5)图像的数学形态学处理。
针对二值图像,MATLAB提供了数学形态学运算函数;腐蚀(Erode)、膨胀(Dilate)算子,以及在此基础上的开(Open)、闭(Close)算子、厚化(Thicken)、薄化(Thin)算子等丰富的数学形态学运算。
以上所提到的MATLAB在图像中的应用都是由相应的MATLAB函数来实现的,使用时,只需按照函数的调用语法正确输入参数即可。
具体的用法可参考MATLAB丰富的帮助文档。
图像边缘对图像识别和计算机分析十分有用,在MATLAB中,函数edge()用于灰度图像边缘的提取,它支持六种不同的边缘提取方法,即Sobel方法、Prewitt方法、Robert方法,Laplacian2Gaussian方法、过零点方法和Canny方法。
2数字图像处理
2.1概述
图像处理就是对图像信息进行加工处理,以满足人得视觉心理和实际应用的需求。
图像处理可以应用光学方法、电子学方法,从60年代开始,随着计算机技术的发展,数字图像处理获得了飞跃的发展。
所谓数字图像处理,就是利用数字计算机或其他高速、大规模集成数字硬件,对从图像信息转换来的数字电信号进行某些数字运算或处理,一起提高图像质量或达到人们要求的某些与预期的结果。
如对被噪声污染的图像去除噪声;对信息微弱的图像进行增强处理;对失真的图像进行几何校正;从遥感图片中辨别农作物、森林、琥珀和军用设施等等。
应用计算机处理图像精度高,改变软件即可变换处理方法,灵活方便。
但由于计算机是顺序处理技术,因此对信息量较大的图像,运算处理速度不如光学方法快。
2.2图像统计编码
统计编码又称熵编码,他建立在图像统计特征基础之上的数据压缩方法。
根据香农的观点,信息冗余来自信息源数据本身的相关性和信源内事件的概率分布不均,只要找到去除相关性和改变概率分布不均的方法,也就找到了信源数据的统计编码方法。
熵编码即编码过程中按熵原理不丢失任何信息的编码。
信息熵为信源的平均信息量(不确定性的度量)。
常见的熵编码有:
LZW编码、香农(Shannon)编码、霍夫曼(Huffman)编码和算术编码(arithmeticcoding)。
2.2.1霍夫曼编码
霍弗曼编码完全依据信源字符出现的概率来构造其码字,对出现概率大的字符使用较短的码字,面对出现概率低的字符使用较长的码字,从而达到压缩数据的目的。
霍夫曼编码有时有称为最佳编码(一般直接称为霍夫曼编码),最初主要用于文本文件压缩。
霍夫曼编码是一种变长编码(VLC),同时也是一种无失真编码。
在具有相同信源概率分布的前提下,他的平均码字长度比其他任何一种有效编码方法都短。
2.2.2霍夫曼编码算法
霍夫曼编码是以信源字符的概率分布为基础的,若理论上并不知道信源字符的概率分布,那么可以根据对大量数据进行统计所得到的统计分布来近似代替。
以统计数据代替实际概率分布,可能会导致实际应用时霍夫曼编码无法达到最佳编码效果,应用中可以根据输入数据序列自适应的匹配信源概率分布的方法,这样能在一定程度上能改进霍夫曼编码的性能。
香农编码也是一种典型的可变字长编码。
与霍夫曼编码相似,当信源符号出现的概率正好为2的负幂次方时,香农编码的编码效率可以达到100%
从理论上分析,采用霍夫曼编码可以获得最佳信源字符编码效果,但实际应用中,由于信源字符出现的概率并非满足2的负幂次方,因此往往无法达到理论上的编码效率和信息压缩比。
为了提高编码效率,Elias等人提出了算术编码算法。
算术编码是信息保持型编码,他不像霍夫曼码,无需为一个符号设定一个码字。
算术编码可以分为固定方式编码和自适应方式编码两种。
选择不同的编码方式,将直接影响到编码效率。
自适应算术编码的方式,无需先定义概率模型,适合于无法知道信源字符概率分布的情况。
这也是算术编码优于霍夫曼编码的地方之一。
同时,当信源字符出现的概率比较接近时,算术编码效率高于霍夫曼编码的效率,在图像通信中常用它来取代霍夫曼编码。
不足之处是实现算术编码算法的硬件比霍夫曼编码复杂。
3图像统计编码程序设计
3.1总体方案设计
3.1.1系统运行的环境
WindowsXP、Matlab7.0
3.1.2功能模块的划分
①Huffman编码中:
主程序调用huffencode函数对输入矩阵vector进行Huffman编码,返回编码后的向量(压缩后数据)及相关信息;
再调用huffdecode函数对输入矩阵vector进行Huffman解码,返回解压后的图像数据;
调用addnode函数添加节点;
调用frequency函数计算各符号出现的概率;
调用decode函数返回码字对应的符号。
Huffman编码的步骤:
l)将信号源的符号按照出现概率递减的顺序排列。
2)将两个最小出现概率进行合并相加,得到的结果作为新符号的出现概率。
3)重复进行步骤1和2直到概率相加的结果等于1为止。
4)在合并运算时,概率大的符号用编码0表示,概率小的符号用编码1表示。
5)记录下概率为1处到当前信号源符号之间的0,l序列,从而得到每个符号的编码。
②算术编码中:
主程序调用arithencode函数对symbol进行算术编码;
再调用arithdecode对算术编码进行解码。
算术编码不是将单个信源符号映射成一个码字,而是把整个信源表示为实数线上的0到1之间的一个区间,其长度等于该序列的概率。
再在该区间选择一个代表性的小数,转化成二进制作为实际的编码输出。
消息序列中的每个元素都要缩短为一个区间。
消息序列中元素越多,所得到的区间就越小。
当区间变小时,就需要更多的数位来表示这个区间。
采用算术编码,每个符号的平均编码长度可以为小数。
3.1.3系统方框图
1Huffman编码:
开始
加载图像
将图像转换成无符号的8位整数
调用Huffman编码程
序进行压缩
调用Huffman解码程
序进行解码
结束
子程序:
函数调用
显示图像,原始图像和经编码解码后的图像显示压缩比
②算术编码:
3.2各功能模块的主要实现程序
3.2.1用Matlab程序实现Huffman编码
clear
X=imread('rice.tif');%从MAT文件下载到工作空间
data=uint8(X);%将该图片定义为无符号8为整数
[zipped,info]=huffencode(data);%调用Huffman编码程序进行压缩
unzipped=huffdecode(zipped,info);%调用Huffman解码程序进行解码
subplot(121);imshow(data);%显示原图像
subplot(122);imshow(unzipped);%显示经编码、解码后的图像
erms=compare(data(:
),unzipped(:
))%计算两幅图,得均方根误差
cr=info.ratio
whosdataunzippedzipped
function[zipped,info]=huffencode(vector)%函数声明,huffencode对输入矩阵vector进行Huffman编码
%输入和输出都是uint8格式
if~isa(vector,'uint8')%若矩阵vector是给定类时,为真
error('inputargumentmustbeauint8vector');%跳出函数并显示信息
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);
whilelength(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;
forindex=1:
length(vector)%得到整个图像所有比特数
len=len+length(codeword{double(vector(index))+1});
end
string=repmat(uint8(0),1,len);
pointer=1;
forindex=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个零
ifpad>0
string=[stringuint8(zeros(1,pad))];
end
codeword=codeword(symbols);
codelen=zeros(size(codeword));
weights=2.^(0:
23);
maxcodelen=0;
forindex=1:
length(codeword)
len=length(codeword{index});
iflen>maxcodelen
maxcodelen=len;
end
iflen>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;%将字符串的长度除以8,得到列数
string=reshape(string,8,cols);%对这个字符串阶数重组,8行,cols列
weights=2.^(0:
7);
zipped=uint8(weights*double(string));
huffcodes=sparse(1,1);%码表存储到一个稀疏矩阵
forindex=1:
nnz(codeword)%length(codeword),numel(codeword)
huffcodes(codeword(index),1)=symbols(index);
end
%填写解码时所需的结构信息
info.pad=pad;%添加的比特数
info.huffcodes=huffcodes;%产生Huffman码字
info.ration=cols./length(vector);%显示原始图像的列数除以矩阵长度的值
info.length=length(vector);%显示原始图像数据长度
info.maxcodelen=maxcodelen;%显示最大码长
info.rows=m;%显示原始图像的行数
info.cols=n;%显示原始图像的列数
functionvector=huffdecode(zipped,info,image)%huffdecode函数对输入矩阵vector进行
Huffman解码,返回解压后的图像数据
if~isa(zipped,'uint8')
error('inputargumentmustbeauint8vector');
end
len=length(zipped);%产生0、1序列,每位占一个字节
string=repmat(uint8(0),1,len.*8);
bitindex=1:
8;
forindex=1:
len
string(bitindex+8.*(index-1))=uint8(bitget(zipped(index),bitindex));
end
string=logical(string(:
)');
len=length(string);
string((len-info.pad+1):
end)=[];
len=length(string);
weights=2.^(0:
51);%开始解码
vector=repmat(uint8(0),1,info.length);
vectorindex=1;
codeindex=1;
code=0;
forindex=1:
len
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;
end
end
vector=reshape(vector,info.rows,info.cols);
functioncodeword_new=addnode(codeword_old,item)%函数addnode添加节点
codeword_new=cell(size(codeword_old));
forindex=1:
length(codeword_old)
codeword_new{index}=[itemcodeword_old{index}];
end
functionf=frequency(vector)%函数frequency计算各符号出现的概率
if~isa(vector,'uint8')
error('inputrgumentmustbeauint8vector');
end
f=repmat(0,1,256);
len=length(vector);
forindex=0:
255
f(index+1)=sum(vector==uint8(index));
end
f=f./len;
functionbyte=decode(code,info)%函数decode返回码字对应的符号
byte=info.huffcodes(code);
3.2.3算术编码的Matlab实现
clearall;
formatlonge;%设置输出格式
symbol=['abcd'];%将信源符号定义为符号函数,四个信源符号分别为a、b、c、d
ps=[0.10.40.20.3];%四个信源符号出现的概率
inseq=('cadacdb');%设定某一消息序列
codeword=arithencode(symbol,ps,inseq)
outseq=arithdecode(symbol,ps,codeword,length(inseq))
functionacode=arithencode(symbol,ps,inseq)%函数arithencode对symbol进行算术编码
high_range=[];%定义high_range
fork=1:
length(ps)
high_range=[high_rangesum(ps(1:
k))];
end
low_range=[0high_range(1:
length(ps)-1)];
sbidx=zeros(size(inseq));
fori=1:
length(inseq)
sbidx(i)=find(symbol==inseq(i));
end
low=0;high=1;
fori=1:
length(inseq);
range=high-low;
high=low+range*high_range(sbidx(i));
low=low+range*low_range(sbidx(i));
end
acode=low;
functionsymbos=arithdecode(symbol,ps,codeword,symlen)%函数arithdecode对算术编码进行解码
formatlonge;
high_range=[];
fork=1:
length(ps)
high_range=[high_rangesum(ps(1:
k))];
end
low_range=[0high_range(1:
length(ps)-1)];
psmin=min(ps);
symbos=[];
fori=1:
symlen
idx=max(find(low_range<=codeword));
codeword=codeword-low_range(idx);
ifabs(codeword-ps(idx))<0.01*psmin
idx=idx+1;
codeword=0;
end
symbos=[symbossymbol(idx)];
codeword=codeword/ps(idx);
ifabs(codeword