一、量化
为进一步减少图像数据存储量,并方便后续编码,需要对DCT变换后的系数量化。量化是将DCT系数除以量化表中对应的量化步长并取整,取整操作会导致精度丢失,这也是JPEG图像有损的主要原因。量化和反量化的具体步骤如式(1),式(2)所示。
(1)
(2)
其中,round() 为取整函数, F(U,V)是量化前的DCT系数,Q(U,V) 是量化步长,D(u,v)为量化后的DCT系数,I(u,v) 为反量化后的DCT系数。由于量化过程的取整操作, I(u,v)≠F(u,v),量化是有损的。
基于人眼对亮度和色度分量的视觉敏感特性区别,在量化中可以保留更多的亮度信息,压缩更多的色度信息。为此,JPEG提供了两张标准量化表,分别为亮度量化表与色度量化表,对亮度分量细量化,对色度分量粗量化,如图1所示。经大量实验验证和分析,人眼对不同频率位置信息的敏感程度存在差异性,为保留更高的视觉质量并取得更大的压缩比,JPEG标准给不同频率位置设计不同的量化步长。可以看到,左上方的量化步长更小,右下方的量化步长更大,频率越高,零系数越多,从而使得量化后大部分AC系数的值变为0。
图1.量化表
由上述分析可知,量化步长直接影响JPEG的压缩性能,为满足不同的压缩率需求,JPEG定义了质量因子 (QF: Quality Factor) 来衡量压缩后的图像视觉质量。
QF取值范围为(0,100】,QF越大,图像视觉质量越高,压缩率越低。在给定QF后,根据式(3)计算得到对应的亮度量化表 Qf(u,v),其中Q(u,v) 是标准亮度量化表,SF与设定的QF有关,由式(4)计算。
(3)
(4)
二、熵编码
(1) Zigzag扫描
量化后的8*8 大小的 DCT 系数矩阵使用Z字形扫描顺序 (Zigzag Scanning Order) 转换成一维数组。Z字形扫描方式可以根据频率位置对量化 AC 系数排序,即将矩阵左上方的低频系数排列于高频系数之前,连续的高频系数将使更多的零AC系数相邻,方便后续熵编码。如图2所示。Z字形扫描后,对一维量化DCT系数序列进行熵编码,将系数值变为二值比特流的形式,存储在计算机系统中。
(2) DC系数编码
JPEG对DC系数和AC系数使用不同的编码方式。DC系数包含了图像块的平均能量,取值一般比较大,直接进行编码可能会使图像达到更好的压缩性能。JPEG相邻的图像块具有相关性,使得相邻的DC系数值差异较小,因此,采用差分脉冲编码调制 (DPCM: Differential Pulse Code Modulation) 对DC系数编码。
设一张JPEG图像共有nb 个8×8大小的图像块,每个块包含一个DC系数,表示为 D1,D2,.....Dn。将当前块的DC系数减去前一个块的DC系数得到当前DC系数的差分值,如下式所示。DC系数差值表示为di ,DPCM即是对 di 编码。
(5)
首先,di 被转换为 (Size, Value) 的中间格式,其中Size表示di 的编码长度,Value表示di 的值。通过头文件的DC系数霍夫曼编码表,将中间格式 (Size, Value)编码成为DC系数霍夫曼编码 (DCH: DC Huffman Code)。使用变长整数 (VLI: Variable Length Integer) 编码表将Value编码为DC系数扩展位编码 (DCA: DC Appended Bits)。DCH和DCA组成了DC系数编码 (DCC: Direct Coefficient Code)。
VLI编码表
(3)AC系数编码
图像块中的量化AC系数包含许多连续的零值,使用行程长度编码(Run Length Encoding,RLE)可以利用起这一特性,实现有效压缩。首先,将块内每个非零AC系数及前面所有连续的零AC系数转化成中间格式 (Run/Size, Value),其中Run是非零AC系数前的连续零AC个数,Size是非零AC系数的编码长度,Value是该非零AC系数的值。通过头文件中的AC系数霍夫曼编码表,将Run/Size编码为AC系数霍夫曼编码 (ACH: AC Huffman),Value使用VLI编码表编码成为AC系数扩展位编码(ACA: AC Appended Bits)。AC系数编码 (ACC:Altering Coefficient Code) 由ACH和ACA组成。
熵解码是熵编码的逆过程,根据JPEG头文件中的编码表,解析熵编码比特流,得到对应的中间格式和量化DCT系数。