title('预测误差图像'); subplot(2,3,4); imhist(mat2gray(x1)); title('预测误差直方图'); x2=yucejiema(x1); subplot(2,3,5); imshow(mat2gray(x2)); title('解码图像'); e=double(x)-double(x2); [m,n]=size(e);
erms=sqrt(sum(e(:).^2)/(m*n)); %平方和开方
%预测编码函数;
%一维无损预测编码压缩图像x,f为预测系数,如果f默认,则f=1,即为前值预测
function y=yucebianma(x,f) error(nargchk(1,2,nargin)) if nargin<2 f=1; end
x=double(x); [m,n]=size(x); p=zeros(m,n); xs=x;
zc=zeros(m,1); if length(f)>1 for j=1:length(f)
xs=[zc xs(:,1:end-1)]; p=p+f(j)*xs; end
y=x-round(p); else
xs=[zc xs(:,1:end-1)]; p=xs; y=x-round(p); end
% yucejiema是解码程序,与编码程序用的是同一个预测器 function x=yucejiema(y,f) error(nargchk(1,2,nargin)); if nargin<2 f=1; end
if length(f)>1 f=f(end:-1,1); [m,n]=size(y); order=length(f); x0=zeros(m,n+order); for j=1:n jj=j+order; for i=1:m tep=0.0; for k=order:-1:1
tep=tep+f(k)*x0(i,jj-order-1+k); end
x0(i,jj)=y(i,j)+tep; end end
x=x0(:,order+1:end); else
[m,n]=size(y); x0=zeros(m,n+1); for j=1:n jj=j+1; for i=1:m
x0(i,jj)=y(i,j)+x0(i,jj-1); end end
x=x0(:,2:end); end
图1.10.2 摄影师图像预测编码实验结果
实验三 图像熵编码与压缩
一、实验题目:
图像熵编码与压缩
二、实验目的:
学习和理解建立在图像统计特征基础上的熵编码压缩方法。
三、实验内容:
(1)编程实现二值文本图像的行程编码。
(2)编程实现灰度图像的霍夫曼编码,并计算图像熵、平均码字长度及
编码效率。
四、预备知识:
(1)熟悉行程编码原理。 (2)熟悉霍夫曼编码原理。
(3)熟悉在MATLAB环境下对图像文件的I/O操作。
五、实验原理:
(1)行程编码
行程编码是将一行中颜色相同的相邻像素用一个计数值和该颜色值来代替。 比如,aaabbcccccdddeeee可以表示为3a2b5c3d4e。如果一幅图像由很多块颜色相同的大面积区域组成,则采用行程编码可大大提高压缩效率,尤其适用于二值图像。但当图像中每两个相邻像素的颜色都不相同时,采用这种方法不但不能实现数据压缩,反而使数据量增加一倍。因此,对复杂的图像都不能单纯地采用行程编码。
(2) 霍夫曼编码
霍夫曼编码是一种代码长度不均匀的编码方法。它的基本原理是按信源符号出现的概率大小进行排序,出现概率大的分配短码,反之则分配长码。
霍夫曼编码基本步骤如下:
步骤1:统计图像每个灰度级(信息符号)出现的概率,并按概率从大到小进行排序。
步骤2:选出概率最小的两个值进行组合相加,形成的新概率值和其他概率 值形成一个新的概率集合。
步骤3:重复步骤2,反复利用合并和排序的方法,直到只有两个概率为止。 步骤4: 分配码字,对最后两个概率一个赋予“0”码字,一个赋予“1”码字。
如此反向进行到开始的概率排列,这样就得到了各个符号的霍夫曼编码。
六、实验步骤:
(1)编程实现二值文本图像的行程编码。
(2)编程实现连续灰度图像的霍夫曼编码,并计算图像熵、平均码字长度及编码效率。
七、思考题目:
将行程编码与霍夫曼编码结合,能否提高压缩效果?试验证之。
八、实验程序代码:
(1)二值文本图像的行程编码程序: clear,close all t=imread('text.tif'); ts=logical(t);
codetable=zeros(1,20000); [m,n]=size(ts); nn=n+1; icodecount=1; for i=1:m
p1=ts(i,1);%第i行,第1个像素 ipcount=1;%同一灰度值连续出现的次数 for j=2:n p2=ts(i,j);
if ((p1==p2)&(ipcount codetable(icodecount)=ipcount; codetable(icodecount+1)=p1; icodecount=icodecount+2; p1=p2; ipcount=1; end;