在OpenCV中,将2D图像点转换为3D世界单位向量

13
我已经通过OpenCV(findChessboard等)对我的相机进行了校准,因此我拥有: - 相机畸变系数和内参矩阵 - 相机姿态信息(平移和旋转,通过其他方法分别计算得出),以欧拉角和4x4形式表示 - 相机内的2D点。
如何将这些2D点转换为指向世界的3D单位向量?我尝试使用cv::undistortPoints,但似乎不行(仅返回2D映射点),而我也不确定应该使用什么矩阵数学方法来模拟具有我所拥有的相机内参的相机。

你在谈论哪些二维点? - Ian Medeiros
在相机的框架内捕获2D图像(像素)坐标。基本上,给定一个2D图像坐标和上述数据,我应该能够从相机构造一个指向该2D图像坐标的3D单位向量。 - Yeraze
1个回答

20

将您的2D点转换为齐次点(将其第三个坐标设置为1),然后乘以相机内参矩阵的逆矩阵。例如:

cv::Matx31f hom_pt(point_in_image.x, point_in_image.y, 1);
hom_pt = camera_intrinsics_mat.inv()*hom_pt; //put in world coordinates

cv::Point3f origin(0,0,0);
cv::Point3f direction(hom_pt(0),hom_pt(1),hom_pt(2));

//To get a unit vector, direction just needs to be normalized
direction *= 1/cv::norm(direction);

原点和方向现在定义了对应于该图像点的射线在世界空间中。注意,这里的原点位于相机中心,您可以使用相机姿态将其转换为不同的原点。畸变系数从实际相机映射到针孔相机模型,应在最开始时用于找到实际的2D坐标。然后的步骤是:

  1. 使用畸变系数无畸变的2D坐标
  2. 将其转换为射线(如上所示)
  3. 将该射线移动到您喜欢的任何坐标系中。

你忘记对hom_pt进行归一化了。 :) - Ian Medeiros
@IanMedeiros 你的意思是将它变成单位向量还是将第三个元素变为1?由这些点定义的向量在任何归一化的情况下都是正确的,在乘以相机矩阵的逆矩阵后,第三个元素可以被解释为z坐标。 - Hammer
其实,我已经给你的答案点了赞,但现在我不确定它是否正确。我认为,在进行您所谈论的同次化之前,您需要使用内参矩阵将2D坐标从像素转换为世界坐标。然后,您可以使用相机姿态信息来对其进行变换以获取光线方向。 - Ian Medeiros
@IanMedeiros 我本意是让camera_mat成为内参矩阵,我更新了答案以使其更加清晰。这就是你所说的吗? - Hammer
相机畸变怎么办? - EBAG
显示剩余4条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接