美文网首页
2D-2D相机位姿估计

2D-2D相机位姿估计

作者: 金戈大王 | 来源:发表于2017-06-05 20:34 被阅读3165次

本文将介绍如何根据相机在不同位置拍摄的两张图片恢复出相机的运动。在多视图几何学中,这被称为对极几何。

一、对极几何

如下图所示,相机在两个不同的位置(蓝色位置和绿色位置)同时观测到了同一个点X。根据上一篇文章《OpenCV提取ORB特征并匹配》,我们可以将X在两个相机平面上的投影x点和x'点的像素坐标匹配起来。此时,x和x'便满足一个约束,称为对极约束。

对极约束的数学推导并不复杂,本文为求简明和实用,对此不做细究。更多内容可以参考文末列出的参考资料。这里只给出直观的解释。

相机在两个位置的光心分别为O点和O'点,连线OO'与两个成像平面的交点分别为e点和e'点。我们把线段xe和x'e'称为极线。下面我们来分析为什么利用两张图片中特征点对的像素坐标可以恢复相机运动和地图点X的深度(X点的深度估计将在下篇文章中介绍)。

假设左侧相机固定,右侧相机位姿待估计。那么OX射线方向确定,同时,OX在右侧相机平面上的投影也随之确定,即直线l'。这一投影关系便称为对极约束。不过,单个对极约束并不能完全确定右侧相机的位置,大家可以想象右侧相机平面如何在保持x'坐标不变的情况下调整自己的姿态。换句话说,对极约束是有多个自由度的,一对匹配点并不能唯一确定两个相机的位姿。那到底需要多少对点呢?数学上可以证明,至少需要5对。而实际应用中通常使用8对以简化计算过程,称为“八点法”。下面就进入实际代码环节,不在理论上过多纠缠了。

二、2D-2D相机位姿估计

从两张2D图像估计相机位姿的流程如下图所示。

其中有一处分叉点,分别适用于不同的情况。左侧“计算基础矩阵或本质矩阵”适用于特征点不共面的情况;右侧“计算单应矩阵”适用于特征点共面的情况(比如墙壁、地面、航拍等场合)。

下面只给出2D-2D相机位姿估计函数的代码,特征点匹配部分的代码在上一篇文章中可以找到。

完整代码的下载地址:https://github.com/jingedawang/FeatureMethod

void pose_estimation_2d2d ( std::vector<KeyPoint> keypoints_1,
                            std::vector<KeyPoint> keypoints_2,
                            std::vector< DMatch > matches,
                            Mat& R, Mat& t )
{
    // 相机内参,TUM Freiburg2
    Mat K = ( Mat_<double> ( 3,3 ) << 520.9, 0, 325.1, 0, 521.0, 249.7, 0, 0, 1 );

    //-- 把匹配点转换为vector<Point2f>的形式
    vector<Point2f> points1;
    vector<Point2f> points2;

    for ( int i = 0; i < ( int ) matches.size(); i++ )
    {
        points1.push_back ( keypoints_1[matches[i].queryIdx].pt );
        points2.push_back ( keypoints_2[matches[i].trainIdx].pt );
    }

    //-- 计算基础矩阵
    Mat fundamental_matrix;
    fundamental_matrix = findFundamentalMat ( points1, points2, CV_FM_8POINT );
    cout<<"fundamental_matrix is "<<endl<< fundamental_matrix<<endl;

    //-- 计算本质矩阵
    Point2d principal_point ( 325.1, 249.7 );   //相机光心, TUM dataset标定值
    double focal_length = 521;          //相机焦距, TUM dataset标定值
    Mat essential_matrix;
    essential_matrix = findEssentialMat ( points1, points2, focal_length, principal_point );
    cout<<"essential_matrix is "<<endl<< essential_matrix<<endl;

    //-- 计算单应矩阵
    Mat homography_matrix;
    homography_matrix = findHomography ( points1, points2, RANSAC, 3 );
    cout<<"homography_matrix is "<<endl<<homography_matrix<<endl;

    //-- 从本质矩阵中恢复旋转和平移信息.
    recoverPose ( essential_matrix, points1, points2, R, t, focal_length, principal_point );
    cout<<"R is "<<endl<<R<<endl;
    cout<<"t is "<<endl<<t<<endl;
    
}

这里需要解释一下,基础矩阵和本质矩阵都是3×3的矩阵,它们之间不过是差了个相机内参,因此使用时效果完全一样。上边的代码使用了本质矩阵来恢复相机运动,而没有用单应矩阵,这是因为示例图片中的特征点并不共面。在实际应用中,如果事先无法知道特征点是否共面,则应当同时计算本质矩阵和单应矩阵,选择重投影误差比较小的那个作为最终的运动估计矩阵,具体操作敬请期待后续系列文章。

三、进一步讨论

2D-2D相机位姿估计是单目SLAM初始化时的关键技术。初始化成功之后,后续的视频帧就可以采用3D-2D匹配来简化计算过程。因此初始化成功与否对SLAM至关重要。

从单目SLAM的角度考虑,2D-2D相机位姿估计存在以下三个敏感的问题:

  1. 尺度不确定性
    用上面的方法估计出的相机平移向量t的值并没有单位,也就是说相机移动的距离只有相对值,没有绝对值。这是单目相机固有的尺度不确定性问题,无法从根本上解决。因此单目SLAM中一般把初始化后的t归一化,即把初始化时移动的距离默认为1,此后的距离都以这个1为单位。

  2. 初始化的纯旋转问题
    单目初始化不能只有旋转,必须要有一定程度的平移,否则由于t趋近于0,导致无从求解R或者误差非常大。

  3. 多于8对点的情况
    如果匹配的点对数多于8(大多数情况都是这样),可以考虑充分利用这些点,而不是只从中选择8对用于计算。推荐的算法是随机采样一致性(Random Sample Consensus,RANSAC),该算法可以有效地避免错误数据对整体结果的影响。在代码中,只需要将findFundamentalMat函数的第三个参数从CV_FM_8POINT换成CV_FM_RANSAC就可以了。

四、参考资料

《视觉SLAM十四讲》第7讲 视觉里程计1 高翔
本质矩阵和基础矩阵的区别是什么? 知乎

相关文章

  • 三角测量

    本文紧接着前一篇文章《2D-2D相机位姿估计》展开。在得到了两张图片对应的相机位姿之后,就可以通过三角测量的方法计...

  • 2D-2D相机位姿估计

    本文将介绍如何根据相机在不同位置拍摄的两张图片恢复出相机的运动。在多视图几何学中,这被称为对极几何。 一、对极几何...

  • LK光流跟踪

    一、什么是光流? 在前几篇文章中,我们介绍了2D-2D、3D-2D、3D-3D等相机位姿估计方法,它们都是在特征点...

  • week63 PnP位姿估计 基于ArUco Marker来估算

    相机位姿估计 相机位姿估计是指给定若干图像,估计其中相机运动的问题。求解方法通常分特征点法和直接法两种,这也是视觉...

  • 3D-3D相机位姿估计

    在上一篇文章中,我们介绍了3D-2D相机位姿估计,采用PnP方法估计单目SLAM的相机位姿。而对于RGBD深度相机...

  • 直接法估计相机位姿(inverse compositional)

    直接法是用于视觉里程计估计相机位姿的一种重要方法。相比于其他依赖几何特征做相机位姿估计的方法,直接法具有无需计算特...

  • 直接法相机位姿估计

    前面用了好几篇文章介绍特征点法的相机位姿估计,本文则换一种思路,介绍近年来日渐流行的直接法。 一、直接法 与“光流...

  • SLAM学习笔记4

    在SLAM中常需要估计一个相机的位置和姿态,这是个优化问题,需要对相机位姿求导,而李代数可以方便地表示相机位姿的导...

  • 3D-2D相机位姿估计

    本文首先介绍如何使用OpenCV中的PnP求解3D-2D位姿变换,再介绍如何使用g2o对前面得出的结果进行集束调整...

  • 位姿估计

    SLAM-基于深度学习的位姿估计

网友评论

      本文标题:2D-2D相机位姿估计

      本文链接:https://www.haomeiwen.com/subject/chiifxtx.html