为何Pillow生成的灰度/黑白图像对应numpy.ndarray为3D形状?
问题:PIL转换灰度/黑白图像后仍保留RGB通道形状?
输入代码
import numpy as np from PIL import Image with Image.open("testimage.png") as img: img.convert('L') # 转换为灰度图 #img.convert('1') # 转换为黑白图 image_pil = np.asarray(img) print(f'{image_pil.shape=}')
输出结果
image_pil.shape=(266, 485, 3)
技术疑问
为什么image_pil的形状不是(266, 485)或(266, 485, 1)?预期得到二维灰度图像,但结果显示形状为(266, 485, 3),说明仍是RGB图像;使用.convert('1')转换为黑白图像也得到相同结果,为什么它们的形状不是(266, 485)?
解答
核心原因是PIL的convert()方法不会修改原图像对象,而是返回一个新的转换后的图像实例。你当前的代码只是调用了convert('L')但没有把返回值重新赋值给img,后续np.asarray(img)处理的还是最初打开的RGB原图,所以形状依然是3通道的。
修正后的代码需要将转换结果赋值回img:
import numpy as np from PIL import Image with Image.open("testimage.png") as img: img = img.convert('L') # 将转换后的图像赋值给img,替换原对象 # img = img.convert('1') # 转换黑白图像时同理 image_pil = np.asarray(img) print(f'{image_pil.shape=}')
调整后,灰度图像('L'模式)的形状会是(266, 485),黑白图像('1'模式)的形状同样为二维的(266, 485)——因为这两种模式本身就是单通道格式。
如果需要得到形状为(H, W, 1)的数组,可以在转换后通过np.expand_dims()手动添加维度:
image_pil = np.expand_dims(np.asarray(img), axis=-1)
内容的提问来源于stack exchange,提问作者Sun Bear
相关产品推荐
相关产品推荐

