3.4 压缩(Compression)

2022-10-02
3分钟阅读时长

3.4.1 游程编码(Run-Length Encoding)

游程编码(Run-Length Encoding)适用于经常出现重复值的文件中,比如下图中有 7 个连续黄色像素,可以插入额外的字节表示有连续 7 个黄色像素,接着删除重复数据。

游程编码

但需要为了能让计算机分辨出“长度”和“字节”,所以需要为所有不同颜色的像素标上长度,有时反而会使得数据量变多。

3.4.2 DFTBA

DFTBA 有点像“Don’t forget to be awesome”(别忘了变厉害)的缩写,使用字典(dictionary)来存储代码和数据之间的对应关系,使得数据的表示更为紧凑,同样是无损压缩。

首先将数据分块计算组合出现的频率,使用「霍夫曼树」(Huffman Tree)进行编码——由大卫·霍夫曼(David Huffman)发明于 1950s,具体步骤如下:

列出所有分块组合以及其出现频率,每轮选中最低的两个频率组成一个树的节点,重复组成最终的霍夫曼树。其特点在于出现频率最低的排列在树的最底端,数字也越大。

DFTBA

根据霍夫曼树对分块组合进行编码,因树的每条路径唯一,所以编码也不会有冲突。接着根据组合的对应将像素数据替换成相应的 code,如将两个黄色的像素替换为 00。同时将保存对应关系的字典也存储在编码数据前即可。

字典编码

3.4.3 有损压缩

解压前后数据完全一致的压缩方法,称为「无损压缩」(lossless compression)。常常组合使用“消除冗余”和“使用更紧凑的表示方式”两者压缩方法来实现,如 GIF, PNG, PDF, ZIP 。

在一些人类看不出区别的时候,使用有损压缩(lossy compression)会更有效率。比如人类无法听到超声波数据,其对人声较为敏感,而对低音只能感觉得到震动。音频有损压缩会利用人类这种感知特性,使用不同的精度来编码不同的频段,比如在网络通话时会根据网速来视情况降低声音质量。

这种通过删除人类无法感知到的数据的编码方式,称为「感知编码」(perceptual coding),属于心理物理学(Psychophysics)领域,依赖于人类的感知模型。

与声音类似,人类的视觉系统也更善于看到尖锐对比(比如物体边缘),而对颜色的细微变化无法感知。因此 JPEG 会利用这种特性,将图片分解为 8×8 的像素块后,删除大量人眼无法分辨的高频率空间数据。

视频作为一长串图片的组合,帧和帧之间有很多像素是一致的,这种情况称为「时间冗余」(temporal redundancy)。

在存储视频时,有些视频编码格式会利用这种相似性,只存储帧与帧之间变化了的部分。更高级些的编码格式——比如视频压缩的常见标准 MPEG-4 ,会找出帧和帧之间变化部分中相似的补丁(patches),然后用简单效果(如移动、旋转等)来实现这种变化。比如用一些补丁代表 up 主手的移动,然后在帧之间直接移动补丁。

但随之而来的问题是,当压缩过于严重时,没有足够空间来更新补丁内的像素,但播放器也依然会照常播放,画面就会错乱。