试验方法:
- 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)
上述现象原因分析:两个库默认使用的压缩质量不同(参考1,参考2)
“”“设置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改成一个值,保存后图片质量就相同!
上面破案了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])
我将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