如何通过单应/透视变换实现平面内给定坐标矩形的任意角度旋转
平面矩形旋转的单应性变换实现方法
你要实现的同平面内矩形自然旋转完全可以通过单应性(透视变换)实现,具体操作步骤如下:
前置准备
首先整理你给出的矩形四个角点(按顺序排列的(x,y)坐标):
- 点1:
(47.1317829457364, 320) - 点2:
(144.62015503876, 837.953488372093) - 点3:
(547.720930232558, 741.209302325581) - 点4:
(361.674418604651, 331.162790697674)
步骤1:计算矩形自身中心点
以矩形中心为旋转基点,才能保证旋转时矩形不会偏移原位置:
cx = (47.1317829457364 + 144.62015503876 + 547.720930232558 + 361.674418604651) / 4 ≈ 275.287 cy = (320 + 837.953488372093 + 741.209302325581 + 331.162790697674) / 4 ≈ 557.581
步骤2:生成旋转后的目标点坐标
设你需要旋转的角度为θ(使用弧度制,角度转弧度公式:弧度 = 角度 * π / 180),每个源点(x,y)旋转后的坐标(x', y')计算规则为:
x' = (x - cx) * cosθ - (y - cy) * sinθ + cx y' = (x - cx) * sinθ + (y - cy) * cosθ + cy
按上述公式对四个源点逐一计算,得到一一对应的四个旋转后目标点。
步骤3:计算单应性变换矩阵
以Python+OpenCV实现为例,直接调用内置方法即可得到3*3的单应性矩阵H:
import cv2 import numpy as np # 源点数组,顺序和你给出的角点顺序一致 src_points = np.array([ [47.1317829457364, 320], [144.62015503876, 837.953488372093], [547.720930232558, 741.209302325581], [361.674418604651, 331.162790697674] ], dtype=np.float32) # 替换成你计算得到的四个旋转后目标点,顺序必须和源点严格对应 dst_points = np.array([ # t1坐标, # t2坐标, # t3坐标, # t4坐标 ], dtype=np.float32) # 计算单应性矩阵 H, _ = cv2.findHomography(src_points, dst_points)
步骤4:应用变换得到结果图像
调用透视变换方法处理原图即可:
# original_img为你读入的原始图像 # 第三个参数为输出图像的宽高,若要保留完整旋转后内容可自行调大尺寸 warped_img = cv2.warpPerspective(original_img, H, (original_img.shape[1], original_img.shape[0]))
注意事项
- 四个源点和目标点的顺序必须严格对应,否则会出现图像扭曲错位
- 如果只是实现纯平面内的刚性旋转,用仿射变换也可以实现,但单应性的兼容性更强,后续如果需要添加倾斜、透视变化等效果无需调整流程
- 若旋转后矩形边缘被裁剪,可提前计算旋转后的矩形外接框尺寸,调整
warpPerspective的第三个参数适配
内容的提问来源于stack exchange,提问作者Brans
相关产品推荐
相关产品推荐

