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

如何通过OpenCV Homography获取目标在变换后图像的新坐标?

问题描述

我正在使用**Homography(单应性变换)**进行篮球场检测,已在原始图像中检测到球员目标,现需获取该球员在透视变换后图像中的新坐标,用于构建小地图系统。

当前代码
import cv2
import numpy as np
import matplotlib.pyplot as plt

#player coordinates - multiple players
x_coords = []
y_coords = []

print(x_coords)
print(y_coords)


#basketball court, size-1830, 910
pts_src = np.array([
    [394, 412], # top left corner
    [0, 500],
    [0, 670],     
    [910, 770],
    [1830, 720],     
    [1830,545],
    [1540, 450]      # top right corner
])

#minimap, size-500,300 
pts_dst = np.array([
    [0, 0],         # top left corner
    [0, 275],
    [25, 300],      
    [250, 300],
    [475, 300],
    [500, 275],     
    [500, 0]       # top right corner
])

#find homography
h, status = cv2.findHomography(pts_src, pts_dst)


img_src2 = cv2.imread('basketball_court.png')
img_out = cv2.warpPerspective(img_src2, h, (img_dst.shape[1], img_dst.shape[0]))

cv2.imshow("Warped", img_out)
cv2.waitKey(0)
已尝试参考资料
  • 利用OpenCV单应性从像素坐标转换为全局XY坐标
  • OpenCV 2.4官方文档:从齐次坐标转换点的说明
解决方案

要实现球员坐标从原始图像到小地图的转换,核心是用已求得的单应矩阵h对球员坐标进行齐次变换,具体步骤如下:

  1. 整理球员坐标格式:将检测到的球员(x,y)坐标转换为OpenCV要求的N×1×2格式numpy数组,示例:
# 替换为实际检测到的球员坐标
x_coords = [150, 400, 650]
y_coords = [300, 550, 700]
players = np.array(list(zip(x_coords, y_coords)), dtype=np.float32).reshape(-1,1,2)
  1. 应用单应变换:使用cv2.perspectiveTransform()函数完成坐标转换:
transformed_players = cv2.perspectiveTransform(players, h)
  1. 提取最终坐标:将变换后的结果转换为普通(x,y)格式,方便后续使用:
new_coords = transformed_players.reshape(-1,2).tolist()
  1. 整合后的完整代码:
import cv2
import numpy as np
import matplotlib.pyplot as plt

# 替换为实际检测到的球员坐标
x_coords = [150, 400, 650]
y_coords = [300, 550, 700]
# 转换为OpenCV要求的格式
players = np.array(list(zip(x_coords, y_coords)), dtype=np.float32).reshape(-1,1,2)

#basketball court, size-1830, 910
pts_src = np.array([
    [394, 412], # top left corner
    [0, 500],
    [0, 670],     
    [910, 770],
    [1830, 720],     
    [1830,545],
    [1540, 450]      # top right corner
], dtype=np.float32)

#minimap, size-500,300 
pts_dst = np.array([
    [0, 0],         # top left corner
    [0, 275],
    [25, 300],      
    [250, 300],
    [475, 300],
    [500, 275],     
    [500, 0]       # top right corner
], dtype=np.float32)

#find homography
h, status = cv2.findHomography(pts_src, pts_dst)

# 转换球员坐标并打印结果
transformed_players = cv2.perspectiveTransform(players, h)
new_coords = transformed_players.reshape(-1,2).tolist()
print("球员在小地图中的坐标:")
for idx, (x,y) in enumerate(new_coords):
    print(f"球员{idx+1}: ({round(x,2)}, {round(y,2)})")

# 透视变换图像(修正原代码中img_dst未定义的问题)
img_src2 = cv2.imread('basketball_court.png')
img_out = cv2.warpPerspective(img_src2, h, (500, 300))

cv2.imshow("Warped", img_out)
cv2.waitKey(0)
cv2.destroyAllWindows()
关键注意事项
  • 所有参与变换的坐标数组需指定dtype=np.float32,否则会触发类型错误
  • cv2.perspectiveTransform()会自动处理齐次坐标转换,无需手动调用convertPointsFromHomogeneous
  • 原代码中img_dst未定义,因此warpPerspective的输出尺寸直接使用小地图的(500,300)即可

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 01:00:55