图像处理:压缩方法对图片大小的影响(cv2 vs PIL)

问题发现: 同一图片,用不同的库读取并保存后,图片大小受压缩方式影响很大~

一、初步试验

试验方法:

- python库opencv与PIL
- 输出格式:png与jpg

代码如下,仅仅是直接读入然后保存而已

import cv2
from PIL import Image

name = 1 # 2

img = Image.open('{}.jpg'.format(name))
img.save('{}_pil.jpg'.format(name))
img.save('{}_pil.png'.format(name))

image = cv2.imread('{}.jpg'.format(name))
cv2.imwrite('{}_cv2.jpg'.format(name), image)
cv2.imwrite('{}_cv2.png'.format(name), image)

试验结果:
在这里插入图片描述
在这里插入图片描述


二、进一步试验:jpg压缩质量

上述现象原因分析:两个库默认使用的压缩质量不同参考1参考2

  • jpg的压缩程度和参数quality相关,一般取1~100(越大图片质量越好,建议最高到95)
  • PIL默认quality=75
  • cv2默认quality=95
“”“设置quality参数!”“”

name = 'data\img_1\img'

img = Image.open('{}.jpg'.format(name))
img.save('{}_pil.jpg'.format(name))
img.save('{}_pil_75.jpg'.format(name), quality=75)
img.save('{}_pil_95.jpg'.format(name), quality=95)
img.save('{}_pil_01.jpg'.format(name), quality=1)
img.save('{}_pil.png'.format(name))

image = cv2.imread('{}.jpg'.format(name))
cv2.imwrite('{}_cv2.jpg'.format(name), image)
cv2.imwrite('{}_cv2_95.jpg'.format(name), image, [int(cv2.IMWRITE_JPEG_QUALITY), 95])
cv2.imwrite('{}_cv2_75.jpg'.format(name), image, [int(cv2.IMWRITE_JPEG_QUALITY), 75])
cv2.imwrite('{}_cv2_01.jpg'.format(name), image, [int(cv2.IMWRITE_JPEG_QUALITY), 1])
cv2.imwrite('{}_cv2.png'.format(name), image)

以下结果印证了上面所说,不论什么库,只要quality改成一个值,保存后图片质量就相同!
在这里插入图片描述


三、还有个试验:png压缩质量

上面破案了jpg压缩问题,那为何PIL和cv2保存的png文件质量也不同呢?
在这里插入图片描述
其实,png压缩时也有一个压缩程度参数,0~9,越大压缩程度越高(不过我们发现PIL和cv2在同一压缩参数下的压缩程度还是不同,可能用了不同的算法吧,这里吗水好深…)

name = 'data\img_1\img'

img = Image.open('{}.jpg'.format(name))
img.save('{}_pil.png'.format(name))
img.save('{}_pil_opt.png'.format(name), optimize=True)
img.save('{}_pil_0.png'.format(name), compress_level=0)
img.save('{}_pil_3.png'.format(name), compress_level=3)
img.save('{}_pil_9.png'.format(name), compress_level=9)

image = cv2.imread('{}.jpg'.format(name))
cv2.imwrite('{}_cv2.png'.format(name), image)
cv2.imwrite('{}_cv2_0.png'.format(name), image, [int(cv2.IMWRITE_PNG_COMPRESSION), 0])
cv2.imwrite('{}_cv2_3.png'.format(name), image, [int(cv2.IMWRITE_PNG_COMPRESSION), 3])
cv2.imwrite('{}_cv2_9.png'.format(name), image, [int(cv2.IMWRITE_PNG_COMPRESSION), 9])

在这里插入图片描述



ps:另一个试验

我将jpg文件强制转换为png格式,然后采取同样的操作

name = 'data\img_2\img'

img = Image.open('{}.png'.format(name))
img.save('{}_pil.jpg'.format(name))
img.save('{}_pil_75.jpg'.format(name), quality=75)
img.save('{}_pil_95.jpg'.format(name), quality=95)
img.save('{}_pil_01.jpg'.format(name), quality=1)
img.save('{}_pil.png'.format(name))

image = cv2.imread('{}.png'.format(name))
cv2.imwrite('{}_cv2.jpg'.format(name), image)
cv2.imwrite('{}_cv2_95.jpg'.format(name), image, [int(cv2.IMWRITE_JPEG_QUALITY), 95])
cv2.imwrite('{}_cv2_75.jpg'.format(name), image, [int(cv2.IMWRITE_JPEG_QUALITY), 75])
cv2.imwrite('{}_cv2_01.jpg'.format(name), image, [int(cv2.IMWRITE_JPEG_QUALITY), 1])
cv2.imwrite('{}_cv2.png'.format(name), image)

发现,这次输出的图片大小,与读入.jpg图片时完全一样
在这里插入图片描述
猜测的原因: 不同压缩方法的文件格式不同,比如png格式中有IHDR数据块等,cv2和PIL应该是识别出了该文件压缩方式不是png而是jpg,所以仍然按照jpg进行解码、处理,所以得到和之前一样的结果~
不过,要注意输入图片的后缀要改为.png,若仍保留为jpg,可能会报错;PIL直接报错改文件不存在,cv2报错

libpng warning: Image width is zero in IHDR
libpng warning: Image height is zero in IHDR
libpng error: Invalid IHDR data

发布了52 篇原创文章 · 获赞 4 · 访问量 2131

猜你喜欢

转载自blog.csdn.net/qq_42191914/article/details/104511455
今日推荐