使用np.array()转换PIL图像时需先统一模式(如convert('RGB')),避免P/LA等模式导致异常;90°整数倍旋转优先用np.rot90(),任意角度用img.rotate();水平/垂直翻转或90°旋转可用img.transpose()提升性能。

用 np.array() 转换 PIL 图像时要注意数据类型和通道顺序
直接调用 np.array(img) 是最快的方式,但 PIL 的 RGB 图像转成 NumPy 后是 (height, width, 3),且 dtype 默认为 uint8 —— 这没问题;但若原图是 LA(灰度+alpha)或 P(调色板模式),会出意外:P 模式图像不转颜色表就直接转,得到的是索引数组而非 RGB 值。
- 安全做法:先统一转为
RGB或L,再转数组:np.array(img.convert('RGB')) - 若需保留 alpha 通道,用
img.convert('RGBA'),避免后续旋转后 alpha 错位 - 不要依赖
img.mode自动推断——'1'(1-bit)、'I'(32-bit int)等模式转np.array()后 dtype 会不同,影响后续计算
旋转用 np.rot90() 还是 img.rotate()?看需求场景
np.rot90() 只支持 90° 整数倍旋转,快、无插值、纯数组操作;而 img.rotate() 支持任意角度、带重采样(默认 Image.BICUBIC),但需 PIL 再转回数组,多一次内存拷贝。
- 只要 90/180/270°:优先
np.rot90(arr, k=1)(k=1→90°逆时针),比 PIL 快 3–5 倍 - 要任意角度(如 30°)或指定填充色:必须用
img.rotate(angle, expand=True, fillcolor=(0,0,0)),再转数组 - 注意
np.rot90()旋转的是最后两个轴,对 (H,W,3) 数组有效;若数组是 (3,H,W),得先transpose或用k和axes参数显式指定
一步到位:用 img.transpose() 替代旋转 + 转数组的组合操作
如果只是水平翻转、垂直翻转或 90° 旋转,PIL 的 transpose() 方法比先转数组再用 NumPy 处理更快,且零拷贝(返回新 Image 对象,底层像素缓冲可复用)。
-
img.transpose(Image.FLIP_LEFT_RIGHT)→ 水平翻转 -
img.transpose(Image.ROTATE_90)→ 90° 逆时针(等价于np.rot90(arr, k=1)) - 之后再调
np.array(),比先转数组再np.fliplr()或np.rot90()少一次内存分配 - 但
transpose()不支持角度参数,别试图传数字进去
性能陷阱:别在循环里反复调 np.array() 和 img.rotate()
这两个操作都不是零开销:前者触发像素拷贝,后者涉及重采样计算。如果批量处理上百张图,把转换和旋转拆开做,容易成为瓶颈。
立即学习“Python免费学习笔记(深入)”;
- 批量 90° 旋转:用
[np.rot90(np.array(x.convert('RGB')), k=1) for x in pil_list],比[np.array(x.rotate(90)) for x in pil_list]快 40%+ - 避免
img.rotate().convert('RGB').convert('L')这种链式调用——中间产生多个临时 Image 对象 - 如果最终要送入 PyTorch/TensorFlow,考虑跳过 NumPy 中间层,用
torchvision.transforms或tf.image.rot90直接处理 PIL 或 tensor
img.mode 可能分别是 'RGB'、'RGBA'、'L',不预处理就进 np.array(),后续 reshape 或模型输入会报错。


















