如何使用 Pillow (PIL) 定义和选择 JPEG Q 表

问题描述 投票:0回答:1

我目前正在研究图像压缩。我在 PIL(documentation)中发现,通过使用 im.save 函数并自定义 qtables 我可以减小图像大小。问题是如何在Python中生成这些表并选择最好的表以提供更好的压缩比?

还说必须有2到4张桌子。我猜第一个是 第二个是“亮度量化表”,第二个是“色度量化表”。其他的是什么?

如果您提供有关此事的任何信息,我将不胜感激。

python python-imaging-library jpeg image-compression quantization
1个回答
0
投票

量化是一种压缩过程,用于减少图像中的高频数据量。这里的想法是,人类视觉不太擅长区分非常亮(或暗)的颜色。

这是通过将 DCT 系数(矩阵,表示频域)除以量化矩阵并将结果值舍入为整数来完成的。

量化 DCT 系数 = Round( DCT 系数 / 量化矩阵 )

通常,当您接近量化表的右下角时,您会发现值增加。这是因为当接近 DCT 系数的右下角时,频率会增加,而我们要牺牲高频值来增加压缩。生成的量化 DCT 系数将包含许多零,特别是在右下角(高频数据所在的位置)。量化的 DCT 系数被设置为通过利用重复零的熵编码进行压缩。

Image.save('pathto.jpeg', qtables= <integer between 0-100> )
# Where 0 is worst and 95 is best. 100 will disable some of the compression.
# These values represent tables based on Section K.1 of the JPEG specification
# Other options: web_low, web_medium, web_high, web_very_high, 
# web_maximum, low, medium, high, maximum

# To retrieve an image's Q-tables use (returns a Dictionary with each table as a list):
with Image.open('pathto.jpeg') as im:
    qtable_dict = im.quantization
# qtable_dict = {[<64 integers>],[<64 integers>]}
# A dictionary in this format can be provided to the qtables arg
# to save an image with specific Q-tables

一般来说,创建 Q 表时高值会增加压缩并降低图像质量。量化 DCT 系数中的零越多,熵编码就越能压缩它们。

一张 JPEG 中至少有一个 Q 表。第一个用于亮度分量,第二个用于一个或两个颜色分量,第三个(通常是第二个的重复)用于另一个颜色分量。

量化步骤的舍入部分是有损的,这意味着信息将永久丢失。然而,只要 Q 表中存在 1,系数就会除以 1,因此不会丢失任何信息。


JPEG 压缩中还有一个对图像大小影响很大的步骤,称为下采样(又名色度子采样)。这通常发生在量化之前的几个步骤。 JPEG 压缩中的下采样基于亮度比颜色对人类视觉影响更大的想法。这是通过编码比亮度信息少的颜色信息来完成的,该量由比率

#:#:#
定义。

Image.save('pathto.jpeg', subsampling= <integer between 0-2> )
# 0: 4:4:4
# 1: 4:2:2
# 2: 4:2:0

其中,Y':Cb:Cr(亮度:蓝色分量:红色分量)。

霍夫曼编码是一种熵编码(无损压缩),它本质上采用量化生成的重复零并创建更小的包来表示它们。这通常是 JPEG 压缩的最后步骤之一。

# You can use stream type to save with or without Huffman tables
# But there doesn't appear to be an arg for switching to a different encoding
Image.save('pathto.jpeg', streamtype= <integer between 0-2> )

此外,还有一些JPEG 压缩格式。每个都会影响图像大小和编码/解码速度。

# The following saves a progressive jpeg
# the only difference between baseline and progressive is the number of tables
Image.save('pathto.jpeg', progressive=True)
© www.soinside.com 2019 - 2024. All rights reserved.