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

使用OpenCV将Unity场景已知3D点投影至图像的问题排查

Unity转OpenCV 3D点投影错误排查建议

问题背景

在Unity中构建含纹理球体与相交平面的场景,使用Physical Camera拍摄图像后,尝试用OpenCV将已知3D点投影到图像上,但投影点位置错误。已确认3D坐标正确,预期投影点与实际输出偏差明显。

排查步骤

1. 相机内参矩阵计算验证

你的内参计算逻辑可能存在错误,需重点核对以下细节:

  • 焦距计算冗余项:Unity的pixelAspectRatio是显示适配参数,无需加入f_y的计算。正确的f_y计算应为:
    float f_y = cam.focalLength * ((float)cam.pixelHeight / cam.sensorSize.y);
    
  • 主点偏移修正:若Unity相机开启了镜头偏移(Lens Shift),主点坐标不能直接取像素宽高的一半,需加入偏移量对应的像素值:
    float lensShiftX = cam.lensShift.x;
    float lensShiftY = cam.lensShift.y;
    float x_0 = (float)cam.pixelWidth / 2 + lensShiftX * (float)cam.pixelWidth / 2;
    float y_0 = (float)cam.pixelHeight / 2 - lensShiftY * (float)cam.pixelHeight / 2;
    
    注意Unity镜头偏移的Y轴方向与图像坐标系的对应关系,需取反适配。
  • 内参矩阵构造:确保最终生成的K矩阵是标准3x3内参格式:
    K = np.array([
        [f_x, 0, x_0],
        [0, f_y, y_0],
        [0, 0, 1]
    ], dtype=np.float32)
    

2. 坐标系转换逻辑修正

Unity为左手坐标系,OpenCV为右手坐标系,且两者相机空间定义差异较大,你的转换矩阵逻辑存在偏差:

(1)3D点转换

正确流程是先将Unity世界点转Unity相机空间,再转OpenCV相机空间:

  • Unity相机空间转换:unity_cam_point = cam.worldToCameraMatrix.MultiplyPoint(world_point)
  • OpenCV相机空间适配:cv_cam_point = np.array([unity_cam_point.x, -unity_cam_point.y, -unity_cam_point.z])
    直接反转Y、Z轴,匹配OpenCV右手坐标系与图像Y轴向下的规则。

(2)旋转矩阵转换

cv.projectPoints需要的是世界到相机空间的旋转向量,正确转换步骤:

  • 从Unity获取相机旋转矩阵(世界到相机):unity_rot(转换为3x3矩阵格式)
  • 坐标系适配转换:
    cv_rot = np.array([
        [1, 0, 0],
        [0, -1, 0],
        [0, 0, -1]
    ]) @ unity_rot
    
  • 旋转矩阵转旋转向量:rvec, _ = cv.Rodrigues(cv_rot)

(3)平移向量转换

OpenCV的tvec是世界到相机空间的平移向量,对应Unity相机世界位置的反向适配:

unity_tvec = -cam.transform.position
cv_tvec = np.array([unity_tvec.x, -unity_tvec.y, -unity_tvec.z]).reshape(3,1)

3. cv.projectPoints参数校验

  • 3D点格式:确保输入的3d_points是(N,3)格式的numpy数组,且为世界空间坐标。
  • 外参顺序:rvec和tvec组成的外参是世界到相机空间的变换,不要搞反成相机到世界。
  • 图像坐标系适配:OpenCV图像原点在左上角、Y轴向下,Unity图像原点在左下角、Y轴向上,绘制投影点时需反转Y坐标:cv_point_y = image_height - projected_point_y

4. 辅助验证手段

  • 用Unity的Gizmos在场景中绘制已知3D点,再次确认坐标正确性。
  • 手动计算简单测试点(如相机正前方1米处的原点)的投影坐标,对比cv.projectPoints的输出结果。
  • 用OpenCV绘制内参对应的成像平面,验证焦距与主点参数是否符合预期。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 07:25:29