Python三种图像处理库,PIL、skimage、OpenCV中三次插值对比

Python三种图像处理库,PIL、skimage、OpenCV中三次插值对比

        PIL、skimage、OpenCV三种图片处理库在图片的缩放上都有resize方法。在resize方法中我们又可以调用不同的插值方法。

对比前的准备

      首先导入必要的python库,将测试文件放入测试目录。我的测试图片comic.png放在与工程同目录的test文件夹里。`

import cv2 as cv
import PIL.Image as pil_image
import numpy as np
import skimage
from skimage import io,transform
from pylab import *

在这里插入图片描述
采用PSNR来评价三种库插值方法
PSNR计算公式,单位dB。PSNR越高,缩放效果越好(图片保真度更好)。

def psnr(img1, img2):
    """
    compute the psnr
    :param img1: img1
    :param img2: img2
    :return:
    """
    diff = img1 - img2
    diff = diff.flatten('C')
    rmse = math.sqrt(np.mean(diff ** 2.))
    psnr = 20 * math.log10(1.0 / rmse)
    return psnr

OpenCV插值(cubic)

img = cv.imread("test/comic.png")
img = cv.cvtColor(img,cv.COLOR_BGR2RGB)
img = cv.resize(img,(249,360))
cvimg1 = cv.resize(img, None, fx=1/3, fy=1/3, interpolation=cv.INTER_CUBIC)
cvimg2 = cv.resize(cvimg1, None, fx=3, fy=3, interpolation=cv.INTER_CUBIC)
cvPicture = figure()
ax1 = cvPicture.add_subplot(131)
title('img')
ax2 = cvPicture.add_subplot(132)
title('cvimg1')
ax3 = cvPicture.add_subplot(133)
title('cvimg2')
ax1.imshow(img)
ax2.imshow(cvimg1)
ax3.imshow(cvimg2)
cvpsnr = psnr(img/255, cvimg2/255)
print("psnr: %.5fdB"%cvpsnr)

在这里插入图片描述

          首先将图片缩小为原图的 1 3 \frac{1}{3} 31,即cvimg1。然后再将cvimg1放大到3倍,即cvimg2。新放大的cvimg2与原图做对比。从PSNR可以看出用openCV进行插值,效果还是很不错的。后面的两种对比方式同理。

PIL插值(bicubic)

img = pil_image.open("test/comic.png").convert('RGB')
img = img.resize((249,360),resample=pil_image.BICUBIC)
pilimg1 = img.resize((img.width // 3, img.height // 3), resample=pil_image.BICUBIC)
pilimg2 = pilimg1.resize((pilimg1.width * 3, pilimg1.height * 3), resample=pil_image.BICUBIC)
# 不转numpy的话这里img是PIL.Image.Image类型,没法计算psnr
img = np.array(img)
pilimg2 = np.array(pilimg2)
pilPicture = figure()
ax1 = pilPicture.add_subplot(131)
title('img')
ax2 = pilPicture.add_subplot(132)
title('pilimg1')
ax3 = pilPicture.add_subplot(133)
title('pilimg2')
ax1.imshow(img)
ax2.imshow(pilimg1)
ax3.imshow(pilimg2)
pilpsnr = psnr(img/255, pilimg2/255)
print("psnr: %.5fdB"%pilpsnr)

在这里插入图片描述

Skimage插值(bicubic)

img= io.imread("test/comic.png")
'''
resize函数接口
resize(image, output_shape, order=1, mode='constant', cval=0, clip=True, preserve_range=False)
order : int, optional
        The order of interpolation. The order has to be in the range 0-5:
         - 0: Nearest-neighbor
         - 1: Bi-linear (default)
         - 2: Bi-quadratic
         - 3: Bi-cubic
         - 4: Bi-quartic
         - 5: Bi-quintic
'''
img = transform.resize(img,(360, 249),order=3)
skiimg1 = transform.resize(img,(img.shape[0]//3, img.shape[1]//3),order=3)
skiimg2 = transform.resize(skiimg1,(skiimg1.shape[0]*3, skiimg1.shape[1]*3),order=3)
skiPicture = figure()
ax1 = skiPicture.add_subplot(131)
title('img')
ax2 = skiPicture.add_subplot(132)
title('skiimg1')
ax3 = skiPicture.add_subplot(133)
title('skiimg2')
ax1.imshow(img)
ax2.imshow(skiimg1)
ax3.imshow(skiimg2)

skipsnr = psnr(img, skiimg2)
print("psnr: %.5fdB"%skipsnr)

在这里插入图片描述

总结

        通过对以上3种库放大进行对比,可以说明同样用三次插值的方法对图像进行缩放三种库的缩放后的效果是不一样的,且相较而言用OpenCV缩放的效果是最好的。
        还有是观察到三种库对图片插值方法的描述:cv.INTER_CUBIC;pil_image.BICUBIC;Bi-cubic。查了下OpenCV对Cubic的解释是三次样条插值,在它的描述里并没有用Bi-这个前缀,但OpenCV的方法也是在4邻域内做三次插值,所以这三种方法在计算上应该是一样的。其差异的原因看网上老哥解释很可能是在于他们读图片的方式不同导致。
        还有要补充的是OpenCV与Skimage读取图片后,图片的格式是numpy类型数据,PIL则是它自己封装的数据格式PIL.Image.Image。Skimage在使用transform方法后,图片会自动转为0~1之间的浮点数据类型,故不需要再除255。


参考
OpenCV、Skimage、PIL图像处理的细节差异
图像处理库PIL与OpenCV
图像插值四种模式(PIL.Image 实现)

  • 12
    点赞
  • 34
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值