您的位置:首页 > 其它

数字图像处理第一次作业——JPEG格式与压缩流程分析

weixin_43534668 2018-11-13 11:57 423 查看

数字图像处理第一次作业——JPEG格式与压缩流程分析

欢迎阅读

此篇博客是由曹老师数字图像处理课程布置的第一次作业(2018年9月16日)
作业内容:
分析JPEG格式、原理、压缩流程、下载实现代码并调通运行、计算压缩率。
此篇博客以分析原理为主,在每个算法之后会贴出对应的C语言代码。
本文代码使用的编译器是Visual Stdio,第一次作业要求深入了解压缩与解压缩过程,用C/C++实现,不允许使用OpenCv或者matlab直接调用库函数实现,以后将使用OpenCv为主

1.JPEG格式综述

JPEG是联合图象专家组(Joint Picture Expert Group)的英文缩写,是国际标准化组织(ISO)和CCITT联合制定的静态图象的压缩编码标准。JPEG比其它几种压缩比要高得多,而图象质量都差不多,JPEG处理的颜色只有真彩和灰度图。
JPEG有两种基本的压缩算法、两种熵编码方法、四种编码模式。
压缩算法:
(1)有损的离散余弦变换DCT(Discrete Cosine Transform)
(2)无损的预测压缩技术;
熵编码方法:
(1)Huffman编码;
(2)算术编码;
编码模式:
(1)基于DCT的顺序模式:编码、解码通过一次扫描完成;
(2)基于DCT的渐进模式:编码、解码需要多次扫描完成,扫描效果由粗到精,逐级递增;
(3)无损模式:基于DPCM,保证解码后完全精确恢复到原图像采样值;
(4)层次模式:图像在多个空间分辨率中进行编码,可以根据需要只对低分辨率数据做解码,放弃高分辨率信息;
在实际应用中,JPEG图像编码算法使用的大多是离散余弦变换、Huffman编码、顺序编码模式。这样的方式,被人们称为JPEG的基本系统。基本系统的JPEG压缩编码算法一共分为11个步骤:颜色模式转换、采样、分块、离散余弦变换(DCT)、Zigzag 扫描排序、量化、DC系数的差分脉冲调制编码、DC系数的中间格式计算、AC系数的游程长度编码、AC系数的中间格式计算、熵编码。

2.颜色模式转换

YCrCb即YUV,主要用于优化彩色视频信号的传输。其中“Y”表示明亮度(Luminance或Luma),也就是灰阶值;而“U”和“V” 表示的则是色度(Chrominance或Chroma),作用是描述影像色彩及饱和度,用于指定像素的颜色。“亮度”是透过RGB输入信号来建立的,方法是将RGB信号的特定部分叠加到一起。“色度”则定义了颜色的两个方面─色调与饱和度,分别用Cr和Cb来表示。其中,Cr反映了RGB输入信号红色部分与RGB信号亮度值之间的差异。而Cb反映的是RGB输入信号蓝色部分与RGB信号亮度值之间的差异。
RGB->YCrCb的转换可以用如下公式:
Y=0.299R+0.587G+0.114B Y=0.299R+0.587G+0.114B Y=0.299R+0.587G+0.114B
Cb=−0.1687R−0.3313G+0.5B+128 Cb = -0.1687R-0.3313G+0.5B+128 Cb=−0.1687R−0.3313G+0.5B+128
Cr=0.5R−0.418G−0.0813B+128 Cr = 0.5R-0.418G-0.0813B+128 Cr=0.5R−0.418G−0.0813B+128

2. 采样

JPEG图片中,通常采用两种采样方式:YUV411和YUV422,它们所代表的意义是Y,Cb,Cr三个分量的数据取样比例一般是4:1:1或者4:2:2(4:1:1含义就是:在2x2的单元中,本应分别有4个Y,4个U,4个V值,用12个字节进行存储。经过4:1:1采样处理后,每个单元中的值分别有4个Y、1个U、1个V,只要用6个字节就可以存储了)

3.分块

DCT变换是是对8x8的子块进行处理的,因此,在进行DCT变换之前必须把源图象数据进行分块由左及右,由上到下依次读取8x8的子块,存放在长度为64的表中,还必须将每个数值减去128,是因为DCT公式所接受的数字范围是-128到127之间,之后即可以进行DCT变换。

4. 离散余弦变换(DCT)

DCT(Discrete Cosine Transform,离散余弦变换),是码率压缩中常用的一种变换编码方法。任何连续的实对称函数的傅里叶变换中只含有余弦项,因此,余弦变换同傅里叶变换一样具有明确的物理意义。DCT是先将整体图像分成NN的像素块,然后针对NN的像素块逐一进行DCT操作。需要提醒的是,JPEG的编码过程需要进行正向离散余弦变换,而解码过程则需要反向离散余弦变换

原始的图像信号(最左边的波形)经过DCT变换之后变成了8个波,其中第一个波为直流成分,其余7个为交流成分。

5. Zigzag扫描排序

JPEG 规定按如下图中的数字顺序依次保存和读取64 个DCT的系数值,可以使0尽量连在一起,进一步压缩,减少存储空间。

6.量化

图像数据转换为DCT频率系数之后,还要进行量化阶段,才能进入编码过程。量化阶段需要两个8*8量化矩阵数据,一个是专门处理亮度的频率系数,另一个则是针对色度的频率系数,将频率系数除以量化矩阵的值之后取整,即完成了量化过程。当频率系数经过量化之后,将频率系数由浮点数转变为整数,这才便于执行最后的编码。不难发现,经过量化阶段之后,所有的数据只保留了整数近似值,也就再度损失了一些数据内容。在JPEG算法中,由于对亮度和色度的精度要求不同,分别对亮度和色度采用不同的量化表。前者细量化,后者粗量化。
下图给出JPEG的亮度量化表和色度量化表,该量化表是从广泛的实验中得出的。当然,也可以自定义量化表。

7.DC系数的差分脉冲调制编码(DC-DPCM)

88的图像块经过DCT变换之后得到的DC系数有两个特点:
(1)系数的数值比较大;
(2)相邻的88图像块的DC系数值变化不大;
根据这两个特点,DC系数一般采用差分脉冲调制编码DPCM(Difference Pulse Code Modulation),即:取同一个图像分量中每个DC值与前一个DC值的差值来进行编码。对差值进行编码所需要的位数会比对原值进行编码所需要的位数少了很多。假设某一个88图像块的DC系数值为15,而上一个88图像块的DC系数为12,则两者之间的差值为3。如第一个块的DC系数为14,第二个块的DC系数为16,则记录第一块的DC系数为14,第二个块则只记录差值2,需要2bit,如果不采用DPCM则需要5bit。

8.DC系数的中间格式计算

JPEG中为了更进一步节约空间,并不直接保存数据的具体数值,而是将数据按照位数分为16组,保存在表里面。这也就是所谓的变长整数编码VLI

9. AC系数的行程长度编码(RLC)

可以采用行程编码RLC(Run Length Coding)来更进一步降低数据的传输量。利用该编码方式,可以将一个字符串中重复出现的连续字符用两个字节来代替,其中,第一个字节代表重复的次数,第二个字节代表被重复的字符串。
57,45,0,0,0,0,23,0,-30,-8,0,0,1,000…
经过RLC之后,将呈现出以下的形式:
(0,57) ; (0,45) ; (4,23) ; (1,-30) ; (0,-8) ; (2,1) ; (0,0)

10.AC系数的中间格式

根据前面提到的VLI表格,对于前面的字符串: (0,57) ; (0,45) ; (4,23) ; (1,-30) ; (0,-8) ; (2,1) ; (0,0)只处理每对数右边的那个数据,对其进行VLI编码: 查找上面的VLI编码表格,可以发现,57在第6组当中,因此,可以将其写成(0,6),57的形式,该形式,称之为AC系数的中间格式。同样的(0,45)的中间格式为:(0,6),45; (1,-30)的中间格式为:(1,5),-30;

11.熵编码

Huffman编码:对出现概率大的字符分配字符长度较短的二进制编码,对出现概率小的字符分配字符长度较长的二进制编码,从而使得字符的平均编码长度最短。Huffman编码时DC系数与AC系数分别采用不同的Huffman编码表,对于亮度和色度也采用不同的Huffman编码表。因此,需要4张Huffman编码表才能完成熵编码的工作。

12.压缩和解压缩的代码

压缩和解压缩的完整代码实在是太长了,文件也太多了,就不放了(捂脸)

标签: