numpy 本身不提供图像旋转/翻转的高层函数,仅支持数组变换;图像翻转推荐用 np.fliplr 或 np.flipud 提高可读性,避免误翻通道;任意角度旋转必须用 scipy.ndimage.rotate 并注意类型转换、插值阶数与边界处理;翻转与旋转顺序不同会导致结果差异,操作后需 clip 值域。

NumPy 本身不提供图像旋转/翻转的高层函数,它只负责数组变换;真正做几何变换必须配合 scipy.ndimage.rotate 或手动插值,而翻转可直接用 np.flip 系列——但要注意轴顺序和通道处理。
用 np.flip 做安全的图像翻转
RGB 图像本质是 (height, width, channels) 的 3D 数组,np.flip 按轴翻转时极易搞错方向:
-
np.flip(img, axis=0):上下翻转(绕水平中线) -
np.flip(img, axis=1):左右翻转(绕垂直中线) -
np.flip(img, axis=2):把 RGB 变成 BGR(通常不是你想要的)
常见错误是传入 axis=-1 而没意识到它在彩色图上会翻通道。更稳妥写法是显式指定 axis=1 做镜像,或用 np.fliplr(img)(等价于 axis=1)和 np.flipud(img)(等价于 axis=0)提高可读性。
旋转必须用 scipy.ndimage.rotate,别硬写
np.rot90 只支持 90° 整数倍旋转,且是“块旋转”(不插值、不缩放),不能用于任意角度。真实图像旋转需空间变换:
- 用
scipy.ndimage.rotate(img, angle, reshape=True, order=1) -
order=0:最近邻(快,适合标签图);order=1:双线性(默认,适合 RGB);order=3:双三次(更平滑,略慢) -
reshape=True(默认)会让输出尺寸自适应,避免裁切;设为False则保持原尺寸,边缘被截断 - 注意:输入必须是 float 类型(如
img.astype(np.float64)),否则整数数组可能触发下溢/上溢
示例:rotated = rotate(img.astype(np.float64), 30, order=1, reshape=True)
Python 3.14.2是Python编程语言在2025年12月5日发布的稳定版本,属于3.14系列的第二个维护更新。该版本包含了18项修复,重点解决了多进程、数据类及正则表达式等模块的回归问题,并修复了CVE-2025-12084等安全漏洞。此版本标志着自由线程模式(移除GIL)正式获得官方支持,是Python发展的重要里程碑。
手动旋转?除非你明确要控制插值核或边界模式
自己实现仿射变换(用 np.meshgrid + 坐标映射 + scipy.ndimage.map_coordinates)可行,但容易出错:
- 坐标系原点默认在左上角,旋转中心需手动平移
- 插值前必须把像素坐标归一化并偏移 0.5(因图像坐标系中 (0,0) 对应像素左上角,而非中心)
-
map_coordinates默认边界模式是constant(填 0),会导致黑边;改用mode='reflect'或'nearest'更自然 - 性能比
rotate低,且无内置抗锯齿
除非你在做教学演示、定制重采样逻辑,或嵌入到无法引入 scipy 的环境,否则没必要绕开 scipy.ndimage.rotate。
翻转+旋转组合时,顺序影响结果
先翻转再旋转 ≠ 先旋转再翻转。例如:np.flip(rotate(img, 30), axis=1) 是旋转后镜像,而 rotate(np.flip(img, axis=1), 30) 是镜像后再旋转——二者视觉效果不同,取决于你要模拟的物理操作。
另外,所有操作后记得将结果 clip 回合法范围(如 np.clip(rotated, 0, 255).astype(np.uint8)),尤其旋转浮点运算后可能出现负值或超 255 值。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!










