首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >【OpenCV 中的坐标还原操作】仿射、透视、ROI

【OpenCV 中的坐标还原操作】仿射、透视、ROI

作者头像
flos chen
发布2026-01-23 15:07:34
发布2026-01-23 15:07:34
1250
举报

在 OpenCV 中,坐标还原通常指将经过变换(如旋转、缩放、仿射/透视变换)后的图像中的坐标点,反向映射回原始图像中的对应位置。这在目标检测、图像配准、几何校正等场景中非常关键。


一、坐标还原的核心原理

坐标还原本质是 逆变换。若对图像应用了某种变换矩阵 ( M ),则还原坐标需使用其逆矩阵 ( M^{-1} )。

数学表示
  • 变换公式:( \text{dst}(x’, y’) = M \cdot \text{src}(x, y) )
  • 逆变换公式:( \text{src}(x, y) = M^{-1} \cdot \text{dst}(x’, y’) )

二、常见场景与实现方法
1. 仿射变换的坐标还原

仿射变换(如旋转、平移、缩放)使用 2x3 矩阵,可通过计算逆矩阵还原坐标。

步骤
  1. 生成逆变换矩阵: OpenCV 提供 cv2.invertAffineTransform(M) 直接计算仿射矩阵的逆矩阵。
  2. 应用逆变换: 使用 cv2.transform() 或手动矩阵乘法还原坐标。
代码示例
代码语言:javascript
复制
import cv2
import numpy as np

# 原图尺寸
h, w = 400, 600

# 定义仿射变换矩阵(旋转45度)
center = (w//2, h//2)
M = cv2.getRotationMatrix2D(center, angle=45, scale=1.0)

# 变换后的图像
rotated = cv2.warpAffine(img, M, (w, h))

# 计算逆矩阵
M_inv = cv2.invertAffineTransform(M)

# 假设变换后图像中的点 (x_dst, y_dst)
x_dst, y_dst = 100, 200

# 还原到原图坐标
src_point = np.array([[x_dst, y_dst]], dtype=np.float32)
restored_point = cv2.transform(src_point.reshape(1, -1, 2), M_inv).squeeze()

print(f"变换后坐标: ({x_dst}, {y_dst}) -> 原图坐标: {restored_point}")
2. 透视变换的坐标还原

透视变换(如投影校正)使用 3x3 矩阵,需计算逆矩阵或使用 cv2.perspectiveTransform()

步骤
  1. 生成逆矩阵: 使用 np.linalg.inv(M) 计算透视变换矩阵的逆矩阵 ( M^{-1} )。
  2. 应用逆变换: 使用 cv2.perspectiveTransform() 处理齐次坐标。
代码示例
代码语言:javascript
复制
# 定义透视变换矩阵(假设已通过cv2.getPerspectiveTransform获取)
M_perspective = cv2.getPerspectiveTransform(src_pts, dst_pts)

# 变换后的图像
warped = cv2.warpPerspective(img, M_perspective, (w, h))

# 计算逆矩阵
M_perspective_inv = np.linalg.inv(M_perspective)

# 变换后图像中的点 (x_dst, y_dst)
x_dst, y_dst = 150, 300

# 齐次坐标转换
dst_point = np.array([[[x_dst, y_dst]]], dtype=np.float32)
restored_point = cv2.perspectiveTransform(dst_point, M_perspective_inv).squeeze()

print(f"变换后坐标: ({x_dst}, {y_dst}) -> 原图坐标: {restored_point}")
3. ROI(感兴趣区域)的坐标还原

若操作仅涉及图像裁剪(ROI),坐标还原只需 平移操作

代码示例
代码语言:javascript
复制
# 定义ROI区域 (x, y, width, height)
roi_x, roi_y, roi_w, roi_h = 100, 50, 200, 150
roi = img[roi_y:roi_y+roi_h, roi_x:roi_x+roi_w]

# 在ROI中检测到点的局部坐标 (x_local, y_local)
x_local, y_local = 30, 40

# 还原到原图全局坐标
x_global = roi_x + x_local
y_global = roi_y + y_local

print(f"ROI坐标: ({x_local}, {y_local}) -> 原图坐标: ({x_global}, {y_global})")

三、注意事项

矩阵可逆性

  • 仿射矩阵必须满足可逆条件(行列式不为零)。
  • 透视矩阵需为满秩矩阵。

浮点精度误差: 还原后的坐标可能为浮点数,需根据需求决定是否取整。

边界处理: 若变换后坐标超出原图范围,需进行有效性检查:

代码语言:javascript
复制
if (0 <= x_restored < w) and (0 <= y_restored < h):
    # 坐标有效
else:
    # 坐标越界

齐次坐标: 透视变换需使用齐次坐标(三维向量),还原后需归一化:

代码语言:javascript
复制
restored_point_homogeneous = np.dot(M_inv, [x_dst, y_dst, 1])
x_restored = restored_point_homogeneous[0] / restored_point_homogeneous[2]
y_restored = restored_point_homogeneous[1] / restored_point_homogeneous[2]

四、完整应用案例

场景:在旋转后的图像中检测目标框,还原坐标到原图。

代码语言:javascript
复制
# 旋转图像
M = cv2.getRotationMatrix2D((w//2, h//2), 30, 1.0)
rotated = cv2.warpAffine(img, M, (w, h))

# 在旋转后的图像中检测目标框 (x1, y1, x2, y2)
box_rotated = [50, 80, 200, 300]

# 还原四个顶点坐标
points_dst = np.array([
    [box_rotated[0], box_rotated[1]],
    [box_rotated[2], box_rotated[1]],
    [box_rotated[2], box_rotated[3]],
    [box_rotated[0], box_rotated[3]]
], dtype=np.float32)

M_inv = cv2.invertAffineTransform(M)
points_src = cv2.transform(points_dst.reshape(1, -1, 2), M_inv).squeeze()

# 在原图中绘制还原后的框
cv2.polylines(img, [points_src.astype(np.int32)], True, (0, 255, 0), 2)
cv2.imshow('Restored Box', img)
cv2.waitKey(0)

五、总结

变换类型

核心方法

关键函数

适用场景

仿射变换

计算逆仿射矩阵

cv2.invertAffineTransform()

旋转、平移、缩放

透视变换

计算逆透视矩阵 + 齐次坐标归一化

cv2.perspectiveTransform()

投影校正、视角变换

ROI

直接平移坐标

图像裁剪后的坐标映射

掌握坐标还原技术能有效提升图像处理流程的灵活性,尤其在需要跨变换空间传递信息的任务中(如目标跟踪、增强现实)。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2025-04-12,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、坐标还原的核心原理
    • 数学表示:
  • 二、常见场景与实现方法
    • 1. 仿射变换的坐标还原
      • 步骤:
      • 代码示例:
    • 2. 透视变换的坐标还原
      • 步骤:
      • 代码示例:
    • 3. ROI(感兴趣区域)的坐标还原
      • 代码示例:
  • 三、注意事项
  • 四、完整应用案例
  • 五、总结
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档