MATLAB图像编码与压缩_第1页
MATLAB图像编码与压缩_第2页
MATLAB图像编码与压缩_第3页
MATLAB图像编码与压缩_第4页
MATLAB图像编码与压缩_第5页
已阅读5页,还剩90页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

8.1图像压缩和编码概述

原始数字图像的数据量一般很大,直接用于存储和传输会占用很大的系统资源。尽管数据存储技术不断发展、信道传输带宽不断增长,但对于压缩图像数据以节省数据存储空间和提高信道利用率的需求仍在不断的增长。因此对图像进行适当的编码和压缩具有很强的现实意义。图像的压缩已成为图像处理的重要研究和应用领域。虽然MATLAB图像处理工具箱中没有针对图像编码和压缩的专门处理工具,但使用MATLAB语言可方便地实现各种压缩算法。图像压缩是在保证一定图像质量的前提下,采取某种编码方式尽量减少图像比特数的图像编码过程。同时,压缩后的图像在解码重建后,要具有与原图像相当的图像质量,否则图像的压缩是无意义的。因此,对压缩图像的品质及其度量方法的研究也是图像压缩领域研究的重点。图像压缩的原理基于两个现实:一是图像信息往往存在很大的冗余度,数据之间存在着相关性,如相邻像素之间的相关性,图像越有规律,像素之间的相关性就越强,可压缩的空间就越大;另一个特点是,由于人眼是图像信息的接收端,所以可以利用视觉对边缘急剧变化不敏感,以及对图像的亮度信息敏感,对颜色分辨率弱等特点来实现对图像的高压缩比,使得解压后的图像信号仍有着较好的质量。基于上述现实发展出的图像压缩方法可基本分为两类:一类是将相同或相似的数据归类,使用较少的数据量描述原始数据,这种压缩被称为无损压缩;第二类方法是利用人眼的视觉特性有针对性地简化不重要的数据,以减少总的数据量,这种压缩被称为有损压缩,只要损失的数据不影响人眼的主观接收效果,就可以采用这种压缩方法。无损压缩利用数据的统计冗余进行压缩,可完全恢复原始数据而不引入任何失真,但压缩率受到数据统计冗余度的理论限制,压缩比一般为2∶1~5∶1,这类方法广泛用于文本数据和特殊应用场合的图像数据(如指纹图像)的压缩。有损压缩利用人眼对图像中的某些频率成分不敏感的特性,允许压缩过程中损失一定的信息。虽然经有损压缩后的图像不能完全恢复成原始图像的状态,但是损失的部分对图像的视觉效果影响较小,同时得到了较大的压缩比。因此,有损压缩方式被广泛应用于语音、图像和视频等数据的压缩中。对于图像压缩,特别是有损压缩,必须对图像压缩的恢复效果进行度量,以判断压缩算法的好坏。逼真度是衡量图像品质的核心参数,一般采用压缩图像与标准图像的偏差作为图像的逼真度的度量,偏差包括亮度、对比度、色度和分辨率等参数上的偏差。常用的逼真度准则有两种,一是客观逼真度准则;二是主观逼真度准则。客观逼真度准则是用编码输入与解码输出图像来计算损失的信息量。最常见的客观逼真度准则是输入、输出图像之间的均方根误差准则。设输入图像和解压图像分别为f (n,m)和,设图像大小为M × N,那么f (n,m)和之间的均方根误差定义为输出图像的均方信噪比也是一种常用的客观保真度准则,其定义如下:(8.1)(8.2)对图像压缩和解压的最终目的还是将图像提供给人眼观察,所以主观逼真度准则是图像压缩效果判断的有效和最终方法。常用的主观保真度度量方法是给一组观察者展示图像,将观察者的评价综合起来进行统计分析,得到主观评价结果。评价可以按照某种绝对尺度进行,也可以通过比较两幅图像(标准图像与解压图像)进行,评价结果一般将图像分为优秀、良好、可用、勉强、差和不可用几种。8.2无损图像压缩

无损压缩算法可以分为两大类:一种是基于字典的编码方法;另外一种是基于统计的编码方法。基于字典的编码方法生成的压缩文件包含的是定长码,即采用相同的位数对数据进行编码。基于字典的编码方法生成的每个码都代表原文件中数据的一个特定序列,常用的基于字典的编码方法有游程编码。基于统计方法生成的压缩文件包含的是变长码,即采用不同的位数对数据进行编码,以节省储存空间。很多图像常含有单色的大面积图块,而且某些颜色比其它颜色出现得更频繁。因此,为了节省空间,在对数据进行编码时,就有可能对那些常出现的数据指定较少的位数来表示,而对那些不常出现的数据指定较多的位数来表示,这样从总的效果看还是节省了储存空间。比如,不同的字符出现的概率是不同的,有的字符出现的概率非常高,有的则非常低。据统计,字母E的使用概率为13%,而字母Z的使用概率仅为0.08%。因此国际电报码中使用单点(“· ”)来表示字母e,而用(“--··”)表示字母z。在实际应用中,最常用的统计编码方法是哈夫曼编码和算术编码。8.2.1行程编码游程编码又称“运行长度编码”,或“游行程编码”,是一种统计编码,该编码属于无损压缩编码,对于二值图有效。行程编码的基本原理是用一个符号值或串长代替具有相同值的连续符号(连续符号构成了一段连续的“行程”,行程编码因此而得名),使符号总长度少于原始数据的长度。例如:55555555777777777333333332222222111111111的行程编码为(5,8)(7,9)(3,8)(2,7)(1,9)。可见,行程编码的位数远远少于原始字符串的位数。从原理上讲,并不是所有的行程编码都远远少于原始字符串的位数。例如,55555是5个字符而(5,6)也是5个字符。在对图像数据(特别是二值图像)进行编码时沿一定方向排列的具有相同灰度值的图像块可看成是连续符号,用字串代替这些连续符号,可大幅度减少数据量。如果图像中有大量的纵向色块,则可以先把图像旋转90°,再用行程编码进行压缩。行程编码是连续精确的编码,在传输过程中,如果其中一位符号发生错误,将会影响整个编码序列,使行程编码无法还原回原始数据。下面一段例程演示如何利用行程编码实现对灰度图像的压缩。程序首先生成一个棋盘图,如图8.1所示,压缩编码后再对比统计压缩的效果。图8.1棋盘图%棋盘图像

I=checkerboard(20);

imshow(I)

[mn]=size(I);

J=[];

fori=1:m

value=I(i,1);

num=1;

forj=2:nifI(i,j)==valuenum=num+1;elseJ=[Jnumvalue];

num=1;value=I(i,j);end

endJ=[Jnumvalue00];%添加的行判断位00enddisp('原图像大小:')whos('I');disp('压缩图像大小:')whos('J');disp('图像的压缩比:')disp(m*n/length(J))图8.1棋盘图

程序运行结果如下:原图像大小:

NameSizeBytesClass I 160x160204800doublearrayGrandtotalis25600elementsusing204800bytes压缩图像大小:

NameSizeBytesClass J1x288023040doublearrayGrandtotalis2880elementsusing23040bytes图像的压缩比:204800/23040=8.88898.2.2算术编码算术编码是一种基于统计的无损数据压缩方法,也是一种熵编码的方法。和其它熵编码方法不同,其它的熵编码方法通常是把输入的消息分割为符号,然后对每个符号进行编码,而算术编码是直接把整个输入的消息编码为一个数,一个满足(0.0≤s<1.0)的小数s。算术编码的编码过程可以用下列简单的实例来描述。例如,假设某条信息中可能出现的字符仅有a、b、c三种,要压缩保存的信息为bccb。开始时暂时认为三者的出现概率相等,也就是都为1/3,将0~1区间按照概率的比例分配给三个字符,即a从0.0000到0.3333,b从0.3333到0.6667,c从0.6667到1.0000。现在拿到第一个字符b,注意b对应的区间为0.3333~0.6667。这时由于多了字符b,三个字符的概率分布变成:Pa = 1/4,Pb=2/4,Pc=1/4。按照新的概率分布比例划分0.3333~0.6667这一区间,即c从0.6667到0.5834,b从0.5834到0.4167,a从0.4167到0.3333。接着拿到字符c,现在要关注上一步中得到的c的区间0.5834~0.6667。新添了c以后,三个字符的概率分布变成Pa=1/5,Pb=2/5,Pc=2/5。用这个概率分布划分区间0.5834~0.6667,即c从0.6667到0.6334,b从0.6334到0.6001,a从0.6001到0.5834。现在输入下一个字符c,三个字符的概率分布为Pa=1/6,Pb=2/6,Pc=3/6。划分c的区间0.6334~0.6667,即c从0.6667到0.6501,b从0.6501到0.6390,a从0.6390到0.6334。输入最后一个字符b,因为是最后一个字符,不用再做进一步的划分了,上一步中得到的b的区间为0.6390~0.6501,在这个区间内随便选择一个容易变成二进制的数,例如0.64,将它变成二进制0.1000000,去掉前面没有太多意义的0和小数点,我们可以输出二进制1000000,这就是信息被压缩后的结果,就完成了一次最简单的算术压缩过程。解码过程与上述编码过程相反,首先0.64位于0.3333~0.6667之间,得到第一个字母b。然后将0.64减去0.3333并除以1/3(b的概率范围)得到0.92。0.92位于3/4~1之间,于是得到第二个字母c。0.92减去3/4并除以1/4(c的概率范围)得到0.68,0.68位于3/5~1之间,于是得到第三个字母c。0.68减去3/5并除以2/5(c的概率范围),得到0.2,0.2位于1/6~2/6之间,于是得到第四个字母b。下面一段例程为用MATLAB设计的算术编码和解码程序。

%算术编码程序

functionacode=arithmetic_encode(symbol,ps,inseq)

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));endlow=0;high=1;fori=1:length(inseq);range=high-low;high=low+range*high_range(sbidx(i));low=low+range*low_range(sbidx(i));endacode=low;%算术解码函数functionsymbos=arithmetic_decode(symbol,ps,codeword,symlen)formatlongehigh_range=[];fork=1:length(ps)high_range=[high_rangesum(ps(1:k))];endlow_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*psminidx=idx+1;codeword=0;endsymbos=[symbossymbol(idx)];codeword=codeword/ps(idx);ifabs(codeword)<0.01*psmini=symlen+1;endend调用上述程序对字符串进行编码和解码:formatlonge;symbol=['abcd'];ps=[0.40.20.10.3];inseq=('daccb');codeword=arithmetic_encode(symbol,ps,inseq)codeword=0.77392outseq=arithmetic_decode(symbol,ps,codeword,length(inseq))outseq=daccb

8.2.3哈夫曼编码哈夫曼编码(HuffmanCoding)是另外一种重要的基于统计的编码方式。此方法是由Huffman于1952年提出的一种编码方法,它完全依据字符出现概率来构造不同字符所对应的最短的码字,有时称之为最佳编码,一般称为Huffman编码。哈夫曼编码可以用于各类数据的无损压缩。哈夫曼编码根据每一个源字符出现的概率建立一张编码表,出现概率高的字符使用较短的编码,反之出现概率低的则使用较长的编码,这样使编码之后的字符串的平均期望长度降低,从而达到无损压缩数据的目的。例如,在英文中,e的出现概率很高,而z的出现概率则最低。当利用哈夫曼编码对一篇英文进行压缩时,e极有可能用一个位(bit)来表示,而z则可能花去25个位。用普通的表示方法时,每个英文字母均占用一个字节(byte),即8个位。二者相比,e使用了一般编码的1/8的长度,z则使用了3倍多。倘若我们能实现对英文中各个字母出现概率的较准确的估算,就可以大幅度提高无损压缩的比例。在用于图像压缩时,哈夫曼编码首先对图像数据扫描一遍,计算出各种像素出现的概率,按概率的大小指定不同长度的唯一字码,由此得到一张该图像的哈夫曼码表。编码后的图像数据记录的是每个像素的码字,而码字与实际像素值的对应关系记录在码表中。当然,码表是附在图像文件中的。哈夫曼编码过程如下:

(1)将消息按出现的概率从大到小排列,记为

p1≥p2≥…≥pm-1≥pm。

(2)给最小的概率pm赋予符号1,倒数第二小的概率pm-1赋予符号0。

(3)计算联合概率pi = pm +pm-1,将未处理的m - 2个概率与pi一起重新排序。

(4)重复步骤(1)到步骤(3),直到所有的概率都被赋予一个0或1符号为止。下面举例说明哈夫曼编码的过程。表8.1给出了信号源发出的8个消息及其出现的概率。表8.1信号源及出现的概率哈夫曼编码过程如图8.2所示。在图8.2中,消息H的概率最小,因此本身的符号为1。H与D的联合概率为0.09,在与F的比较中获得概率符号1。0.09与F的联合概率为0.19,在与B的比较中获得概率符号0。0.19与B的联合概率为0.37,在与另一个联合概率0.23比较中获得概率符号为0。0.37与0.23的联合概率为0.6,在与C的概率比较中获得概率符号0。这样消息H的编码为00011。图8.2哈夫曼编码过程示意图由以上编码过程可看出,对于不同概率的消息,编码字的长度不同。概率大的信息编码字短,概率小的码字长。下面一段例程用MATLAB语言实现哈夫曼编码,其输入值p为概率向量,其输出量h为编码值,l为平均编码位数。

function[h,l]=huffman(p)

iflength(find(p<0))~=0,

error('概率向量值小于0')

endifabs(sum(p)-1)>10e-10,error('概率向量总和不为1')endn=length(p);q=p;m=zeros(n-1,n);fori=1:n-1[q,l]=sort(q);m(i,:)=[l(1:n-i+1),zeros(1,i-1)];q=[q(1)+q(2),q(3:n),1];endfori=1:n-1c(i,:)=blanks(n*n);endc(n-1,n)='0';c(n-1,2*n)='1';fori=2:n-1c(n-i,1:n-1)=c(n-i+1,n*(find(m(n-i+1,:)==1))...-(n-2):n*(find(m(n-i+1,:)==1)));c(n-i,n)='0';

c(n-i,n+1:2*n-1)=c(n-i,1:n-1);c(n-i,2*n)='1';forj=1:i-1c(n-i,(j+1)*n+1:(j+2)*n)=c(n-i+1,...n*(find(m(n-i+1,:)==j+1)-1)+1:n*find(m(n-i+1,:)==j+1));

endend

fori=1:nh(i,1:n)=c(1,n*(find(m(1,:)==i)-1)+1:find(m(1,:)==i)*n);

l1(i)=length(find(abs(h(i,:))~=32));endl=sum(p.*l1);下面一段代码调用[h,l]=huffman(p)并输出编码结果:

p=rand(1,10);

p=p/sum(p);

[h,l]=huffman(p);

p=0.16760.04080.10710.08570.15720.13440.08050.00330.1449

0.0785

h= 000110101011111101001110011001010111

l=3.1652在将哈夫曼编码用于图像压缩时,首先要统计图像中各种颜色(或灰度)出现的概率,产生概率向量,然后调用huffman(p)计算编码值。一般将颜色值和其对应的编码作为文件头写入压缩文件,而后将图像中的各个像素译成相应的编码并写入文件,即完成了文件的压缩。8.3有损图像压缩

8.3.1预测编码将图像数据按照行或列重新排列后可得到一个一维信号序列。预测编码根据这个信号序列的一些已知情况来预测以后信号可能的状态,然后对预测的误差进行编码。在误差较小的情况下,这种编码可以比直接对信号进行编码节省较大的数据量。下面介绍信号预测的一般方法。假设已知信号xn以前的信号xn - 1,xn - 2,…,xn - m的值,那么可以得到xn的预测估计值为如果估计值是信号xn-1,xn-2,…,xn-m的线性组合,那么就称该预测为线性预测,否则为非线性预测。定义预测的误差为(8.3)(8.4)如果函数f (xn - 1,…,xn - m)选择的比较准确,那么xn和的差值将比较小。为了按照一定的最优标准来定义预测估计值函数,一般都采用均方误差最小作为预测的准则,预测误差的统计均方值为(8.5)这样线性预测问题就转化为怎样利用均方误差最小原则求取预测系数。令均方误差对每个预测系数的偏导为零,即于是可以得到N - m个线性方程组:(8.6)(8.7)当N - m>m时,用最小二乘的方法可以求取一组最优的线性预测系数。但上述方法对于每幅图像都要计算出预测函数,适用范围小,计算复杂。对于二维图像,通常使用以下简化的预测公式进行预测。(8.8)式(8.8)中的系数总和为1可以保持图像的平均亮度不变。式(8.8)中表示的预测情形是用相邻像素值进行预测的,如图8.3所示,是一种简单的二维预测方法。这种方法利用了图像行与行之间的相关性来进一步提高压缩比。图8.3二维线性预测预测编码也可用于运动图像帧之间的压缩,这时压缩的效果自然与图像的运动变化规律密切相关。下面一段代码用式(8.8)实现图像的预测编码,并将编码结果取整型,以减少储存空间。运行结果如图8.4所示。

I=imread('D:\eye.jpg');

I=rgb2gray(I);

imshow(I);

I=double(I);

[m,n]=size(I);J=zeros(m,n);J(1:m,1)=I(1:m,1);J(1,1:n)=I(1,1:n);J(1:m,n)=I(1:m,n);J(m,1:n)=I(m,1:n);fork=2:m-1forl=2:n-1J(k,l)=I(k,l)-(I(k,l-1)/2+I(k-1,l)/4+I(k-1,l-1)/8+I(k-1,l+1)/8);

endendJ=round(J);figureimshow(J);图8.4预测编码图像和编码结果下面一段代码实现预测编码的解码,使用的变量与编码程序相对应,运行结果如图8.5所示,对比图8.4可知解码图像的逼真度比较高。

J=double(J);

[mn]=size(J);

I=ones(m,n);

I(1:m,1)=J(1:m,1);

I(1,1:n)=J(1,1:n);

I(1:m,n)=J(1:m,n);

J(m,1:n)=J(m,1:n);

fork=2:m-1

forl=2:n-1

I(k,l)=J(k,l)+(J(k,l-1)/2+J(k-1,l)/4+J(k-1,l-1)/8+J(k-1,l+1)/8);

end

nd

图8.5预测解码图像8.3.2变换编码预测编码认为冗余度是数据固有的,通过对信源建模来尽可能精确地预测源数据,去除图像的时间冗余度。但是冗余度有时与不同的表达方法也有很大的关系,变换编码是将原始数据“变换”到另一个更为紧凑的表示空间,去除图像的空间冗余度,可得到比预测编码更高的数据压缩比。

1968年,出现了正交变换图像编码,H.C.Andrews等人提出不对图像本身编码,而对其二维离散傅立叶系数进行编码和传输(DFT)。但这是一种复变换,运算量大,不易实时处理。1974年,N.Ahmed等人提出了离散余弦变换(DiscreteCosineTransform,DCT),DCT常常被认为是图像信号的准最佳变换。DCT是一种空间变换,DCT变换的最大特点是对于一般的图像都能够将像块的能量集中于少数低频DCT系数上,这样就可能只编码和传输少数系数而不会严重影响图像质量。由于近年来数字信号处理芯片(DSP)的发展,加上其在专用集成电路设计上的优势,牢固地确立了DCT变换在目前图像编码中的重要地位,成为H.261、JPEG、MPEG等国际上公用的编码标准的重要环节。在视频压缩中,最常用的变换方法是DCT,DCT变换编码的主要特点有:

(1)视频图像在变换域里要比空间域里简单。

(2)经过DCT变换后,视频图像的相关性明显下降,信号的能量主要集中在少数几个变换系数上,采用量化和熵编码可有效地压缩其数据。

(3)具有较强的抗干扰能力,传输过程中的误码对图像质量的影响远小于预测编码。DCT变换的概念在第三章已经介绍过,下面主要介绍DCT在压缩编码中的具体应用。用DCT实现图像的压缩编码需要经过变换、量化和编码三个步骤。其中二维DCT压缩和解压的流程框图如图8.6所示。图8.6二维DCT压缩和解压的流程框图进行二维DCT图像压缩时,首先要将图像分成若干个N×N的图像块,N一般取为8。然后调用快速DCT将8×8数据块分解成64个正交基信号,每个基信号都对应64个独立二维空间中的某一个频率分量。这些频率分量中包括一个直流分量系数和63个交流分量。DCT变换的解压过程就是对这64个DCT变换系数进行逆变换,重建一个64点的输出图像。在8×8像素块上完成DCT变换之后,为了在压缩比方面获得大的提高需要量化过程。量化过程指的是用一组预定的容许值之一代表实际系数值的过程,以便用较少的位数对全部数据编码。人眼对低频分量的图像比对高频分量的图像更敏感。因此,高频分量的图像中的细小错误不容易被发现,完全去掉一些高频分量通常在视觉上是可以接受的。JPEG算法中的量化过程正是利用这一特性来降低对给定8×8像素块编码所需要的DCT信息量。在JPEG处理中,量化是不可逆的关键步骤。虽然完成一个DCT反变换由于舍入误差将不能精确地恢复原始输入的8×8输入矩阵,但是其结果通常在视觉上是完全能接受的。然而,由于量化后原来未量化的系数的精密度会永久地丢失,所以量化仅用在有损压缩算法中。当量化表建立好之后量化过程就很简单,就是对于给定的行和列,DCT输出系数与量化系数的元素简单相除。但是量化表本身也可能非常复杂,DCT变换输出8×8数据块的每个元素通常具有一个单独的量化系数。因为这个输出矩阵对应于其输入像素块与64个DCT基函数关系的密切程度,并且可以用实验方法测定每个DCT频率对人眼的重要性,由此做出相应的量化处理,如表8.2所示。表8.2DCT亮度量化表量化后的二维系数要重新编排,转换为一维系数。为了增加连续的“0”系数的个数,就是“0”的游程长度,DCT编码中采用的“Z”字形编排方法。在DCT输出中,随着水平方向和垂直方向频率值的增加,其量化系数变为零的机会越来越大。为了利用这一特性,我们可将这些二维系数按照从DC系数开始到最高阶空间频率系数的顺序重新编排为一维系数。通过使用“Z”字形编码方法实现这种编排,即在8×8像素块中沿着空间频率增加的方向呈“Z”字形来回移动,如图8.7所示。使用“Z”字形编排模式,能产生一个一维系数向量。图8.7DCT编码中的Z字形编排每个量化后的DCT输出矩阵都经过Z字形编码过程。从DCT二维系数生成的64×1一维数组中的第一个元素代表DC系数,其余的63个系数代表AC系数。这两类系数完全不同足以将它们分开,并且可采用不同的编码方法以获得最佳压缩效率。

必须对所有的DC系数(每个DCT输出块中有一个)分组放在一起。因此,对DC系数组和每个AC系数组分别编码。

DC系数代表每个8×8像素块的亮度(数值比较大)。因此,它们在相邻像素块之间存在很大相关性(DC系数值变化不大)。虽然仅靠相邻的DC系数不能完全正确地预测任何给定输入数组的DC系数,但实际图像的DC系数通常在局部区域变化不大。因此,可以用以前的DC系数预测当前的DC系数。通过使用差分预测技术(DPCM)对相邻图像块之间的DC系数的差值进行编码,能增加对数值很小的系数进行编码的可能性,从而降低压缩图像中的位数。为了获得编码值,我们简单地用当前的像素块中的DC系数减去以前处理过的8×8像素块的DC系数,这个差值被称为“DPCM差值”。该差值一旦计算出来,与一个表比较以确定它属于的符号组(根据其幅度),然后使用熵编码方法(如哈夫曼编码)进行适当的编码。由于经过量化后有许多AC系数值变为零,所以对这些系数要采用游程编码。在实际图像序列中,相同值的像素总可以用单个字节表示。例如,我们看到量化后的DCT输出数据块产生许多系数为零的字节。Z字形编排有助于在每个序列末尾产生系数为零的数组。下面给出用MATLAB语言实现的DCT图像编码和解码例程,供大家参考。

%DCT编码程序

%--------------------------初始化-----------------------------

%量化表矩阵

Q_8x8=uint8([

%DCT系数优先级矩阵,低频优先级高

dct_coefficient_priority_8x8=[

%Z字形编排矩阵

ZigZag_Order=uint8([

%生成反向Z字形编排矩阵

reverse_zigzag_order_8x8=zeros(8,8);fork=1:(size(ZigZag_Order,1)*size(ZigZag_Order,2))reverse_zigzag_order_8x8(k)=find(ZigZag_Order==k);end;

Compressed_image_size=0;

%--------------------------打开图像----------------------------input_image=im2double(imread('D:\helicopter.bmp'));[imsize_x,imsize_y]=size(input_image);%--------------------------------------------------------------------

figureimshow(input_image);title('原始图像');%----------------根据DCT系数优先级矩阵,选择DCT系数------------------

coef_selection_matrix_8x8=zeros(8,8);chosen_number_of_dct_coefficient=21;

forl=1:chosen_number_of_dct_coefficient

[y,x]=find(dct_coefficient_priority_8x8==min(min(dct_coefficient_priority_8x8)));

coef_selection_matrix_8x8(y,x)=1;

%已经选过的系数置99,以便下次循环不再选到

dct_coefficient_priority_8x8(y,x)=99;end

%将系数选择矩阵复制(imsize_x*imsize_y/(8*8))份,以对应整个图像

selection_matrix=repmat(coef_selection_matrix_8x8,imsize_x/8,imsize_y/8);%-------------------------计算8×8DCT-------------------------------dct_transformed_image=Classic_DCT(input_image).*selection_matrix;

figureimshow(dct_transformed_image);title('图像8x8DCT变换');

%DCT系数归一化

Maximum_Value_of_dct_coeffieient=max(max(dct_transformed_image));dct_transformed_image=dct_transformed_image./Maximum_Value_of_dct_coeffieient;%转换成8位整型

dct_transformed_image_int=im2uint8(dct_transformed_image);

%量化quantization_matrix=repmat(Q_8x8,imsize_x/8,imsize_y/8);

quantized_image=round(dct_transformed_image_int./quantization_matrix);%将8×8图像块转化成列矩阵Single_column_quantized_image=im2col(quantized_image,[88],'distinct');

%将每个8 × 8数据块进行Z字形编排ZigZaged_Single_Column_Image=Single_column_quantized_image(ZigZag_Order,:);%对每个8 × 8数据块中的零值数据进行行程编码,将编码结果写入run_level_pairs中run_level_pairs=double([]);forblock_index=1:(imsize_x*imsize_y)/64%共有(imsize_x*imsize_y)/8^2

个8×8数据块在图像中

single_block_image_vector_64(1:64)=1;forTemp_Vector_Index=1:64single_block_image_vector_64(Temp_Vector_Index)=ZigZaged_Single_Column_Image(Temp_Vector_Index,block_index);end

non_zero_value_index_array=0;non_zero_value_index_array=find(single_block_image_vector_64~=0);number_of_non_zero_entries=length(non_zero_value_index_array);ifnumel(non_zero_value_index_array)>0ifnon_zero_value_index_array(1)==1run=0;run_level_pairs=cat(1,run_level_pairs,run,single_block_image_vector_64(non_zero_value_index_array(1)));endforn=2:number_of_non_zero_entries,run=non_zero_value_index_array(n)-non_zero_value_index_array(n-1)-1;run_level_pairs=cat(1,run_level_pairs,run,single_block_image_vector_64(non_zero_value_index_array(n)));

endend%写入两个255作为次数据块编码的结束符

run_level_pairs=cat(1,run_level_pairs,255,255);end%-Compressed_image_size=size(run_level_pairs);%计算压缩比

Compression_Ratio=imsize_x*imsize_y/Compressed_image_size(1,1)

%DCT解码程序

%----------------------行程解码---------------------------

c=[];runsize=size(run_level_pairs);forn=1:2:runsize(1,1)

ifrun_level_pairs(n)<255zero_count=0;zero_count=run_level_pairs(n);forl=1:zero_countc=cat(1,c,0);endc=cat(1,c,run_level_pairs(n+1));

elsenumber_of_trailing_zeros=64-mod(size(c),64);forl=1:number_of_trailing_zerosc=cat(1,c,0);endendend

fori=1:(imsize_x*imsize_y)/64forj=1:64

ZigZaged_Single_Column_Image(j,i)=c(64*(i-1)+j);endend%---------------------------------------------------------------------

%---------------------------反向Z字形编排--------------------------Single_column_quantized_image=ZigZaged_Single_Column_Image(reverse_zigzag_order_8x8,:);%---------------------------------------------------------------------

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论