图像旋转与镜像操作详解(OpenCV + NumPy 实现)

在图像处理过程中,旋转与镜像操作是最常见的几何变换。它们不仅用于图像预处理(如数据增强、图像对齐),还常应用于计算机视觉任务(如目标检测、OCR 文字识别、人脸识别等)。本文将介绍 三种图像旋转方法 与 两种图像镜像方法,并进行对比分析。


一、图片旋转

方法一:使用 cv2.rotate 函数(最简便)

cv2.rotate 是 OpenCV 提供的专门用于旋转的函数,支持 90 度倍数的旋转操作,使用简单高效。

import cv2
# 读取图像
img = cv2.imread('image.jpg')

# 顺时针旋转 90 度
rotated_90_clockwise = cv2.rotate(img, cv2.ROTATE_90_CLOCKWISE)

# 逆时针旋转 90 度
rotated_90_counterclockwise = cv2.rotate(img, cv2.ROTATE_90_COUNTERCLOCKWISE)

# 旋转 180 度
rotated_180 = cv2.rotate(img, cv2.ROTATE_180)

# 显示结果
cv2.imshow('Original Image', img)
cv2.imshow('Rotated 90 Clockwise', rotated_90_clockwise)
cv2.imshow('Rotated 90 Counterclockwise', rotated_90_counterclockwise)
cv2.imshow('Rotated 180', rotated_180)
cv2.waitKey(0)
cv2.destroyAllWindows()

解析:

  • cv2.imread('image.jpg') → 读取图像,返回一个 NumPy 数组。

  • cv2.rotate(img, cv2.ROTATE_90_CLOCKWISE) → 内置旋转方法,直接实现 90°/180°/270° 的旋转。

  • cv2.imshow → 显示图像窗口,参数分别是窗口名和图像数组。

  • cv2.waitKey(0) → 等待键盘输入,否则窗口会立即关闭。

👉 特点:无需计算矩阵,直接调用即可,但仅限 90°、180°、270° 的旋转。


方法二:使用 cv2.warpAffine + 旋转矩阵(最灵活)

通过 cv2.getRotationMatrix2D 获取旋转矩阵,再结合 cv2.warpAffine 执行仿射变换,可以实现 任意角度 的旋转。

import cv2
import numpy as np

# 读取图像
img = cv2.imread('image.jpg')
height, width = img.shape[:2]

# 设置旋转中心为图像中心
center = (width // 2, height // 2)

# 设置旋转角度(例如 45 度)
angle = 45
scale = 1.0  # 缩放比例

# 获取旋转矩阵
M = cv2.getRotationMatrix2D(center, angle, scale)

# 仿射变换
rotated = cv2.warpAffine(img, M, (width, height))

cv2.imshow('Original Image', img)
cv2.imshow('Rotated Image', rotated)
cv2.waitKey(0)
cv2.destroyAllWindows()

解析:

  • img.shape[:2] → 获取图像高度和宽度(忽略颜色通道)。

  • center = (width // 2, height // 2) → 旋转中心点设为图像中心。

  • cv2.getRotationMatrix2D(center, angle, scale) → 返回一个 2×3 的旋转矩阵,用于描述旋转+缩放变换。

  • cv2.warpAffine(img, M, (width, height)) → 根据矩阵 M 对图像做仿射变换,得到旋转后的结果。

👉 特点:可以旋转 任意角度,但计算稍复杂。
💡 提示:若想避免旋转后图像被裁剪,可以在 warpAffine 时增大输出尺寸 (width, height)。


方法三:使用 NumPy rot90(适合矩阵操作)

如果图像以 NumPy 数组形式存储,可以直接用 np.rot90 实现 90° 倍数旋转。

import cv2
import numpy as np

# 读取图像
img = cv2.imread('image.jpg')

# 顺时针旋转 90 度(k=-1)
rotated_90_clockwise = np.rot90(img, k=-1)

# 逆时针旋转 90 度(k=1)
rotated_90_counterclockwise = np.rot90(img, k=1)

# 旋转 180 度(k=2)
rotated_180 = np.rot90(img, k=2)

cv2.imshow('Original Image', img)
cv2.imshow('Rotated 90 Clockwise', rotated_90_clockwise)
cv2.imshow('Rotated 90 Counterclockwise', rotated_90_counterclockwise)
cv2.imshow('Rotated 180', rotated_180)
cv2.waitKey(0)
cv2.destroyAllWindows()

解析:

  • np.rot90(img, k=1) → 每次旋转 90°,k 控制次数(正数逆时针,负数顺时针)。

  • 本质上是通过矩阵行列交换 + 反转来实现旋转。

👉 特点:简洁快速,尤其适合与 NumPy 结合处理大规模图像数据,但只能处理 90° 倍数旋转。


各方法对比

方法旋转角度灵活性操作简便性适用场景
cv2.rotate仅支持 90、180、270 度高,直接调用常规 90° 倍数旋转
cv2.warpAffine任意角度中,需要矩阵运算图像增强、任意旋转
np.rot90仅支持 90° 倍数高,适合批量矩阵处理科研计算、NumPy 工作流

二、图片镜像(翻转)

方法一:使用 cv2.flip(推荐)

OpenCV 的 cv2.flip 专门用于翻转图像,只需指定 flipCode 参数即可:

  • flipCode = 0:垂直镜像(上下翻转)

  • flipCode = 1:水平镜像(左右翻转)

  • flipCode = -1:同时水平 + 垂直镜像

import cv2

img = cv2.imread('image.jpg')

# 水平镜像
horizontal_flip = cv2.flip(img, 1)

# 垂直镜像
vertical_flip = cv2.flip(img, 0)

# 水平 + 垂直镜像
both_flip = cv2.flip(img, -1)

cv2.imshow('Original Image', img)
cv2.imshow('Horizontal Flip', horizontal_flip)
cv2.imshow('Vertical Flip', vertical_flip)
cv2.imshow('Both Flip', both_flip)
cv2.waitKey(0)
cv2.destroyAllWindows()

👉 特点:简单高效,推荐使用。


方法二:使用 NumPy 索引(原理性方法)

图像本质是 NumPy 数组,因此可以直接通过索引实现翻转。

import cv2
import numpy as np

img = cv2.imread('image.jpg')

# 水平翻转:列反转
horizontal_flip = img[:, ::-1, :]

# 垂直翻转:行反转
vertical_flip = img[::-1, :, :]

# 同时水平 + 垂直翻转
both_flip = img[::-1, ::-1, :]

cv2.imshow('Original Image', img)
cv2.imshow('Horizontal Flip', horizontal_flip)
cv2.imshow('Vertical Flip', vertical_flip)
cv2.imshow('Both Flip', both_flip)
cv2.waitKey(0)
cv2.destroyAllWindows()

解析:

  • img[:, ::-1, :] → 第二个维度(列)反转 → 水平翻转。

  • img[::-1, :, :] → 第一个维度(行)反转 → 垂直翻转。

  • img[::-1, ::-1, :] → 行列都反转 → 水平 + 垂直翻转。

👉 特点:更底层,适合理解图像存储结构或进行自定义操作。


各方法对比

方法操作简便性依赖库灵活性
cv2.flip高,直接调用函数仅需 OpenCV高,通过 flipCode 控制
NumPy 索引中等,需理解数组结构OpenCV + NumPy高,可自定义更复杂翻转

三、总结

  • 旋转:

    • 如果是 90° 倍数旋转 → cv2.rotate 或 np.rot90。

    • 如果是 任意角度旋转 → cv2.warpAffine。

  • 镜像:

    • 推荐用 cv2.flip,更简洁高效。

    • NumPy 索引更灵活,适合需要批量矩阵操作时使用。

这些操作还常用于 数据增强(Data Augmentation),例如在深度学习训练中,通过旋转和镜像生成不同角度和方向的图像,可以有效提高模型的泛化能力。

更多推荐