测试图像: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 在读取图像文件的结果基本(也不是完全)是一致的;
- 但是在按照各自默认的差值方式进行插值后,结果却有一定差异;
- 即使指定相同的插值方式(本例中为最近邻插值)之后,结果也有较大的差异。
注意事项:
- 注意 opencv 中的默认数据类型是 np.uint8 ,用以表示 0-255 之间的像素值,在计算两个 np 数组的像素值的差异时,要转换为 np.int16 并取绝对值,因为 np.uint8 中没有负数,如果像素值作差得到负数,则会被转换为 uint8 的正数,如 -1 -> 255。
- PIL 和 OpenCV 读取图像文件的结果在本例中是一样的(误差为0.0),但是笔者亲测这是与图像有关的,换一张图大概率就不能做到误差为 0 了,但是误差基本也都在 1 以内。
- PyTorch 中的 torchvision.transforms.Resize 就是采用的 PIL 的 resize 。
Ref:
Pillow vs cv2 resize



