使用zlib

时间:2017-03-15 23:32:48

标签: python image zlib pillow image-compression

我有兴趣了解可以压缩多少具有不同功能的图像而不会丢失。所以我生成了3种不同类型的双层图像(全黑,黑白棋盘和随机黑白)并使用zlib压缩图像。我使用PIL(枕头)压缩到PNG也做了同样的事情并得到了相同的结果,但为了简单起见,我们坚持使用zlib(我相信PIL也使用zlib)。

我做了以下事情。我生成一个0和1的numpy二维数组(类型为uint8)并将其转换为字节(是的,我通过这样做丢失了有关数组形状的信息)。然后我将字符串传递给压缩它的zlib,并将原始图像的大小与压缩图像的大小进行比较。我这是作为原始像素数(字节)的函数。可以找到最小的工作示例here。高达1024x1024字节的压缩字节数与原始字节数的关系如下(" raw"只是我们开始的像素总数," comp。"代表压缩和"常数"指的是全0,"棋盘"重复101010和"随机"每个像素是随机采样的)

comparison of compressed images

和压缩字节与原始字节的比率(彩色线除以黑线)

enter image description here

我觉得结果很奇怪,可能是因为我不太清楚zlib在做什么。为什么压缩率会发生变化?它起初非常高效,然后达到恒定速率(比率恒定)。

对于"常数" (全0)示例为什么当我通过添加更多0来实质上添加少量信息时,压缩字符串的大小会以这样的速率增长? (可以对棋盘进行类似的考虑,因为它是周期性的)

我预计压缩图像的大小与其Kolmogorov复杂度有些相关,但似乎并非如此。

2 个答案:

答案 0 :(得分:1)

zlib technical notes所述,deflate格式固有的最大压缩比为1032:1。当你得到10 -3 的图上的比率时,你正在使格式的能力饱和。

答案 1 :(得分:0)

回答你的问题:“为什么压缩字符串的大小会以这样的速度增长?”。最长的字符串zlib(deflate)可以编码为一个(长度,距离)LZ对是258字节:在您的情况下,复制从1或2个字节前开始,258字节,以编码0或checkboard 1和0的运行。

您拥有全0或1和0的棋盘格局。它们都可以由相同的(长度,距离)对编码。因此,对于每258个字节的输入,输出的大小将增加一些量,这解释了第一个图形中不断增加的蓝色和绿色曲线。

为什么压缩后的尺寸不是原件的1/258?长度和距离符号的霍夫曼编码可能是造成这种情况的原因。在您的情况下,当压缩导致长度为= 258且距离= 0的符号时,则每个将由1位代码进行霍夫曼编码,从而导致总长度为2位的(长度,距离)对编码。这意味着每次运行258个字节将在压缩输出中仅占用2位。渐渐地,这是Mark在上面总结的压缩率1032。

相关问题