ORB_SLAM2代码阅读(3)——LocalMapping线程

  • 1.说明
  • 2.简介
  • 3.处理关键帧
  • 4. 地图点剔除
  • 5. 创建新的地图点
  • 6.相邻搜索
  • 6.剔除冗余关键帧

1.说明

本文介绍ORB_SLAM2中的LocalMapping线程。相对而言,LoaclMapping线程要比tracking线程简练整洁一些。整体思路比较清晰,没有那么多情况需要讨论。该部分内容中有很多细节部分还没有弄清楚,暂时先将整体思路捋顺,更多细节内容以后再补充。

2.简介

在学习ORB_SLAM2系统的过程中,我们需要紧紧抓住两样东西:帧(关键帧)和地图点,只要把握好这两样东西,就很容易理清整个系统的脉络。而在LoaclMapping线程中,大部分都是对地图点进行处理,只有少部分内容是处理关键帧。

先来看一下LoaclMapping线程的主要思路

  1. 检测在队列中是否存在新的关键帧,如果存在进行局部地图构建。
  2. 处理关键帧。在该过程中,计算关键帧特征点的BoW映射,将关键帧插入地图。
  3. 剔除冗余地图点。该部分内容遍历当前关键帧的所有地图点,对于不满足条件的地图点将其剔除。
  4. 添加新的地图点。相机运动过程中与相邻关键帧可以通过三角化恢复出一些MapPoints。
  5. 如果当前关键帧是关键帧队列中的最后一帧,则进行局部BA,然后剔除冗余关键帧。
  6. 将关键帧加入到回环检测线程。

具体流程如下图:

接下来,从 处理关键帧地图点剔除创建新的地图点局部搜索剔除多余关键帧这5部分分别展开介绍。

3.处理关键帧

处理关键帧这部分内容相当于局部建图线程中的第一步,该步骤主要的操作是:

  1. 从缓冲队列中取出一帧关键帧 。
  2. 计算该关键帧特征点的Bow向量。
  3. tracking线程中局部地图跟踪过程中新匹配上的MapPoints和当前关键帧绑定。
  4. 更新关键帧间的连接关系。
  5. 将该关键帧插入到地图中。

在处理关键帧过程中,有一个问题需要搞清楚(我自己开始理解的不清楚,导致这个问题想了很久)。这个问题是:在获取当前关键帧的地图点之后,为什么还要判断地图点是否在当前关键帧中?

要弄清这个问题还要从tracking线程中的局部地图跟踪过程说起。局部地图跟踪过程中首先将能够观测到当前帧地图点的关键帧及这些关键帧的共视关键帧和父子关键帧作为局部地图跟踪过程中的关键帧,然后将这些关键帧的所有地图点作为局部地图跟踪过程中的地图点。有了关键帧和地图点之后,需要将这些地图点与当前帧的地图点进行投影匹配,然后进行当前帧的位姿优化。这是局部地图跟踪的大致过程。由于局部地图(此处的局部地图是tracking线程中的局部地图)中的地图点与当前帧的地图点进行了投影匹配。所有可以认为当前帧的匹配地图点分为两部分:当前帧自己生成的地图点非当前帧(局部地图中其他关键帧)生成的地图点。而非当前帧生成的地图点未与当前帧进行关联,所以在局部建图线程的关键帧处理部分需要为这些非当前帧(局部地图中其他关键帧)生成的地图点更新属性。

4. 地图点剔除

地图点剔除过程是指剔除局部地图中的某些不合乎要求的地图点。具体来说,要剔除的不合乎要求的地图点是 处理关键帧过程中的 当前帧自己生成的地图点中的一部分。

剔除原则是:

  1. 已经是坏点的MapPoints直接从检查链表中删除
  2. 跟踪到该地图点的Frame数与预计可观测到该地图点的Frame数的比例小于25%,则剔除
  3. 从该点建立开始,到现在已经过了不小于2个关键帧但是观测到该点的关键帧数却不超过cnThObs帧,则剔除
  4. 从建立该点开始,已经过了3个关键帧而没有被剔除,则仅从队列中删除,放弃继续对该MapPoint的检测而不将其设为bad点。

那么问题又来了。既然该部分处理的是 当前帧自己生成的地图点为什么会考虑这些地图点的跟踪情况呢?

原因是:当前帧自己生成的地图点虽然没有在tracking线程的局部地图跟踪过程中进行匹配和跟踪,但是这些地图点在tracking线程中的位姿估计部分进行了匹配跟踪。换句话说:当前帧自己生成的地图点非当前帧(局部地图中其他关键帧)生成的地图点在tracking线程中都进行了匹配跟踪,只是匹配跟踪的方式和时间不同。

5. 创建新的地图点

目前为止,我们知道当前帧地图点分为两部分:当前帧自己生成的地图点非当前帧(局部地图中其他关键帧)生成的地图点。而创建新的地图点则是根据当前关键帧的共视关键帧和当前帧之间的姿态关系,利用三角化的方式恢复出一些地图点。所以经过创建新的地图点之后,当前帧的地图点分为三部分:当前帧自己生成的地图点非当前帧(局部地图中其他关键帧)生成的地图点当前帧与共视帧通过三角化计算出的地图点

该部分内容的大致思路为:

  1. 在当前关键帧的共视关键帧中找到共视程度最高的nn帧相邻帧vpNeighKFs
  2. 遍历相邻关键帧vpNeighKFs
  3. 判断相机运动的基线是不是足够长
  4. 根据两个关键帧的位姿计算它们之间的基本矩阵。
  5. 通过极线约束限制匹配时的搜索范围,进行特征点匹配
  6. 对每对匹配通过三角化生成3D点。

具体流程:

这部分的代码,注释的较为详细,以后再上传。

6.相邻搜索

如果当前关键帧是待处理关键帧队列中的最后一帧。则经过创建新的地图点之后要进行相邻搜索。相邻搜索的主要目的是检查并融合当前关键帧与相邻帧(两级相邻)重复的MapPoints。在经过上面几步的处理之后,地图点必然存在冗余,所以需要在此处进行冗余去除。

相邻搜索的主要思路为:

  1. 获得当前关键帧在covisibility图中权重排名前nn的邻接关键帧,找到当前帧一级相邻与二级相邻关键帧并将其存入vpTargetKFs中。
    这里提到的一级相邻关键帧指:与当前关键帧共视程度最高的nn个相邻关键帧,二级相邻关键帧指:与一级相邻关键帧共视程度最高的5个相邻关键帧。
  2. 将当前帧的MapPoints分别与一级二级相邻帧(的MapPoints)进行融合。
    投影当前帧的MapPoints到相邻关键帧pKFi中,并判断是否有重复的MapPoints。如果MapPoint能匹配关键帧的特征点,并且该点有对应的MapPoint,那么将两个MapPoint合并(选择观测数多的);如果MapPoint能匹配关键帧的特征点,并且该点没有对应的MapPoint,那么为该点添加MapPoint。
  3. 将一级二级相邻帧的所有有效的MapPoints分别与当前帧(的MapPoints)进行融合。
  4. 更新当前帧MapPoints的描述子,深度,观测主方向等属性。
  5. 更新covisibility图。

具体步骤如图:

6.剔除冗余关键帧

如果已经处理完队列中的最后的一个关键帧,并且闭环检测没有请求停止LocalMapping。则进行局部BA,然后剔除冗余关键帧。在此处先不说局部BA(后面单独说),只介绍一下剔除冗余关键帧操作。

剔除冗余关键帧的操作比较简单。其主要思想是:过去当前关键帧的所有共视关键帧。如果这些共视关键帧中的某一帧的地图点有90%能被至少3个关键帧观测到,则认为该帧是冗余的,需要将其设置为bad。

做完这些操作后,便可以将当前帧加入到闭环检测队列中进行闭环检测。


局部建图的过程就介绍到这里,相对来说内容比较少。

ORB_SLAM2代码阅读(3)——LocalMapping线程相关推荐

  1. ORB_SLAM2代码阅读(4)——LoopClosing线程

    ORB_SLAM2代码阅读(4)--LoopClosing线程 1.说明 2.简介 3.检测回环 4.计算Sim3 4.1 为什么在进行回环检测的时候需要计算相似变换矩阵,而不是等距变换? 4.2 累 ...

  2. ORB_SLAM2代码阅读(2)——tracking线程

    ORB_SLAM2代码阅读(2)--Tracking线程 1. 说明 2. 简介 2.1 Tracking 流程 2.2 Tracking 线程的二三四 2.2.1 Tracking 线程的二种模式 ...

  3. ORB_SLAM2代码阅读(5)——Bundle Adjustment

    ORB_SLAM2代码阅读(5)--Bundle Adjustment 1. 说明 2. Bundle Adjustment(BA)的物理意义 3. BA的数学表达 4. BA的求解方法 4.1 最速 ...

  4. ORB_SLAM2代码阅读(1)——系统入口

    ORB_SLAM2代码阅读(1)--系统简介 1.说明 2.简介 3.stereo_kitti.cc 4.SLAM系统文件(System.cc) 4.1 构造函数System() 4.2 TrackS ...

  5. ORB_SLAM2代码阅读及总结使用(二)

    把建图系统分为了三个节点,如下所示. 第一个节点作为驱动节点,采集摄像头传感器的数据. 第二个节点利用ORB_SLAM主要做姿态估计,提供Tcw 第三个节点作为见图节点,收集第一和第二节点的建图节点接 ...

  6. GLIBC中NPTL线程实现代码阅读

    项目的性能测试告一段落,暂时松了一口气.但是也发现很多知识的盲点,也许这就是所谓的知道的越多,不知道的也越多.  现在所有的程序基本上都是用多线程来实现的,尤其是Unix/Linux server程序 ...

  7. ORB-SLAM2代码阅读笔记(五):Tracking线程3——Track函数中单目相机初始化

    Table of Contents 1.特征点匹配相关理论简介 2.ORB-SLAM2中特征匹配代码分析 (1)Tracking线程中的状态机 (2)单目相机初始化函数MonocularInitial ...

  8. 谈谈技术原则,技术学习方法,代码阅读及其它

    一.选用技术的原则 比较规范的软件开发过程要到有限的几个公司才能学到.偶现在所采用的方法都是圡方法,主程序员,测试驱动,文档和代码写在一起,原型.但基本上坚持几个原则: 在工作上以实用为主导,哪个实用 ...

  9. 谈谈技术原则,技术学习方法,代码阅读及其他的(引用)

    这篇文章是前一阵在水木BBS上和别人讨论中偶自己发言的摘编,是偶这几年开发过程完全经验式的总结.完全个人经验,供批判. 一.选用技术的原则 比较规范的软件开发过程要到有限的几个公司才能学到.偶现在所采 ...

最新文章

  1. JavaScript初学者编程题(24)
  2. CVPR 2021 | 记录SCRFD人脸检测C++工程化(含docker镜像)
  3. Linux 交换eth0和eth1
  4. myeclipse创建java错误提示_myeclipse 遇到的一些问题及解决方案
  5. 做百度AI工程师,还要会“相牛”?
  6. MySQL索引介绍,普通索引,全文索引,空间索引,多列索引使用原则,建立索引常用的规则
  7. wine最小化游戏后无法恢复的问题
  8. 数学--数论--HDU-2698 Maximum Multiple(规律)
  9. linuxliveu盘怎么用_linux mint 12 U盘(live usb)安装及体验
  10. Matlab信息加密解密系统
  11. 华南理工大学 电力电子技术(王兆安) 期末复习笔记2 第三章第四章
  12. matlab冲激函数的傅里叶变换,信号与系统课件14.ppt
  13. 概要、详细设计文档内容简述
  14. VBA读excel写xml
  15. O(lgn)计算斐波那契数
  16. 联想thinkpad E430C硬盘位换为固态,硬盘放于光驱位(win7+win10+ubuntu三系统安装教程)
  17. 深入理解操作系统实验——bomb lab(phase_4)
  18. 怎样降低计算机屏幕亮度,如何调低电脑屏幕亮度【解决步骤】
  19. 从无到有完整搭建lnmp+redis+memcache+gearmand网站
  20. (JAVA编程练习):输入某年某月某日,判断这一天是这一年的第几天?

热门文章

  1. 2022-2028年中国TAC薄膜行业市场全景评估及投资前景规划报告
  2. debian10 raid5+lvm
  3. 软件工程——视频总结
  4. 【C#】集合_哈希表_字典_泛型_文件
  5. LeetCode简单题之判断矩阵经轮转后是否一致
  6. 容器云原生DevOps学习笔记——第三期:从零搭建CI/CD系统标准化交付流程
  7. Tomcat 1099端口占用重启无效,查不到进程,改换端口无效解决方案
  8. Pipe Utilization管道利用率
  9. 使用Keil语言的嵌入式C编程教程(下)
  10. workerman的基本用法