JPEG简介
JPEG : Joint Photographic Experts Group,联合图像专家组。该小组属于ISO国际标准化组织,主要负责静态数字图像的编码方法,即所谓的JPEG算法
JPEG专家组实际上开发了两种基本的压缩算法,两种熵编码方法和四种编码模式:
压缩算法包括:有损的离散余弦变换DCT,无损的预测压缩技术;
熵编码方法包括:Huffman编码,算术编码;
编码模式包括:
基于DCT的顺序模式:编码,解码通过从左到右,从上到下一次扫描完成;
基于DCT的渐进式模式:编码,解码需要多次扫描完成,扫描效果从模糊逐渐清晰
基于DPCM的无损模式:解码后能完全恢复到原图像的采样值
层次模式:图像在多个空间分辨率中进行编码,可以根据实际需要选择不同分辨率进行解码
基于DCT的顺序编码模式和基于DCT的渐进式编码模式在日常的图片加载中还是挺常见的,图片一行一行的加载出来的就是顺序编码模式,图片从模糊到清晰的加载方式就是渐进式编码模式。一次偶然的机会,在微信图片消息中注意到了这点,在微信中发送一张jpg的图片消息,打开图片所在文件夹
可以看到自动生成了一张缩略图,使用exiftool工具查看缩略图的exif信息:
原图的exif信息:
通常我们所说的JPEG是指由联合照片专家组开发并命名为“ISO 10918-1”的一项数字图像压缩标准,一种有损压缩的数字图像技术,核心算法为离散余弦变换(DCT),压缩数据再根据JFIF文件格式标准进行存储,文件后缀为.jpg或.jpeg
JPEG图像压缩的主要步骤
JPEG图像的压缩主要步骤如上图所示,在一些模块中间还会有一些细分步骤,比如Zig-Zag扫描到熵编码之间还会有:DC系数的差分脉冲调制编码,DC系数的中间格式计算,AC系数的游程长度编码,AC系数的中间格式计算等
颜色空间转换:将RGB数据转换为YCbCr数据。在手机拍照输出.jpg照片的过程中,Camera ISP有个CSC模块就是做这个事的;
分块:JPEG标准中处理图片时会把图片按8x8像素进行分块,主要是为了后续的DCT操作,因为DCT中的n值一般都是8。后续的DCT,量化,熵编码都是针对单个方块的操作
离散余弦变换DCT:将图像从色彩域转换到频率域,关于色彩域和频率域可以参考之前的文章图像与滤波 ,常用的变换方法也很多:傅立叶变换,正弦变换,余弦变换,斜变换,哈尔变换等等。数字图像处理中离散余弦变换是使用最为广泛的。DCT变换公示为:
f(i,j) 经 DCT 变换之后,F(0,0) 是直流系数,其他为交流系数
举个例子说明一下(例子数据来源于参考资料2):
8x8的原始图像:
因为DCT的数据范围为-128~127,所以减去128:
DCT处理:
可以看到频率域中,图像的低频部分会集中在矩阵的左上角,高频部分集中在矩阵的右下角。
量化:利用人眼对高频部分不敏感的特性来丢弃数据到达压缩目的,该过程不是无损可逆的,所以在解码还原后的图像质量会比原图低。
选择50% quality的JPEG量化表将频率数据量化,量化表为:
量化公式:
B(i, j) = round(G(i, j) / Q(i, j))
如:Q(0, 0) = round(-415.38 / 16) = -26
量化结果为:
DCT变换就是空间域的低通滤波器,选择不同的量化表就能控制JPEG的压缩比
Zig-Zag扫描:观察量化后的数据,可以发现右下角含有大量的0,按照“z”字形进行编排的时候,连续的0就会顺序存储,此时就可以充分利用行程编码(适合该算法的数据具有一大特点:大量相同数据连续存储,比如原始数据为1111 1112 3333,使用行程编码后数据就变为来1721 34)来进行压缩数据
熵编码:一种无损压缩编码,JPEG中主要采用Huffman编码
Huffman编码主要思想为概率高的数值用短码表示,概率小的数值用长码表示,这样编码后的总长度会小于编码前的长度
JPEG图像的解码就是压缩编码的逆过程
参考资料
1.https://blog.csdn.net/qq_34812257/article/details/88047623
2.https://www.ibm.com/developerworks/cn/linux/l-cn-jpeg/index.html
3.https://www.jianshu.com/p/f2c644769d5d
4.https://www.jianshu.com/p/ed295fe3669d