【OpenCV 对图片做旋转操作】仿射=旋转+平移+缩放+剪切
OpenCV 中的旋转相关函数详解
OpenCV 提供了多种函数用于图像的旋转操作,主要分为 任意角度旋转 和 固定角度旋转。以下是常用函数及详细使用说明:
一、任意角度旋转
1. cv2.getRotationMatrix2D()
生成旋转矩阵,用于定义旋转参数。
函数原型:
cv2.getRotationMatrix2D(center, angle, scale) -> M
- 参数说明:
center
:旋转中心坐标(x, y)
,通常为图像中心(width/2, height/2)
。angle
:旋转角度(顺时针方向,单位为度)。scale
:缩放因子(1.0 表示不缩放)。
- 返回值:2x3 的仿射变换矩阵
M
。
2. cv2.warpAffine()
应用旋转矩阵对图像进行仿射变换。
函数原型:
cv2.warpAffine(src, M, dsize[, dst, flags, borderMode, borderValue]) -> dst
- 关键参数:
M
:旋转矩阵(来自cv2.getRotationMatrix2D
)。dsize
:输出图像尺寸(width, height)
。若未指定,默认与原图尺寸相同(可能裁剪内容)。flags
:插值方法(如cv2.INTER_LINEAR
)。borderMode
:边界填充模式(如cv2.BORDER_CONSTANT
)。borderValue
:填充颜色(默认为黑色)。
完整代码示例:
import cv2
import numpy as np
# 读取图像
img = cv2.imread('image.jpg')
h, w = img.shape[:2]
# 计算旋转中心
center = (w // 2, h // 2)
# 生成旋转矩阵(顺时针旋转45度,无缩放)
M = cv2.getRotationMatrix2D(center, angle=45, scale=1.0)
# 计算旋转后的图像尺寸(避免裁剪)
cos = np.abs(M[0, 0])
sin = np.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), flags=cv2.INTER_LINEAR, borderValue=(255, 255, 255))
cv2.imshow('Rotated Image', rotated)
cv2.waitKey(0)
二、固定角度旋转
cv2.rotate()
快速实现 90°、180°、270° 的旋转(无需手动计算矩阵)。
函数原型:
cv2.rotate(src, rotateCode[, dst]) -> dst
- 参数说明:
rotateCode
:旋转模式:cv2.ROTATE_90_CLOCKWISE
:顺时针旋转90度。cv2.ROTATE_180
:旋转180度。cv2.ROTATE_90_COUNTERCLOCKWISE
:逆时针旋转90度(等效于顺时针270度)。
代码示例:
# 顺时针旋转90度
rotated_90 = cv2.rotate(img, cv2.ROTATE_90_CLOCKWISE)
三、关键问题与优化
1. 旋转后的黑边处理
旋转可能导致图像边缘出现黑色填充。可通过以下方式优化:
- 自定义填充颜色:设置
borderValue
参数(如白色填充)。rotated = cv2.warpAffine(img, M, (new_w, new_h), borderValue=(255, 255, 255))
- 图像扩展模式:使用
borderMode=cv2.BORDER_REPLICATE
复制边缘像素。
2. 旋转后的图像尺寸控制
- 自动计算新尺寸(避免裁剪):
new_w = int(w * |cosθ| + h * |sinθ|) new_h = int(w * |sinθ| + h * |cosθ|)
- 保持原图尺寸(可能裁剪内容):
rotated = cv2.warpAffine(img, M, (w, h))
3. 插值方法选择
cv2.INTER_NEAREST
:最近邻插值(速度快,锯齿明显)。cv2.INTER_LINEAR
:双线性插值(平衡速度与质量,默认)。cv2.INTER_CUBIC
:双三次插值(质量高,速度慢)。
四、复合变换(旋转+平移)
若需同时旋转和平移,可直接修改旋转矩阵的平移分量:
M = cv2.getRotationMatrix2D(center, angle=30, scale=1.0)
M[0, 2] += 50 # 沿x轴正方向平移50像素
M[1, 2] += -20 # 沿y轴负方向平移20像素
五、总结
方法 | 适用场景 | 优点 | 缺点 |
---|---|---|---|
cv2.getRotationMatrix2D | 任意角度旋转,可自定义中心和缩放 | 灵活,支持复杂变换 | 需手动处理尺寸和黑边 |
cv2.rotate | 90°、180°、270° 的快速旋转 | 简单高效,无需计算矩阵 | 仅支持固定角度 |
根据需求选择合适的函数,并通过调整参数优化旋转效果。