)
图像旋转是图像处理中的基本操作之一常用于数据增强、图像校正等场景。OpenCV结合NumPy提供了多种实现方式。本文将介绍三种常用的图像旋转方法NumPy的rot90函数、OpenCV的rotate函数以及通过仿射变换实现任意角度旋转的方法。一、引言旋转操作可以将图像以某点为中心进行转动。在OpenCV中旋转通常通过仿射变换实现但对于90°、180°、270°等特殊角度有更简便的专用函数。NumPy也提供了高效的90°旋转方法。本文将逐一介绍并对比这些方法。二、方法一使用NumPy的rot90函数2.1 函数介绍numpy.rot90用于将数组图像旋转90°的倍数。其语法为numpy.rot90(m, k1, axes(0,1))m输入数组图像。k旋转次数。k1表示逆时针旋转90°k2表示旋转180°k3表示逆时针旋转270°等价于顺时针90°k-1表示顺时针旋转90°。axes旋转轴对于图像通常保持默认。2.2 代码示例与解析import cv2 import numpy as np # 读取图像 img cv2.imread(kele.png) # 顺时针旋转90度k-1 rotated_image1 np.rot90(img, k-1) # 逆时针旋转90度k1 rotated_image2 np.rot90(img, k1) # 显示原图及旋转结果 cv2.imshow(Original, img) cv2.imshow(Clockwise 90(rot90 k-1), rotated_image1) cv2.imshow(Counterclockwise 90 (rot90 k1), rotated_image2) cv2.waitKey(0) cv2.destroyAllWindows()关键细节说明k为正表示逆时针旋转负表示顺时针旋转。此方法仅支持90°整数倍旋转不改变图像数据类型返回原数组的视图如果可能因此速度快且内存效率高。旋转后图像尺寸不变但行列互换。运行结果原图显示在Original窗口。Clockwise 90°窗口显示顺时针旋转90°后的图像。Counterclockwise 90°窗口显示逆时针旋转90°后的图像。三、方法二使用OpenCV的rotate函数3.1 函数介绍OpenCV提供了cv2.rotate函数专门用于90°、180°、270°旋转。其语法为dst cv2.rotate(src, rotateCode)src输入图像。rotateCode旋转标志有以下三种cv2.ROTATE_90_CLOCKWISE顺时针旋转90°cv2.ROTATE_90_COUNTERCLOCKWISE逆时针旋转90°cv2.ROTATE_180旋转180°3.2 代码示例与解析import cv2 img cv2.imread(kele.png) # 顺时针90度 rotated_clockwise cv2.rotate(img, cv2.ROTATE_90_CLOCKWISE) # 逆时针90度 rotated_counterclockwise cv2.rotate(img, cv2.ROTATE_90_COUNTERCLOCKWISE) # 旋转180度 rotated_180 cv2.rotate(img, cv2.ROTATE_180) cv2.imshow(Clockwise 90 (rotate), rotated_clockwise) cv2.imshow(Counterclockwise 90 (rotate), rotated_counterclockwise) cv2.imshow(180 (rotate), rotated_180) cv2.waitKey(0) cv2.destroyAllWindows()关键细节说明cv2.rotate返回旋转后的新图像不会修改原图。旋转后图像尺寸保持不变如90°旋转后宽高互换但函数内部已正确处理。此方法仅支持上述三种特定角度无法实现任意角度旋转。运行结果分别显示顺时针90°、逆时针90°、180°旋转后的图像。四、方法三使用仿射变换实现任意角度旋转对于非90°倍数的任意角度旋转需要使用仿射变换。OpenCV提供了cv2.getRotationMatrix2D和cv2.warpAffine。4.1 函数介绍获取旋转矩阵M cv2.getRotationMatrix2D(center, angle, scale)center旋转中心点(x, y)。angle旋转角度逆时针为正。scale缩放因子。执行仿射变换rotated cv2.warpAffine(src, M, dsize[, dst[, flags[, borderMode[, borderValue]]]])4.2 示例任意角度旋转并保持图像完整显示import cv2 import numpy as np img cv2.imread(kele.png) h, w img.shape[:2] # 计算旋转矩阵绕图像中心逆时针旋转45度 center (w // 2, h // 2) M cv2.getRotationMatrix2D(center, 45, 1.0) # 计算旋转后图像的新边界避免裁剪 cos abs(M[0, 0]) sin abs(M[0, 1]) new_w int((h * sin) (w * cos)) new_h int((h * cos) (w * sin)) # 调整旋转矩阵的平移部分使图像居中 M[0, 2] (new_w / 2) - center[0] M[1, 2] (new_h / 2) - center[1] rotated cv2.warpAffine(img, M, (new_w, new_h)) cv2.imshow(Rotated 45, rotated) cv2.waitKey(0) cv2.destroyAllWindows()关键细节说明默认旋转后图像可能被裁剪需计算新尺寸并调整平移量以完整显示。通过设置borderMode和borderValue可控制填充方式如边缘复制、常数填充等。此方法可实现任意角度旋转但计算量稍大。结果展示五、三种方法对比特性NumPyrot90OpenCVrotate仿射变换支持角度90°的任意整数倍通过k控制仅90°、180°、270°通过枚举任意角度旋转方向k正负控制逆/顺时针枚举明确指定方向角度参数控制逆时针为正返回值原数组的视图可能新图像数组新图像数组依赖需要NumPy仅需OpenCV仅需OpenCV适用场景已使用NumPy、需要灵活倍数时仅需标准90°旋转、代码更直观需要任意角度旋转如45°、30°等内存效率高可能为视图中等新建数组中等新建数组选择建议只需90°、180°旋转优先选择OpenCVrotate代码简洁直观。需要270°或多次旋转且已使用NumPynp.rot90更方便。需要任意角度如45°必须使用仿射变换。六、扩展旋转时保持图像内容不丢失的技巧使用仿射变换旋转图像时默认情况下旋转后的图像可能会被裁剪。为完整显示整个旋转图像需要计算旋转后图像的新边界。调整旋转矩阵的平移部分使旋转后的图像位于新画布中心。上述代码已演示了这一过程。此外可以通过borderMode参数控制边缘填充方式例如cv2.BORDER_CONSTANT用固定颜色填充可设置borderValue。cv2.BORDER_REPLICATE复制边缘像素。cv2.BORDER_REFLECT镜像反射。七、总结本文介绍了三种图像旋转方法NumPyrot90快速实现90°整数倍旋转适合与NumPy结合使用。OpenCVrotate专为标准90°旋转设计的函数代码简洁明了。仿射变换实现任意角度旋转灵活但需处理边界问题。掌握这些方法后可以根据实际需求选择合适的旋转方式高效完成图像预处理任务。