C++ 在OpenCV中,将二维图像点转换为三维世界单位向量

C++ 在OpenCV中,将二维图像点转换为三维世界单位向量,c++,opencv,computer-vision,C++,Opencv,Computer Vision,我已经用OpenCV(findChessboard等)校准了我的相机,因此我有: -摄像机畸变系数与内禀矩阵 -摄像机姿态信息(平移和旋转,通过其他方式单独计算)为Euler角和4x4 -摄影机帧内的二维点 如何将这些二维点转换为指向世界的三维单位向量?我尝试使用cv::UnsortPoints,但似乎不行(只返回2D重新映射的点),而且我不确定使用哪种矩阵数学方法通过我拥有的摄影机内部函数对摄影机建模。将2D点转换为同质点(给它一个等于1的第三个坐标)然后乘以相机内部矩阵的倒数。比如说 cv:

我已经用OpenCV(findChessboard等)校准了我的相机,因此我有: -摄像机畸变系数与内禀矩阵 -摄像机姿态信息(平移和旋转,通过其他方式单独计算)为Euler角和4x4 -摄影机帧内的二维点


如何将这些二维点转换为指向世界的三维单位向量?我尝试使用cv::UnsortPoints,但似乎不行(只返回2D重新映射的点),而且我不确定使用哪种矩阵数学方法通过我拥有的摄影机内部函数对摄影机建模。

将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点?在相机帧内捕获的2D图像(像素)坐标。基本上,给定一个二维图像坐标和上述数据,我应该能够从相机中构造一个指向该二维图像坐标的三维单位向量。您忘记了规范化hom_pt.)@IanMedeiros你的意思是把它变成单位向量还是把第三个元素变成1?这些点定义的向量是正确的,无论是否进行任何规格化,在乘以相机矩阵的倒数后,第三个元素可以解释为z坐标。事实上,我对你的答案投了赞成票,但现在我不确定它是否正确。我认为,在进行所讨论的均匀化之前,需要使用内在矩阵将2D坐标从像素转换为世界坐标。然后你可以使用相机姿态信息来转换它,以获得光线方向。@IanMedeiros我想让相机垫成为本质,我更新了答案,使其更清晰。这就是你说的吗?是的,没错。现在,你确定均匀化的2D点乘以内在矩阵会得到单位向量吗?如果没有,就有必要将其正常化。