使用Python三大图像库读取同一图像为何输出尺寸不同?
Why do imageio, PIL.Image, and cv2 return different dimensions when reading the same image?
Great question! This is a super common gotcha when working with image libraries in Python—let's break down exactly why each library gives you different results, using your example:
1. Axis Order: Width vs. Height First
The biggest immediate difference is how each library reports the image's dimensions:
- PIL.Image: Follows traditional image coordinate conventions, where the first value is the width (horizontal axis, x) and the second is the height (vertical axis, y). That's why your
b.sizereturns(334, 500)—334 is the width, 500 is the height. Note that PIL returns anImageobject, not a numpy array, so itssizeproperty uses this (W, H) order. - imageio and cv2: Both return numpy arrays, which use matrix-style indexing: the first dimension is rows (corresponding to image height) and the second is columns (corresponding to image width). So their shape reports
(500, 334, ...)—500 is height, 334 is width.
If you convert the PIL Image object to a numpy array, you'll see it matches the shape from imageio/cv2 (minus channel differences):
import numpy as np from PIL import Image b = Image.open('test_img.png') print(np.array(b).shape) # Output: (500, 334, 4) (for your RGBA image)
2. Channel Count & Handling
The second difference comes down to how each library handles transparency (Alpha channels) in PNGs:
- imageio.imread: By default, it reads all channels present in the image. Your
test_img.pnghas an Alpha channel (transparency), so it returns a 4-channel RGBA array ((500, 334, 4)), with dtypeuint8(standard for 0-255 pixel values). - cv2.imread: By default, it ignores Alpha channels and only reads the first 3 color channels—but note that OpenCV uses BGR order instead of RGB! That's why you get
(500, 334, 3). If you want to include the Alpha channel, you need to use the flagcv2.IMREAD_UNCHANGED:import cv2 c = cv2.imread('test_img.png', cv2.IMREAD_UNCHANGED) print(c.shape) # Output: (500, 334, 4) - PIL.Image.open: The
Imageobject's mode will reflect the channel count (e.g.,'RGBA'for 4 channels). When converted to a numpy array, it will have the same channel count as imageio, just starting with (W, H) in thesizeproperty.
Quick Recap
imageio.imread: Returns numpy array in (Height, Width, Channels) order, reads all channels including AlphaPIL.Image.open: Returns Image object with (Width, Height) size, preserves original channel modecv2.imread: Returns numpy array in (Height, Width, Channels) order, ignores Alpha by default and uses BGR channel order
内容的提问来源于stack exchange,提问作者PURNENDU MISHRA
相关产品推荐
相关产品推荐

