已知相机内外参如何将图像掩码投影到3D网格并生成点云
2D掩码反投影3D网格点云实现方案
思路合理性判断
你的射线求交实现思路没有过度复杂化,是2D像素反投影到3D表面的标准工业实现方案,不需要调整整体逻辑。
射线上两点的正确生成方式
你之前的反投影公式忽略了齐次坐标的尺度问题,射线上的两个点不需要刻意找"特殊深度值",按以下方式生成即可:
- 第一个点是射线起点,也就是相机在世界坐标系下的光心位置,直接从外参逆矩阵提取即可:
cam_origin = np.linalg.inv(Extrinsic)[:3, 3]
这个点是所有像素投射射线的公共起点,不需要逐像素计算。 - 第二个点(成像平面前方的任意射线上点)逐像素计算即可,深度值可以任意取正数(比如固定取z=1,不影响射线方向):
- 将像素坐标(u, v)转为齐次形式:
px_homo = np.array([u, v, 1.0]) - 转换到相机坐标系:
p_cam = np.linalg.inv(Intrinsic) @ px_homo * 1.0(这里乘的1.0就是取的深度z=1,换成任意正数都可以) - 补齐次维度后转到世界坐标系:
p_cam_homo = np.array([p_cam[0], p_cam[1], p_cam[2], 1.0]) p_far = np.linalg.inv(Extrinsic) @ p_cam_homo p_far = p_far[:3]
p_far就是你需要的远离成像平面的射线上的点,连接cam_origin和p_far就是该像素对应的完整投射射线。 - 将像素坐标(u, v)转为齐次形式:
注意:因为射线是过相机光心的无限长直线,只要选取的深度值为正(保证点在相机前方),无论深度取多少,两点确定的射线方向完全一致,不需要纠结深度取值的大小。
求交环节注意事项
- 求解射线与三角网格交点时,只保留射线正方向(从
cam_origin指向p_far的方向)上距离光心最近的交点,即为该像素对应在3D网格表面的真实点。 - 不要直接使用你提到的
worldpoint= Intrinsic^(-1) * Extrinsic^(-1) * imgpoint公式直接计算世界坐标,该结果是齐次坐标下尺度不确定的点,没有固定物理意义,必须配合深度值或射线求交才能得到正确的空间位置。 - 若使用三角网格作为求交对象,建议直接调用成熟的射线-三角网格求交接口,避免手写求交逻辑出现数值精度问题。
内容的提问来源于stack exchange,提问作者Filipe Jorge
相关产品推荐
相关产品推荐

