以JPEG算法为例,了解图像压缩与编码原理。

本篇仅仅是对以下视频的补充,关于JPEG算法原理这个视频已经讲解得很清楚了,建议以视频学习为主:

【中英双字】JPEG算法原理 jpeg图片是如何压缩的?_哔哩哔哩_bilibili

图像压缩的心理学原理

人眼对图像中的高频部分相对不敏感,可以通过保留图像的低频部分,丢弃高频部分,实现对图像进行压缩。(和音频HE AAC中的SBR技术原理类似)

所谓图像的高频部分,指的是画面变化复杂的部分,而低频部分,指的是画面比较连续的部分,比如颜色相近的大面积色块,以下面的图片为例:

人眼可以很好得识别完整的树干,石头的轮廓,但对于稀疏阴影的变化,落叶堆中的小草,叶片丛中的某几片叶子,人眼则不能很好地识别。树干、石头这些对应的就是低频信号,阴影、落叶堆、叶片丛对应的就是高频信号。将这些高频信号丢掉一部分,让其变模糊一点,对人眼识别画面并不会造成很大的影响,这就是JPEG算法压缩的生物学原理。

关于图像的高频、低频的更详细说明可参考以下链接:

  • 低频分量(低频信号):代表着图像中亮度或者灰度值变化缓慢的区域,也就是图像中大片平坦的区域,描述了图像的主要部分,是对整幅图像强度的综合度量。
  • 高频分量(高频信号):对应着图像变化剧烈的部分,也就是图像的边缘(轮廓)或者噪声以及细节部分。 主要是对图像边缘和轮廓的度量,而人眼对高频分量比较敏感。之所以说噪声也对应着高频分量,是因为图像噪声在大部分情况下都是高频的。

JPEG压缩算法处理流程

色彩空间转换

将RGB转换为YUV,形成亮度(Y)、蓝色色度(Cb)、红色色度(Cr)三个通道的分量。

色度缩减采样

Chrominance Downsampling,将YUV444转换成YUV420,降低U通道和V通道的数据量。

离散余弦变换

对色度缩减采样后的YUV每个通道执行离散余弦变化(DCT/Discrete Cosine Transform),将其从空域转换成频域。

理解离散余弦变换的最好办法是从傅立叶变换开始,傅立叶变换可以将一个周期性的波形分解成一堆的不同频率正弦波的叠加,像下面这样:

也就是说,通过傅立叶变换,我们可以用一系列的正弦波去叠加出一个波形,并且,我们还可以丢弃一些高频波形,这些高频成份对波形的还原影响不大,波形的还原主要还是依赖中低频成份。之前的音频压缩中的变换压缩即是用了上面的原理。

而离散余弦变换,则可以看成是二维平面上的傅立叶变换,其思路就是用一系列的基图像来叠加出任意图像。具体来说,JPEG中的离散余弦变换定义了64个基图像,每个基图像都是8x8个像素大小,把这64个基图像按照下面的8x8形式进行排列(注意下面的8x8排列中每个位置都是一个8x8像素的基图像):

在这个8x8的排列中,左上角的图像是纯白色,信号频率最低,右下角的图像最密集,信号频率最高,从左上到右下,图像信号的频率依次递增

JPEG在执行离散余弦变换时,会先将整个原始图像按8x8个像素切分成许多区块,然后针对每个区块执行离散余弦变换,将该区块转换成用上面的64个基图像叠加时每个基图像所需使用的数量,这样可以得到64个数字,然后将这64个数字存储到原8x8像素的位置上。由此,原来由64个像素组成的区块被转化为64个系数,每个都代表对应的基图像被使用的次数

量化

经过上一步的离散余弦变换后,8x8的像素被转换成8x8的系数矩阵,接下来就是用量化的方式压缩其中的高频信号,使用的办法是定义一张8x8的量化表,这张表从左上到右下,数字依次增大,然后用8x8的系数矩阵除以量化表,得到量化后的系数:

可以看到,在使用这种量化方式时,低频信号由于量化系数小,整除之后舍弃的部分也比较小,结果相对准确,而高频信号由于量化系数大,整除舍弃的部分也比较大。而且,信号频率越高的位置,量化后系数越容易为0。在反量化时,需要用量化后的系数表再乘回量化表,低频信号由于量化系数小,反量化后的结果会更接近原始值,而高频信号由于使用了较大的量化系数,导致反量化后的结果会与原始值相差较大。通过这种方式,就实现了保留图像低频成份,丢弃高频成份的功能。

如果要达到更大压缩比,那么可以使用更大的系数表,这样高频信号量化之后就会出现更多的0,这有利于之后通过游程编码和霍夫曼编码压缩数据,但相应地,图像解码之后就会丢失更多的信息。

JPEG对图像的Y分量和UV分量使用了不同的量化表,UV分量的量化表系数要小一些,这样可以更多地保留色度信息。

游程编码与霍夫曼编码

经过上一步的量化后,8x8的像素块被转换成了8x8的系数矩阵,并且这个系数矩阵右下角通常会包含很多的0,这时可以使用游程编码(Run Length Encoding),以zigzag的方式遍历系数矩阵,以便于尽可能多地将0安排在结尾部分,最大限度发挥游程编码的优势。(小知识:这个zigzag的遍历方式就是FFmpeg logo的由来。)

对所有的8x8块进行游程编码后,再对编码结果进行哈夫曼编码,以进一步压缩数据长度。

JPEG算法局限性

JPEG对自然图像有较好的压缩性能,但对于数码图像,比如矢量图形,压缩质量不好,因为矢量图形中存在大量的直线,这些直线没法用64个基图像重建,所以压缩后图像边缘会存在模糊的问题。

其他可供参考链接:




















  • 无标签