OpenCV透视变换后扭曲图像边界框重映射回原图出错如何解决
错误原因和修正方案
核心错误点
- API使用错误:
cv2.transform是为仿射变换设计的,不会执行透视变换必须的齐次坐标归一化操作,透视变换的坐标转换必须使用cv2.perspectiveTransform。 - 坐标提取逻辑不严谨:透视变换会将矩形变为任意四边形,直接取原矩形对角点的映射结果作为新矩形的对角点会出现错位,需要对四个映射后的点求外接轴对齐矩形。
- 你使用逆矩阵的思路是正确的,只是配合了错误的API才导致结果异常。
修正后代码
import numpy as np import cv2 import copy # 1. 计算H1的逆矩阵 inv_H1 = np.linalg.inv(H1) stereo_bbox = [219, 321, 1005, 634] # 2. 构造符合perspectiveTransform输入要求的角点数组,形状为(4,1,2),数据类型为float32 four_points = np.array([ [stereo_bbox[0], stereo_bbox[1]], [stereo_bbox[2], stereo_bbox[1]], [stereo_bbox[2], stereo_bbox[3]], [stereo_bbox[0], stereo_bbox[3]] ], dtype=np.float32).reshape(-1, 1, 2) # 3. 执行透视逆变换 mapped_points = cv2.perspectiveTransform(four_points, inv_H1) mapped_points = mapped_points.squeeze().astype(np.int32) # 4. 计算映射后四边形的外接轴对齐矩形 min_x = np.min(mapped_points[:, 0]) min_y = np.min(mapped_points[:, 1]) max_x = np.max(mapped_points[:, 0]) max_y = np.max(mapped_points[:, 1]) # 可选:限制坐标不超出原图范围,避免绘图报错 h1, w1 = img1.shape[:2] min_x = max(0, min_x) min_y = max(0, min_y) max_x = min(w1 - 1, max_x) max_y = min(h1 - 1, max_y) # 5. 绘制矩形 tmpimg1 = copy.deepcopy(img1) cv2.rectangle(tmpimg1, (min_x, min_y), (max_x, max_y), (0, 0, 255), 3)
补充说明
cv2.perspectiveTransform 会自动完成齐次坐标到笛卡尔坐标的归一化操作(将矩阵乘法得到的三维坐标除以第三分量得到二维坐标),这是你之前用cv2.transform得到错误坐标的核心原因。
内容的提问来源于stack exchange,提问作者Arkistarvh Kltzuonstev
相关产品推荐
相关产品推荐

