JPEG(发音:[ˈdʒeɪpɛg])是一种针对照片视频而广泛使用的有损压缩标准方法。
这个名称代表 Joint Photographic Experts Group(联合图像专家小组)。联合图像专家小组1992年发布了JPEG的标准而在1994年获得了ISO 10918-1的认定。JPEG与视频音频压缩标准的MPEG(Moving Picture Experts Group)很容易混淆,但两者是不同的组织及标准。
其实JPEG不是一种文件格式,它是由联合图像专家小组推出的一种图像压缩方法(类似于视频中的H.264等编解码标准)。而JPG或者JFIF格式仅仅是一种数据的包装容器(类似于视频中MP4、MOV等封装格式)。
1. 概述
JPEG编码的主要流程是:色彩空间转换 (Color Conversion)、下采样(Downsampling)、 分块 (Dividing Patch) 、离散余弦变换(Discrete cosine transform)、量化(Quantization)、熵编码技术(Entropy coding)。
2. 色彩空间转换(Color Conversion)
我们使用传感器采集到的原始(RAW)图像使用的是RGB色彩空间来表示的。也就是说,按照每一个像素的RGB(Red, Green, Blue)值填充到对应的像素位置。
首先,我们将RGB(红绿蓝)转换为一种称为YCrCb (YUV)的不同色彩空间。
•Y成分表示一个像素的亮度 (luminance) •U成分表示色度(饱和度)(Chrominance)•V成分表示色度(饱和度)
RGB空间到YUV空间转换公式为:
下图为分解开的Y、U、V的示例:
3. 采样(Downsampling)
下采样、也就是减少人类视觉系统不敏感的色度(U和V的成分)。虽然减少了颜色数量,但是人眼并不会察觉到图像质量有任何的差异。
JPEG上这种缩减取样的比例可以是4:4:4(无缩减取样),4:2:2(在水平方向2的倍数中取一个,颜色为之前的 1/2),以及最普遍的4:2:0(在水平和垂直方向 2 的倍数中取一个,颜色为之前的 1/4)。
如图:
4. 分块 (Dividing Patch)
源图像中每点的 3 个分量是交替出现的,先要把这 3 个分量分开,存放到 3 张表中去。然后由左及右,由上到下依次读取 8*8 的子块,存放在长度为 64 的表中,即可以进行DCT变换。如果原始图片的长宽不是 8 的倍数, 都需要先补成 8 的倍数, 使其可以进行一块块的处理。编码时,程序从源数据中读取一个 8*8的数据块后,进行 DCT 变换,量化,编码,然后再读取、处理下一个 8imes8 的数据块。图像的数据值必须减去128,是因为 DCT 公式所接受的数字范围是 -128 到 127 之间。
5、离散余弦变换(Discrete Cosine Transform)
离散余弦变换是一种类似于傅里叶变换的数学工具(不清楚傅里叶变换的同学可以移步:https://www.bilibili.com/video/av19141078来简单了解傅里叶变换).它将信号从时间域转换到频率域。
这一步,将视频中的每个成分(Y, U, V)生成三个区域,每一个区域再划分成如瓷砖般排列的一个个的 8*8 子区域,每一子区域使用二维的离散余弦变换(DCT)转换到频率空间。
如果有一个如这样的的 8*8 的8-比特(0~255)子区域:
如图:
用矩阵表示为:
原始数据每个值的范围是 [0-255] ,使每个数字减去 128 ,标准化。
且接着使用离散余弦变换,和舍位取最接近的整数,得到结果为
左上角相当大的数值称为DC系数(直流系数);其他 63 个值称为AC系数(交流系数)。
6.量化
利用人眼对低频数据敏感对高频数据不敏感的特性,我们可以将离散余弦变换后的很多更高频率的成分舍位成为接近 0 ,且剩下很多会变成小的正或负数。
JPEG标准中定义了量化表。
使用QYQY量化矩阵与前面所得到的DCT系数矩阵逐项相除,得到结果为:
7. 熵编码技术(Entropy Coding)
熵编码是一种无损压缩的技术,它使用Z字形(zigzag)将矩阵数据排列。然后将排列后的数据使用哈夫曼编码(哈夫曼编码的资料请自行查找))。
对于前者量化的系数所作的Z字体序列会是:
−3, 0,−3, −2, −6,2, −4, 1, −3,1, 1, 5, 1, 2,−1, 1, −1, 2, 0, 0,0, 0, 0, −1, −1, 0, 0,0, 0, 0, 0, 0, 0, 0, 0,0, 0, 0, 0, 0, 0, 0,0, 0, 0, 0, 0, 0,0, 0, 0, 0, 0,0, 0, 0, 0,0, 0, 0,0, 0,0
当剩下的所有系数都是零,对于过早结束的序列,JPEG有一个特别的霍夫曼编码用词。使用这个特殊的编码用词,EOB,该序列变为
−3, 0,−3, −2, −6,2, −4, 1 −3,1, 1, 5, 1, 2,−1, 1, −1, 2, 0, 0,0, 0, 0, −1, −1, EOB
在这一步数据量得到了极大的压缩。
8. 结果
JPEG是一种有损压缩算法。所以不同程度的压缩比例,会呈现出不同的文件大小,以及差异化的可视化呈现。以下,呈现了相关的压缩比例与原始图像的对比。从上到下,呈现了压缩比从小到大的结果。每一个图片中,左边是原始图像,右边是压缩后的图像。对应的文件大小显示在图线的上方。