You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将warped图像中Hello的bounding box坐标映射回原始图像?

嘿,这个问题其实很好解决——核心就是利用透视变换的可逆性,把你在warped图上的边界框坐标映射回原始图像就行。我给你一步步讲清楚怎么做:

核心思路

你在执行四点透视变换时,会得到一个透视变换矩阵M(一般是通过cv2.getPerspectiveTransform计算的),它负责把原始图像的坐标映射到warped图像。那反过来,这个矩阵的逆矩阵M_inv,就能把warped图像上的坐标转换回原始图像的对应位置。

具体操作步骤
  1. 修改四点变换函数,保留变换矩阵M
    你之前的four_point_transform应该只返回了warped图像,现在得让它同时返回变换矩阵M。修改后的函数大概是这样:

    def four_point_transform(image, pts):
        # 原有的计算逻辑(排序四点、计算目标宽高)不变
        (tl, tr, br, bl) = pts
        maxWidth = max(int(np.linalg.norm(tr - tl)), int(np.linalg.norm(br - bl)))
        maxHeight = max(int(np.linalg.norm(bl - tl)), int(np.linalg.norm(br - tr)))
        
        # 定义目标图像的四点坐标
        dst = np.array([
            [0, 0],
            [maxWidth - 1, 0],
            [maxWidth - 1, maxHeight - 1],
            [0, maxHeight - 1]
        ], dtype="float32")
        
        # 计算透视变换矩阵M
        M = cv2.getPerspectiveTransform(pts, dst)
        warped = cv2.warpPerspective(image, M, (maxWidth, maxHeight))
        
        # 同时返回warped图像和变换矩阵M
        return warped, M
    
  2. 计算逆变换矩阵M_inv
    拿到M之后,用OpenCV的cv2.invert函数计算它的逆矩阵:

    # 假设你已经有原始图像original_image,以及变换用的四个点pts
    warped, M = four_point_transform(original_image, pts)
    # 计算逆矩阵,第二个返回值是逆矩阵的状态(我们这里不用关注)
    M_inv, _ = cv2.invert(M)
    
  3. 准备warped图中边界框的四个顶点
    你画的矩形是从(37,20)到(222,97),对应的四个顶点按顺序(左上、右上、右下、左下)定义出来:

    warped_bbox_pts = np.array([
        [37, 20],   # 左上
        [222, 20],  # 右上
        [222, 97],  # 右下
        [37, 97]    # 左下
    ], dtype=np.float32)
    
  4. 把warped坐标映射回原始图像
    用cv2.perspectiveTransform做坐标转换,注意要把点转换成函数要求的形状((1, N, 2)):

    # 调整形状以满足透视变换的输入要求
    warped_bbox_pts = warped_bbox_pts.reshape((1, 4, 2))
    # 应用逆变换得到原始图像中的坐标
    original_bbox_pts = cv2.perspectiveTransform(warped_bbox_pts, M_inv)
    # 把浮点坐标转成整数(图像坐标都是整数)
    original_bbox_pts = np.int32(original_bbox_pts)
    
  5. 在原始图像上绘制边界框
    因为逆变换后的点可能不再是严格的矩形(透视变换会让形状畸变),所以用cv2.polylines绘制闭合四边形更准确:

    # 在原始图像上画红色的边界框,线宽2
    cv2.polylines(original_image, original_bbox_pts, isClosed=True, color=(0, 0, 255), thickness=2)
    
完整的代码片段参考

把这些步骤整合起来,大概是这样的:

import cv2
import numpy as np

def four_point_transform(image, pts):
    (tl, tr, br, bl) = pts
    maxWidth = max(int(np.linalg.norm(tr - tl)), int(np.linalg.norm(br - bl)))
    maxHeight = max(int(np.linalg.norm(bl - tl)), int(np.linalg.norm(br - tr)))

    dst = np.array([
        [0, 0],
        [maxWidth - 1, 0],
        [maxWidth - 1, maxHeight - 1],
        [0, maxHeight - 1]
    ], dtype="float32")

    M = cv2.getPerspectiveTransform(pts, dst)
    warped = cv2.warpPerspective(image, M, (maxWidth, maxHeight))

    return warped, M

# 加载原始图像(替换成你的图像路径)
original_image = cv2.imread("your_image_path.jpg")
# 假设你已经有四点变换的四个点pts(比如手动标注或检测得到)
pts = np.array([[x1,y1], [x2,y2], [x3,y3], [x4,y4]], dtype="float32")

# 执行四点变换,得到warped图像和变换矩阵M
warped, M = four_point_transform(original_image, pts)

# 在warped图上绘制原有的蓝色边界框
cv2.rectangle(warped, (37, 20), (222, 97), (255, 0, 0), 2)

# 计算逆变换矩阵
M_inv, _ = cv2.invert(M)

# 定义warped图中边界框的四个顶点
warped_bbox_pts = np.array([
    [37, 20], [222, 20], [222, 97], [37, 97]
], dtype=np.float32)

# 坐标映射转换
warped_bbox_pts = warped_bbox_pts.reshape((1, 4, 2))
original_bbox_pts = cv2.perspectiveTransform(warped_bbox_pts, M_inv)
original_bbox_pts = np.int32(original_bbox_pts)

# 在原始图像上绘制红色边界框
cv2.polylines(original_image, original_bbox_pts, isClosed=True, color=(0, 0, 255), thickness=2)

# 显示结果
cv2.imshow("Warped Image", warped)
cv2.imshow("Original Image with BBox", original_image)
cv2.waitKey(0)
cv2.destroyAllWindows()

内容的提问来源于stack exchange,提问作者Himansingh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 07:42:58