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

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

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

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

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

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

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

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

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

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

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

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

2. 该MapPoint的描述子;

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

for(size_t i=; i<mvIniMatches.size();i++)
{
if(mvIniMatches[i]<)
continue;
//Create MapPoint from mvIniP3D
cv::Mat worldPos(mvIniP3D[i]);
MapPoint* pMP = new MapPoint(worldPos,pKFcur,mpMap);
pKFini->AddMapPoint(pMP,i);
pKFcur->AddMapPoint(pMP,mvIniMatches[i]);
pMP->AddObservation(pKFini,i);
pMP->AddObservation(pKFcur,mvIniMatches[i]);
pMP->ComputeDistinctiveDescriptors();
pMP->UpdateNormalAndDepth();
mCurrentFrame.mvpMapPoints[mvIniMatches[i]] = pMP;
mCurrentFrame.mvbOutlier[mvIniMatches[i]] = false;
mpMap->AddMapPoint(pMP);
}

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

pKFini->UpdateConnections();
pKFcur->UpdateConnections();

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

Optimizer::GlobalBundleAdjustemnt(mpMap,);

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

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

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

    float medianDepth = pKFini->ComputeSceneMedianDepth();
float invMedianDepth = 1.0f/medianDepth; if(medianDepth< || pKFcur->TrackedMapPoints()<)
{
cout << "Wrong initialization, reseting..." << endl;
Reset();
return;
} // Scale current pose
cv::Mat Tc2w = pKFcur->GetPose();
Tc2w.col().rowRange(,) = Tc2w.col().rowRange(,)*invMedianDepth;
pKFcur->SetPose(Tc2w); // Scale points
vector<MapPoint*> vpAllMapPoints = pKFini->GetMapPointMatches();
for(size_t iMP=; iMP<vpAllMapPoints.size(); iMP++)
{
if(vpAllMapPoints[iMP])
{
MapPoint* pMP = vpAllMapPoints[iMP];
pMP->SetWorldPos(pMP->GetWorldPos()*invMedianDepth);
}
}

最后和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. 大整数乘法(POJ2389)

    题目链接:http://poj.org/problem?id=2389 #include <stdio.h> #include <string.h> #define Max 1 ...

  2. 郑州集训Day4 [小Cat与小鲜肉]

    考试的时候由于没有想出这道题就弃疗了 发现主要还是自己姿势不够 [问题描述] \(P\) 校某宿舍人才辈出,其舍长图书馆男神因被偷拍侧身照而在网络上一票走红. 小鲜肉 \(SJY\) 是小 \(Cat ...

  3. 2017.9.11 初入HTML学习

          第二章 静态网页开发技术 静态网页是指可以由浏览器解释执行而生成的网页,HTML是一组标签,负责网页的基本表现形式: JavaScript是在客户端浏览器运行的语言,负责在客户端与用户的互 ...

  4. table自适应

    当table大于屏幕时,table可以左右滑动 //给table的父元素设置样式 .edit_table{ width:100%; overflow: auto; }

  5. servlet三种方式实现servlet接口

    简单介绍 Servlet接口实现类 1.Servlet接口SUN公司定义了两个默认实现类,分别为:GenericServlet.HttpServlet. 2.HttpServlet指能够处理HTTP请 ...

  6. 【洛谷P1288】取数游戏II

    取数游戏II 题目链接 显然,由于一定有一个0,我们可以求出从初始点到0的链的长度 若有一条链长为奇数,则先手可以每次取完一条边上所有的数, 后手只能取另一条边的数,先手必胜: 反之若没有奇数链,后手 ...

  7. 【luogu P2947 [USACO09MAR]向右看齐Look Up】 题解

    题目链接:https://www.luogu.org/problemnew/show/P2947 因为在单调队列上被dalao们锤爆 怒刷单调队列题 何为单调队列? 设我们的队列为从左至右单调递增 对 ...

  8. Android学习笔记_36_ListView数据异步加载与AsyncTask

    一.界面布局文件: 1.加入sdcard写入和网络权限: <!-- 访问internet权限 --> <uses-permission android:name="andr ...

  9. chsh 设置用户禁止登陆

    chsh username -s /sbin/nologin ##禁止登陆 chsh username -s /bin/bash ##允许登陆

  10. jquery mobile 移动web(5)

    有序列表 <div data-role="content"> <ol data-role="listview" data-theme=&quo ...