【问题标题】:cv2 image size is transposed from PIL Imagecv2 图像大小从 PIL Image 转置
【发布时间】:2021-06-27 08:33:49
【问题描述】:

我有一张尺寸为 72x96 的图片。 Windows 说它的大小是 72x96。 PIL Image 还说它是 72x96:

from PIL import Image, ImageOps

with Image.open(<path>) as img:
    print(img.size) # (72, 96)
    print(ImageOps.exif_transpose(img).size) # (72, 96)

但是当我用cv2.imreadskimage.io.imread 读取图像时,它说图像的形状是(96, 72, 3)

from skimage.io import imread
im0 = imread(<path>)
print(im0.shape) # (96, 72, 3)

这里有什么问题?即使我这样做:

import matplotlib.pyplot as plt
plt.imshow(im0)

它以正确的大小显示图像,但写入的大小看起来是转置的。

【问题讨论】:

标签: python image python-imaging-library cv2 scikit-image


【解决方案1】:

这是预期的行为。

PIL 将图像的大小返回为 (width, height) (PIL documentation),而 numpy 将数组的形状返回为第一维和第二维的长度(在二维数组的情况下),所以(高度,宽度)(Numpy documentation)。

【讨论】:

  • 是不是说np.zeros((72, 96, 3))的形状应该是(96, 72, 3)?因为不是
  • 不,正如我在回答中所说,您评论中数组的形状是 (72, 96, 3),因为它对应于第一个维度的长度,然后是第二个维度,然后是第三个维度数组。
  • 好的,比。我的问题是为什么图像的形状不是(72, 96, 3)cv2skimage 应该这样显示形状:(width, height, channels)
  • 这是一个约定问题:您的图像定义的数组(通过 imread 获得)是一个 numpy.ndarray,其形状(根据定义)返回为(高度、宽度、通道)。与 PIL.Image 对象相同的图像具有大小(不是形状),返回为 (width, height)。图像是一样的,只是呈现其形状(或大小)的方式发生了变化。
  • 答案,如上所述,是一个约定。必须为 n 维数组定义 numpy.ndarray 对象的 shape 方法(因此得名),因此 shape 作为数组每个维度的长度返回,从 0 开始。另一方面,PIL 是专注于图像,然后按照惯例将图像的大小返回为(宽度,高度)。在提取图像的形状/大小时,您只需要记住这一点,并根据您使用的对象(np.ndarray 或 PIL.Image)仔细分配宽度和高度。
猜你喜欢
  • 2020-09-16
  • 1970-01-01
  • 2012-12-01
  • 2021-12-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-04-01
  • 2021-08-12
相关资源
最近更新 更多