PIL、OpenCV中resize算子实现不同的问题

PIL、OpenCV中resize算子实现不同的问题

测试图像:https://raw.githubusercontent.com/TropComplique/ssd-pytorch/master/images/dogs-and-cats.jpg (直接 wget 可获得)

测试版本

  • opencv-python 4.4.0.46
  • Pillow 8.0.1

测试代码

import cv2
from PIL import Image
import numpy as np

# read images
path = './dogs-and-cats.jpg'
b = Image.open(path)
a = cv2.imread(path)[:, :, ::-1]

# they are equal
c = np.asarray(b)
print(np.abs(np.int16(b) - np.int16(a)).mean())

# resize images
a_0 = cv2.resize(a, (300, 300))
b_0 = b.resize((300, 300))

a_1 = cv2.resize(a, (300, 300), interpolation=cv2.INTER_NEAREST)
b_1 = b.resize((300, 300), Image.NEAREST)

# results of resizing are different, but visually they are equal
print(np.abs(np.int16(b_0) - np.int16(a_0)).mean())
print(np.abs(np.int16(b_1) - np.int16(a_1)).mean())

测试结果

0.0
1.785388888888889
7.455274074074074

结论

  • PIL 和 OpenCV 在读取图像文件的结果基本(也不是完全)是一致的;
  • 但是在按照各自默认的差值方式进行插值后,结果却有一定差异;
  • 即使指定相同的插值方式(本例中为最近邻插值)之后,结果也有较大的差异。

注意事项

  1. 注意 opencv 中的默认数据类型是 np.uint8 ,用以表示 0-255 之间的像素值,在计算两个 np 数组的像素值的差异时,要转换为 np.int16 并取绝对值,因为 np.uint8 中没有负数,如果像素值作差得到负数,则会被转换为 uint8 的正数,如 -1 -> 255。
  2. PIL 和 OpenCV 读取图像文件的结果在本例中是一样的(误差为0.0),但是笔者亲测这是与图像有关的,换一张图大概率就不能做到误差为 0 了,但是误差基本也都在 1 以内。
  3. PyTorch 中的 torchvision.transforms.Resize 就是采用的 PIL 的 resize 。

Ref:

Pillow vs cv2 resize

你可能感兴趣的:(计算机视觉,opencv,计算机视觉,python)