基于DCT变换的JPEG图像压缩原理

1、为什么要进行图像压缩

       众所周知,当今人类社会具有三大支柱,即物质、能量、信息。当下已由物质过渡到信息,从农业现代化到工业现代化,再到当今的信息化时代。信息具有通用性抽象性无限性。其通用性表现在信息的无所不在和无时不在特点上;抽象性表现在信息不是一个具体的物理物质,没有重量,没有长度;而无限性表现在物质的不可分性,也可以理解为通信网络发展的不可预测,以及电话线模式的不断发展,带来通信信息的扩展以及通信模式的不断更新,变化。

       随着信息技术的发展,图像信息被广泛应用于多媒体通信和计算机系统中,不仅使社会环境更加绚丽多彩,同时给信息化时代的用户提供一种更加直观、确定的获取信息资源的一种便利方法。但是图像信息庞大的数据量,不经压缩处理,不仅会超出计算机的存储和处理能力,同时在现有通信信道的带宽下,无法既在保证图像质量的情况下,又进行大量多媒体信息快速和实时的传输,造成网络负载加剧,计算机处理能力降低,从而影响用户交互心情。


       因此,为了更好的、有效的存储处理以及传输这些图像数据信息,必须进行Image Compression。

2、什么是图像压缩

       目前常用的图像文件格式有十几种,其中JPEG格式由于占用空间小,图像质量高,而为用户广泛采用。JPEG即联合图像专家组(Joint Photographic Experts Group),隶属于ISO国际标准化组织,主要负责定制静态数字图像的编码方法,即所谓的JPEG算子。她适用于各种不同类型、不同分辨率的彩色和黑白二值静止图像。现阶段,JPEG专家小组开发出2种压缩算法,2种熵编码方法以及4种编码模式,如下:

       压缩算法:

       (1)有损的离散余弦变化DCT(Discrete Cosine Transform);

       (2)无损的预测压缩技术;

      熵编码方法:

       (1)Huffman编码

       (2)算术编码;

       编码模式:

       (1)基于DCT的顺序模式:编码、解码通过一次扫描完成;

       (2)基于DCT的渐进模式:编码、解码需要多次扫描完成,扫描效果由粗到精,逐级递增;

       (3)无损模式:基于DPCM,保证解码后完全精确恢复到原图像采样值;

       (4)层次模式:图像在多个空间分辨率中进行编码,可根据需要只对低分辨率数据解码,放弃高分辨率信息;

       实际生活中采用以上红色标注的压缩方法。这是JPEG的基本压缩系统。其中压缩过程一共分为以下9个步骤:颜色空间转换采样分块离散余弦变换(DCT)(Zigzag Z字形扫描排序)量化DC系数的DCPM编码AC系数的游程长度编码熵编码压缩。


3、JPEG压缩过程详解

(1)颜色空间转换

       颜色通常可以使用三种不同的属性对之进行描述,三个独立变量综合作用,就构成了空间坐标,这就是颜色空间。而颜色可以从不同的角度,用三个一组的不同属性加以描述,这就构成了不同的颜色空间。描述的颜色对象是客观的,不同的颜色空间只是从不同的角度去刻画衡量同一个颜色对象。所以,颜色空间的出现大多是面向具体的应用和行业的。

       颜色空间(也叫彩色模型、彩色系统、色彩空间)的概念其实质是一种用途,是一种针对不同应用而采用某接受的方式对彩色加以说明的彩色模型(这里可接受我们可以理解为上面所说的三种不同属性的变量)。

市场上大概推出了上百种颜色空间,常见的有:

       RGB  用于扫描仪和显示设备、计算机系统(将颜色的亮度、色度、饱和度融为一体)[red,green,blue]

       CMY  用于打印机、印刷出版业[cyan,magenta,yellow]

       HSV/HSI/HSB/HSL   广泛用于图像处理和计算机视觉          

              [hue,saturation,value/intensity/brightness/luminance(or lightness)色度,饱和度,亮度]

       YUV/YCbCr  用于视频和电视,JEPG采用的是YCbCr颜色空间,但同时大多数计算机系统采用的是RGB颜色空间。

       采用YUV颜色空间的重要性是它的亮度信号Y和色度信号U、V是分离的(Y表示亮度,U(Cb)、V(Cr)表示色度,有时候分别又说表示色度和饱和度)。如果只有Y信号分量而没有U、V分量,那么这样表示的图就是黑白灰度图。彩色电视采用YUV空间正是为了用亮度信号Y解决彩色电视机与黑白电视机的兼容问题,使黑白电视机也能接收彩色信号。

       电视信号在发射时,转换成YUV形式,接受时再还原成RGB三基色信号,由显像管显示(RGB->YUV->编码发送------YUV->RGB->显示

       这里主要利用了HVS(Human Visual System)对亮度比色度更敏感的特点,而计算机系统没有人眼这样的识别功能,所以主要使用RGB三基色原理(世界中任一颜色都可以使用RGB以不同的权重联合起来表示)。

       因此,针对图像压缩,CV等需要将RGB颜色空间的图像转换为YUV彩色模型的图像,方便后续的图像处理(如压缩,增强,恢复等)。

       RGB->YUV:

       Y = 0.299R+0.587G+0.114B

       Cb = -0.1687R-0.3313G+0.5B+128

       Cr = 0.5R=0.418G-0.0813B+128

       (一般来说,C值(包括Cb、Cr)应该是一个有符号的数字,但这里通过加上128,使其变为8位的无符号整数,从而方便数据的存储和计算。)

       YUV->RGB:

       R = Y+1.402(Cr-128)

       G = Y-0.34414(Cb-128)-0.71414(Cr-128)

       B = Y+1.772(Cb-128)

(2)采样

       根据生物学研究表明,HVS对亮度比色度更敏感。因此我们可以认为将彩色信息的清晰度较低些,这样可显著压缩色度所需带宽,也就是Y分量比Cb和Cr的分量重要的多。在图片格式国际标准BMP中,采用的RGB颜色空间三个分量就需要3个字节进行采样,也就是我们说的RGB888模式。在JPEG中主要采用411和422的采样方式。(也就是在2X2的空间域中,本应总共需要4个Y,4个U,4个V,总共需要4+4+4=12字节,422采样意思为每4个像素单元有4个Y,2个U,2个V,此时只需要4+2+2=8字节,411则是6字节,相应的420类似。其中420格式广泛用于数字电视、会议电视、DVD中)

       采用这样的采样方式,虽然损失了一定的精度,但是在HVS观察不到的前提下较少了数据量。

(3)分块

       因为后续的DCT变换是基于8X8大小的像素块的,因此针对一副数字图像在DCT之前需要进行分块。由于图像的YUV三个分量是交替出现的,首先需要将依次分量分开存入3张表中;然后依次从左到右,从上到下,读取8X8的子块,存放到64长度的表中,然后进行DCT变换,量化,编码,然后在读取下一块进行类似操作。

       JPEG编码是以8X8的块为单位进行处理的,但是一幅图像的分辨率中长宽不一定都是8的倍数,此时需要对之边缘补成8的倍数,然后进行分块,依次处理。这里需要注意,分为8X8的块后,需要对每个像素点减去2p(p为采样精度),将像素数据从无符号整数变为有符号整数再带入DCT公式,也就是输入时把[0,2p]变为[-2p-1,2p-1-1]。

      以下是将一张原灰度图像转换为8X8的small block,每block都有64个pixels:


(4)离散余弦变换

       DCT的变换结果只有实数部分,没有复数部分。任何连续的实对称函数的傅里叶变换中只含有余弦项,DCT同FFT一样具有明确的物理意义。DCT是先将原MXN的图像进行分块,然后在逐一的进行DCT。

       分为正向DCT:FDCT

 

       反向DCT:IDCT


       
       

       这里:M=N=8,F(u,v)公式中的从左至右的16由2M,2N所得)

       在这里,详细说明DCT变换的数学意义,其实质,根据上述公式,二维DCT是一种正交的线性变换,因此为方便计算机计算,常常转换为矩阵的形式表示:

       FDCT:

       IDCT:

      其中,C为一个正交矩阵,满足


      变换后:8X8的original pixels A都变成了另外8X8的数字阵列B,变换后的每一个数都是由original 64 data通过basis function组合而得的。阵列B可以很好地将original image的能量(低频部分)集中在左上角,其余高频分布于右下角。当u,v为0时,左上角F(0,0)是所有像素的一个均值(it is the average of all original pixels),叫做直流分量DC或直流系数,随着u,v的增加,阵列B其余元素为交流分量AC,或者交流系数。

      在这里我们只考虑一个方向上的DCT信号变换,如下图所示: 


      其中原图信号波经过DCT变换后分解为了8个不同振幅的波形,其中第一幅为直流成分,其余7副为交流部分。从直流到交流,高频信息越显著。

      F(n)=C(n)*E(n),其中E(n)是一个基底,C(n)是DCT系数,F(n)则是图像信号;当考虑垂直方向的变化时,就需要一个二维的基底。傅里叶变换中提到任何信号都可以被分解为基波和不同幅度的谐波的组合,而DCT变换的物理意义正是如此。

      由于大多数图像的高频分量比较小,相应的图像高频分量的DCT系数经常接近于0,再加上高频分量中只包含了图像的细微的细节变化信息,而人眼对这种高频成分的失真不太敏感,因此考虑将这一些高频成分予以抛弃,从而降低需要传输的数据量。操作以后,传送DCT变换系数的所需要的编码长度要远远小于传送图像像素的编码长度。到达接收端之后通过反离散余弦变换就可以得到原来的数据,虽然这么做存在一定的失真,但人眼是可接受的,而且对这种微小的变换是不敏感的。

(5)Z字形扫描排序

      有了以上的知识,我们知道DCT变换后将8X8的数组变成了另外一种元素更小的8X8的数组。在计算机中数组的存放一般按照行方式存储,但是如果这样的话,每一行的结尾点和下一行的开始点(或者说元素点之间的相邻性)不密切,因此在JPEG中采用以下的顺序存储:



      这样保证了数列里的相邻点在图片上也是相邻的。不难发现,这种数据的扫描、保存、读取方式,是从8X8矩阵的左上角开始,按照英文字母Z的形状进行扫描的,一般将其称之为Zigzag扫描排序。如下图所示:


(6)量化

      所谓量化就是用像素值÷量化表对应值(量化步长)所得的结果。由于量化表左上角的值较小,右上角的值较大,这样就起到了保持低频分量,抑制高频分量的目的。JPEG使用的颜色是YUV格式。我们知道,Y分量相比UV分量对人眼而言更重要,因此我们对Y采用细量化,对UV采用粗量化,可进一步提高压缩比。所以上面所说的量化表通常有两张,一张是针对Y的;一张是针对UV的。

      通过量化可以reducing the number of bits and eliminating some of the components,达到通低频减高频的效果,如下图所示就是两张量化表的例子:


      比如左边那个量化表,最右下角的高频÷99,这样原先DCT后[-127,127]的范围就接近变成了[-1,1],固然减少了码字(从8位减至1位)。这样做,也是为了在一定程度上得到相对清晰的图像和更高的压缩率。另一个重要原因是所有的图片的点与点之间会有一个色彩过渡的过程,而大量的图象信息被包含在低频率空间中,经过DCT处理后,在高频率部分将出现大量连续的零。

      DCT变换是在最小均方误差准则下得出的次最佳正交变换,并且有快速算法,因此它在硬件中也很容易实现。

(7)DC系数的DCPM编码

      经过DCT、量化过后得到的8×8图像块中的DC直流系数有两个特点:直流系数的数值比较大相邻8×8图像块的DC系数值变化不大

      根据这个特点,JPEG算法使用了差分脉冲编码调制(DPCM)技术,对相邻图像块之间的DC系数的差值(Delta)进行编码,是一种预测编码,即

      其差值用两个变长码表示:(SIZE,VALUE)

      SIZE:Bit size of DC Delta value

      VALUE:DC Delta value

      eg:当前块的直流系数为15,与它相邻的上一块为12,那个Delta为3(11):此时存储为(2,3)

      前者SIZE采用Huffman编码,后者VALUE采用VLI编码

(8)AC系数的RLE编码

      经过量化和Z字型扫描后AC系数中包含有许多“0”系数,并且许多“0”是连续的。因此可以使用非常简单的游程长度编码(RLE)对它们进行编码,如下图所示:

      AC系数首先用RLE编码符号对(连续0的个数,下一个非零值)来表示。例如图AC系数为:(1,-2),(0,-1),(0,-1),(0,-1),(2,-1),(0,0) --EOB

 

      JPEG中的编码系数对,采用1个字节的高4位来表示连续“0”的个数;使用它的低4位来表示编码下一个非“0”系数所需要的位数;跟在它后的是非零的量化AC系数的数值(变长码)。

      记为: (RUN/SIZE,VALUE)

      RUN:Run-length of zeros(use 4 bit as it,NNNN)

      SIZE:Bit size of Non-zero value(use 4 bit as it,SSSS)

      VALUE:Non-zero value

      例如: AC系数(1,-2)表示为(1/2,-2)

      注意,如果AC系数之间连续0的个数超过16,则用一个扩展字节(15,0)来表示16连续的0。

      前者RUN/SIZE采用Huffman编码,后者VALUE采用VLI编码

(9)熵编码

      DPCM编码后的直流DC系数和RLE编码后的交流AC系数的RUN/SIZE在统计上还呈现出一定的规律,因此JPEG标准提供了两种熵编码方式:Huffman编码和算术编码。JPEG基本系统规定采用Huffman编码(因为不存在专利问题),但JPEG标准并没有限制JPEG算法必须用Huffman编码方式或者算术编码方式。因此使用霍夫曼编码来进一步压缩。对出现频度比较高的符号分配比较短的代码,而对出现频度较低的符号分配比较长的代码。

      Huffman编码时DC系数与AC系数分别采用不同的Huffman编码表,对于亮度和色度也采用不同的Huffman编码表。因此,需要4Huffman编码表才能完成熵编码的工作。具体的Huffman编码采用查表的方式来高效地完成。然而,在JPEG标准中没有定义缺省的Huffman表,用户可以根据实际应用自由选择,也可以使用JPEG标准推荐的Huffman表。或者预先定义一个通用的Huffman表,也可以针对一副特定的图像,在压缩编码前通过搜集其统计特征来计算Huffman表的值。

      霍夫曼码表分为DC表和AC表,事先进行定义:


(这里没有给出色度对应的DC和AC Huffman表格)

(10)JPEG压缩举例

      Eg:假如某图像被分成8X8块大小时中经过DCT、量化后的阵列为下图:

 

      此时,假定前一个块DC=12,则量化后系数为: 15-12, (1,-2), (0,-1), (0,-1), (0,-1), (2,-1), EOB

      前者SIZE采用Huffman编码,后者VALUE采用VLI编码(查表)DC: 3->(2,3)-T1->011,11

      前者RUN/SIZE采用Huffman编码,后者VALUE采用VLI编码(查表)

      AC:(1,-2)->(1/2-2)-T2-> 11011, (-2-1)mod2 -> 11011,01

            (0,-1)->(0/1-1)-T2->    00, (-1-1)mod2 -> 00,0

            (0,-1)->(0/1-1)-T2->    00, (-1-1)mod2 -> 00,0

            (0,-1)->(0/1-1)-T2->    00, (-1-1)mod2 -> 00,0

            (2,-1)->(2/1-1)-T2-> 11100, (-1-1)mod2 -> 11100,0

            EOB->1010

      压缩后的VLC(Variable Length Code)比特数:5+7+3+3+3+6+4 = 31 bits;

      压缩前:8*8*8=512 bits;

      压缩比为:512/31= 16.5:1,相当于一个像素只需要半个比特(这里一个像素使用8b量化)

4、基于DCT变换的JPEG图像压缩MATLAB实现 

      在MATLAB中,进行DCT变换主要有两种方法,dct()和dct2(),这里我们使用dct2进行模拟:

      <1>方法一:针对gray image图像

[plain] view plain copy
  1. img = imread('len_gray.jpg');%the is a gray image  
  2. I = im2double(img);%T1 = dctmtx(8);%处理后返回一个8 x 8的DCT变换矩阵  
  3. %block1 = blkproc(I1,[8 8],'P1*x*P2',T,T');%对图像I1的每个不同8 x 8块应用矩阵'P1*x*P2'进行处理,必要时补0  
  4. mask = [1 1 1 1 1 1 1 1  
  5.         1 1 1 1 1 1 1 1  
  6.         1 1 1 1 1 1 1 1  
  7.         1 1 1 1 1 1 1 1   
  8.         1 1 1 1 1 1 1 1  
  9.         1 1 1 1 1 1 1 1  
  10.         1 1 1 1 1 1 1 1  
  11.         1 1 1 1 1 1 1 1];%选取10个DCT系数重构图像  
  12. %block2 = blkproc(block1,[8 8],'P1*x',mask);  
  13. %I2 = blkproc(block2,[8 8],'P1*x*P2',T,T');  
  14. I1 = dct(I);  
  15. I2 = idct(I1);  
  16. subplot(2,2,1);imshow(img);title('原图像');  
  17. subplot(2,2,2);imshow(I2);title('经过IDCT变换后得到的重构图像');  
  18. subplot(2,2,3);imshow(abs(I-I2));title('原图像与重构图像之差,反应失真程度');  
  19. subplot(2,2,4);mesh(dct2(I1));title('dct2(dct(im2double(img)))光谱图');  
  20. colorbar('vert')%在水平轴旁增加一颜色等级条  

      仿真结果:


      仿真结果分析:

      可以看到,进过DCT变换后重构所得到的的图像与原图像在HVS上没有显著的区别,也可以从第三幅图中看到,原图和重构图像素之间差值几乎为0,为黑色。

 <2>方法二:针对彩色图像

[plain] view plain copy
  1. rgb = imread('lena_rgb.jpg');%read a RGB image it's format is 'jpg'   
  2. gray = rgb2gray(rgb);%trasform the RGB to gray  
  3. img = im2double(gray);%does turn the gray image I into format of 'double'  
  4. img1 = dct2(img);%does 2dim DCT for I0,and the DCT coefficients return into I1  
  5. img2 = idct2(img1);%get the reverse transform by doing 2dim  
  6.    
  7. subplot(3,2,1);imshow(rgb);title('original image rgb');  
  8. subplot(3,2,2);imshow(gray);title('to gray gray');  
  9. subplot(3,2,3);imshow(img);title('to 2double');  
  10. subplot(3,2,4);imshow(img1);title('the gray image dct');  
  11. subplot(3,2,5);imshow(img2);title('the gray image idct');  
  12. subplot(3,2,6);imshow(abs(img-img2));title('original 2double image - idct');  
  13. figure,mesh(img1);title('变换谱三维彩色图');  
  14. colorbar('vert');  

      仿真结果:


      仿真结果分析:

      基本结果同方法一,这里注意看,进过DCT变换后的系数矩阵,低频部分集中在左上角,高频部分集中在右下角。

5、JPEG2000简介

 <1>核心

      放弃了JPEG中以离散余弦变换DCT为基础的区块编码方式,采用离散小波变换为基础的多解析编码方式;

JPEG2000将彩色静态画面采用的JPEG编码方式2值图像采用的JBIG(Joint Binary Image Group)编码方式无损低压缩率采用的JPEG LS统一起来,成为应对各种图像的通用编码方式。

  <2>优势

      高压缩率 

      无损压缩 

      渐进传输 

      感兴趣区域压缩

  <3>应用

      目前,支持JPEG2000的软件已经出现,如ACD See JPEG2000 插件,相信在不久的将来,JPEG2000无论是在传统的JPEG市场(如数码相机、扫描仪等),还是在网路传输、无线通讯、医疗影像等应用领域都将大有发展。 

猜你喜欢

转载自blog.csdn.net/vipbinn/article/details/80615579
今日推荐