为什么在使用 PIL 和 cv2 加载时图像的宽度和高度会颠倒?

Why are width and height of an image are inverted when loading using PIL versus cv2?

我正在使用 PILcv2 包加载 image。使用 PIL 加载图像时与使用 cv2 加载图像时的高度和宽度相反。以下是打印使用这两个包加载的图像的高度和宽度的代码。

file = 'conceptual_captions/VL-BERT/data/conceptual-captions/val_image/00002725.jpg'
# load image using PIL
import PIL.Image
pil = PIL.Image.open(file).convert('RGB')
w, h = pil.size
print("width: {}, height: {}".format(w, h))

打印输出 width: 1360, height: 765

# now using cv2
import cv2
im = cv2.imread(file)
print("height, width, channels: {}".format(im.shape)) 

打印输出height, width, channels: (1360, 765, 3)

我下载了图像并使用 Mac 上的信息选项检查了图像的大小。 Info有width = 765height = 1360,和cv2方法报的一样。为什么 PIL 给出了错误的图像尺寸?

问题出现在很少的图片上。我链接的图片就是这样一张图片。对于其余图像,PILcv2 报告的高度和宽度相同。

图像有一些 EXIF 元数据,包括有关方向(旋转)的信息。我建议阅读 this 问答和后续参考资料。

不过,现在提出的解决方案可以简化,只需使用 PIL.ImageOps.exif_transpose():

If an image has an EXIF Orientation tag, return a new image that is transposed accordingly. Otherwise, return a copy of the image.

一些要测试的代码:

from PIL import Image, ImageOps

# Read original image, show width and height
file = '...'
pil = Image.open(file).convert('RGB')
w, h = pil.size
print("width: {}, height: {}".format(w, h))

# Transpose with respect to EXIF data
pil = ImageOps.exif_transpose(pil)
w, h = pil.size
print("width: {}, height: {}".format(w, h))

对应输出:

width: 1360, height: 765
width: 765, height: 1360
----------------------------------------
System information
----------------------------------------
Platform:     Windows-10-10.0.16299-SP0
Python:       3.8.5
Pillow:       7.2.0
----------------------------------------