单目初始化以及通过三角化恢复出地图点

单目的初始化有专门的初始化器,只有连续的两帧特征点均>100个才能够成功构建初始化器。

  1. // mvbPreMatched是第一帧中的所有特征点;mvIniMatches标记匹配状态,未匹配上的标为-1;如果返回nmatches<100,初始化失败,重新初始化过程
    int nmatches = matcher.SearchForInitialization(mInitialFrame,mCurrentFrame,mvbPrevMatched,mvIniMatches,);

若成功获取满足特征点匹配条件的连续两帧,并行计算分解基础矩阵和单应矩阵(获取的点恰好位于同一个平面),得到帧间运动(位姿),vbTriangulated标记一组特征点能否进行三角化。mvIniP3D是cv::Point3f类型的一个容器,是个存放3D点的临时变量。

该函数对应Initialize.cpp文件,需要完成较多工作,后面再介绍。

  1. mpInitializer->Initialize(mCurrentFrame, mvIniMatches, Rcw, tcw, mvIniP3D, vbTriangulated)

最后初始化两帧位姿并且将mvIniP3D中的点包装成MapPoint,构建初始地图。

  1. mInitialFrame.SetPose(cv::Mat::eye(,,CV_32F));
  2. mCurrentFrame.SetPose(Tcw);
    CreateInitialMapMonocular();

构建初始地图就是将这两关键帧以及对应的地图点加入地图(mpMap)中,需要分别构造关键帧以及地图点

  1. KeyFrame* pKFini = new KeyFrame(mInitialFrame,mpMap,mpKeyFrameDB);
  2. KeyFrame* pKFcur = new KeyFrame(mCurrentFrame,mpMap,mpKeyFrameDB);

地图点中需要加入其一些属性:

1. 观测到该地图点的关键帧(对应的关键点);

2. 该MapPoint的描述子;

3. 该MapPoint的平均观测方向和观测距离。

  1. for(size_t i=; i<mvIniMatches.size();i++)
  2. {
  3. if(mvIniMatches[i]<)
  4. continue;
  5. //Create MapPoint from mvIniP3D
  6. cv::Mat worldPos(mvIniP3D[i]);
  7. MapPoint* pMP = new MapPoint(worldPos,pKFcur,mpMap);
  8. pKFini->AddMapPoint(pMP,i);
  9. pKFcur->AddMapPoint(pMP,mvIniMatches[i]);
  10. pMP->AddObservation(pKFini,i);
  11. pMP->AddObservation(pKFcur,mvIniMatches[i]);
  12. pMP->ComputeDistinctiveDescriptors();
  13. pMP->UpdateNormalAndDepth();
  14. mCurrentFrame.mvpMapPoints[mvIniMatches[i]] = pMP;
  15. mCurrentFrame.mvbOutlier[mvIniMatches[i]] = false;
  16. mpMap->AddMapPoint(pMP);
  17. }

还需要更新关键帧之间连接关系(以共视地图点的数量作为权重):

  1. pKFini->UpdateConnections();
  2. pKFcur->UpdateConnections();

对这两帧姿态进行全局优化重投影误差(LM):

  1. Optimizer::GlobalBundleAdjustemnt(mpMap,);

注意这里使用的是全局优化,和回环检测调整后的大回环优化使用的是同一个函数。

接下来,需要归一化第一帧中地图点深度的中位数;如果深度<0或者这时发现优化后第二帧追踪到的地图点<100,也需要重新初始化。

否则,将深度中值作为单位一,归一化第二帧的位姿与所有的地图点。

  1. float medianDepth = pKFini->ComputeSceneMedianDepth();
  2. float invMedianDepth = 1.0f/medianDepth;
  3.  
  4. if(medianDepth< || pKFcur->TrackedMapPoints()<)
  5. {
  6. cout << "Wrong initialization, reseting..." << endl;
  7. Reset();
  8. return;
  9. }
  10.  
  11. // Scale current pose
  12. cv::Mat Tc2w = pKFcur->GetPose();
  13. Tc2w.col().rowRange(,) = Tc2w.col().rowRange(,)*invMedianDepth;
  14. pKFcur->SetPose(Tc2w);
  15.  
  16. // Scale points
  17. vector<MapPoint*> vpAllMapPoints = pKFini->GetMapPointMatches();
  18. for(size_t iMP=; iMP<vpAllMapPoints.size(); iMP++)
  19. {
  20. if(vpAllMapPoints[iMP])
  21. {
  22. MapPoint* pMP = vpAllMapPoints[iMP];
  23. pMP->SetWorldPos(pMP->GetWorldPos()*invMedianDepth);
  24. }
  25. }

最后和StereoInitialization()中一样,需要更新局部地图,局部关键帧和局部地图点;并且更新LastFrame,LastKeyFrame,以及当前帧的ReferenceKF(上一帧,上一关键帧,参考关键帧)。

这就是单目初始化的大体步骤,其中最关键算法是通过初始连续两帧的对极约束恢复出相机姿态和地图点的部分(Initializer.cpp)留在下一节说。

ORB-SLAM (四)tracking单目初始化的更多相关文章

  1. ORB-SLAM3 细读单目初始化过程(上)

    作者:乔不思 来源:微信公众号|3D视觉工坊(系投稿) 3D视觉精品文章汇总:https://github.com/qxiaofan/awesome-3D-Vision-Papers/ 点击上方&qu ...

  2. ORBSLAM2单目初始化过程

    ORBSLAM2单目初始化过程 转自博客:https://blog.csdn.net/zhubaohua_bupt/article/details/78560966 ORB单目模式的初始化过程可以分为 ...

  3. ORB-SLAM2 论文&代码学习 —— 单目初始化

    转载请注明出处,谢谢 原创作者:Mingrui 原创链接:https://www.cnblogs.com/MingruiYu/p/12358458.html 本文要点: ORB-SLAM2 单目初始化 ...

  4. ORB-SLAM (四)Initializer单目初始化

    一. 通过对极约束并行计算F和H矩阵初始化 VO初始化目的是为了获得准确的帧间相对位姿,并通过三角化恢复出初始地图点.初始化方法要求适用于不同的场景(特别是平面场景),并且不要进行人为的干涉,例如选取 ...

  5. 单目、双目和RGB-D视觉SLAM初始化比较

    无论单目.双目还是RGB-D,首先是将从摄像头或者数据集中读入的图像封装成Frame类型对象: 首先都需要将彩色图像处理成灰度图像,继而将图片封装成帧. (1) 单目 mCurrentFrame = ...

  6. Semantic Monocular SLAM for Highly Dynamic Environments面向高动态环境的语义单目SLAM

    一.摘要 当前单目SLAM系统能够实时稳定地在静态环境中运行,但是由于缺乏明显的动态异常处理能力,在动态场景变化与运动中往往会失败.作者为解决高度动态环境中的问题,提出一种语义单目SLAM架构,结合基 ...

  7. 从零开始一起学习SLAM | 神奇的单应矩阵

    小白最近在看文献时总是碰到一个奇怪的词叫“homography matrix”,查看了翻译,一般都称作“单应矩阵”,更迷糊了.正所谓:“每个字都认识,连在一块却不认识”就是小白的内心独白.查了一下书上 ...

  8. 三角化---深度滤波器---单目稠密重建(高翔slam---十三讲)

    一.三角化 [1]三角化得到空间点的三维信息(深度值) (1)三角化的提出 三角化最早由高斯提出,并应用于测量学中.简单来讲就是:在不同的位置观测同一个三维点P(x, y, z),已知在不同位置处观察 ...

  9. Ubuntu16.04下编译安装及运行单目ORBSLAM2

    官网有源代码和配置教程,地址是 https://github.com/raulmur/ORB_SLAM2 1 安装必要工具 首先,有两个工具是需要提前安装的.即cmake和Git. sudo apt- ...

随机推荐

  1. MySQL学习(二)数据类型

    截取书中内容留作学习.... 1.整数类型 2.浮点数与定点数类型 3.日期时间类型 向数据库中插入当前系统时间:CURRENT_TIME或者NOW() 4.文本字符串类型 MySQL枚举类型:cre ...

  2. OC 成员变量 ( -> 使用 )

    @interface Student : NSObject { // @public // @protected // @private // 默认的作用域是@protected int age; @ ...

  3. bash: ./adb: No such file or directory

    运行adb出现这种错误: bash: ./adb: No such file or directory   但adb确实存在. 可能1.你用的是64位的Linux,没装32位运行时库,安装 $ sud ...

  4. 【luoguP1996】【luogu-original】约瑟夫问题

    先来看题目: P1996 约瑟夫问题 题目背景 约瑟夫是一个无聊的人!!! 题目描述 n个人(n<=100)围成一圈,从第一个人开始报数,数到m的人出列,再由下一个人重新从1开始报数,数到m的人 ...

  5. sql server 中数据库数据导入到另一个库中

    这篇说了sql语句对于备份的数据库进行还原 ,如果数据量大了还是什么问题,发现我的数据丢失了一些,头疼 sql server 备份还原 下面使用的的数据导入来解决这个问题,因为数据量比较大,导出来的脚 ...

  6. js使用hover事件做一个“个人中心”的浮动层

    原材料知识点:hover html: css:

  7. Vue node.js商城-购物车模块

      一.渲染购物车列表页面 新建src/views/Cart.vue获取cartList购物车列表数据就可以在页面中渲染出该用户的购物车列表数据 data(){   return {      car ...

  8. WPF窗口模板——Style样式

    通用模板,窗口样式 <!-- 通用窗口模板 --> <ControlTemplate x:Key="CustomWindowTemplate" TargetTyp ...

  9. group by 注意的细节 ,

    1. GROUP BY子句必须出现在WHERE子句之后,ORDER BY子句之前. HAVING语句必须在ORDER BY子句之后.(where先执行,再groupby分组:groupby先分组,ha ...

  10. Oracle树形结构数据---常见处理情景

    Oracle树形结构数据---常见处理情景 1.查看表数据结构 SELECT *      FROM QIANCODE.TREE_HIS_TABLE T  ORDER BY T.NODE_LEVEL; ...