orbSLAM2之 局部建图(LocalMapping)线程

ORBSLAM2系列-LocalMapping局部建图线程 到此整个LocalMapping线程就结束了,其中主要就是对局部地图进行了优化,并添加了新的地图点,这个线程中处理的都是关键帧。每个关键帧经过处理后,最后会放入链表中,用于LoopClosing闭环检测线程使用。 阅读详情

概述

该线程的入口是LocalMapping::Run()函数,执行其无限while循环。
下面介绍while循环体一次循环执行的操作。
1,设置LocalMaping类的成员mbAcceptKeyFrames为false,表示不接受Tracking线程创建新关键帧
2,检查成员mlNewKeyFrames中是否有新关键帧。mlNewKeyFrames保存所有Tracking线程创建新关键帧。
3,如果mlNewKeyFrames为空,则检查是否有外部操作要求终止该线程,有的话终止,没有的话休眠3毫秒后进行下一次循环。
4,如果mlNewKeyFrames不为空,则在本次循环中处理一帧新关键帧并进行一系列相关操作,再执行3,退出或进入下一次循环。
如何处理mlNewKeyFrames中的一帧新关键帧是关键,下面详细介绍。

新关键帧处理及相关操作

1,处理新关键帧ProcessNewKeyFrame();

1,将mlNewKeyFrames中的首元素赋值给mpCurrentKeyFrame。mpCurrentKeyFrame即是我们接下来要处理的新关键帧。

2,计算mpCurrentKeyFrame的BoWVector和FeatureVector

3,在生成mpCurrentKeyFrame的普通帧mpCurrentFrame追踪的那些地图点中添加对mpCurrentKeyFrame的记录。在tracking线程中,我们只在mpCurrentFrame中添加了其匹配到的地图点的记录,没有在这些地图点中添加对mpCurrentFrame的记录,因为地图点只保存对关键帧的记录。现在我们要在这些地图点中添加对mpCurrentKeyFrame的记录

4,将mpCurrentKeyFrame新创建的地图点添加到mlpRecentAddedMapPoints。在Tracking线程生成关键帧时,我们会将该关键帧【未匹配的特征点】或【已匹配了地图点,但是匹配的地图点的nObs<1的特征点】生成新的地图点(若为单目相机或为双目/RGBD的单目特征点此时生成的地图点的3d坐标为空)。这些新地图点在生成时添加了对mpCurrentKeyFrame的记录。mlpRecentAddedMapPoints是LocalMapping保存新生成的地图点的数据成员,通过对此成员的操作,确定哪些地图点能够最终保留下来

5,根据mpCurrentKeyFrame->mvpMapPoints更新mpCurrentKeyFrame的mConnectedKeyFrameWeights、mvpOrderedConnectedKeyFrames、mvOrderedWeights、mpParent等参数

6,将关键帧添加到地图(Map)中

2,地图点剪裁MapPointCulling();

1,测试mlpRecentAddedMapPoints中的地图点
2,对于不能通过测试的地图点,从mlpRecentAddedMapPoints删除,设置本地图点mbBad=true,并在所有特征帧以及地图中删除对本地图点的记录,但不删除本地图点。
3,遍历mlpRecentAddedMapPoints中的地图点,若某个地图点满足下面三个条件之一,则未能通过测试。

1,地图点mbBad=true 
2,地图点的 mnFound/mnVisible < 0.25,(即追踪局部地图的 优化内点次数/投影成功次数    <0.25)    
 3,在地图点创建后的第2、3个关键帧要被处理时,地图点的nObs<=设定值cnThObs

若某个地图点在不满足上面三个条件,且 满足:

地图点创建后的第3个关键帧要被处理时,地图点还在mlpRecentAddedMapPoints中

则将该地图点从mlpRecentAddedMapPoints删除,地图点通过测试

3,创建新地图点CreateNewMapPoints();

将mpCurrentKeyFrame中未匹配的地图点与其前nn(单目nn=20,双目RGBDnn=10)共视关键帧中还未匹配地图点进行匹配(BoW加速)、三角化,进而创建新地图点.
1,将mpCurrentKeyFrame的前nn个共视权重最大的共视关键帧保存到vpNeighKFs

2,如果mlNewKeyFrames中还有待处理关键帧,那么只用与mpCurrentKeyFrame共视最多的关键帧pKF2生成新地图点。反之,用所有vpNeighKFs中的共视关键帧pKF2生成新地图点,依次来提高处理速度。

3,通过光心距离判断pKF2是否可用来与mpCurrentKeyFrame三角化。
计算pKF2和mpCurrentKeyFrame的光心距离
如果是双目/RGBD,只有当光心间距大于双目/RGBD基线时,pKF2可用
如果是单目,只有当 光心间距/[共视帧帧观测到的地图点的深度值中位数] >= 0.01时,pKF2可用

4,计算mpCurrentKeyFrame和pKF2之间的基础矩阵F12

5,通过 matcher.SearchForTriangulation(mpCurrentKeyFrame,pKF2,F12,vMatchedIndices,false)匹配mpCurrentKeyFrame和*pKF2中还未匹配地图点的特征点,保存到vMatchedIndices。
关于函数SearchForTriangulation:

//匹配pKF1和*pKF2中还未匹配地图点的特征点,保存到vMatchedPairs(<在pKF1的特征点的索引,匹配的pKF2中的点的索引>),返回匹配数
//如果bOnlyStereo=true(缺省为false),则只对Stereo特征点尝试匹配
//通过BoW加速匹配:只对有相同NodeId的特征点尝试匹配
//匹配过程:对pKF1中的每一个特征idx1,与pKF2的同一NodeId的每一个特征计算描述子距离,选择其中最距离最小的特征bestIdx2,然后进行一下检查:
//          1,如果idx1和bestIdx2都是单目特征点,要检查角:光心1-地图点-光心2是否满足,以控制三角化误差 
//          2,通过基础矩阵判断两个特征点是否满足对极约束
//          3,如果mbCheckOrientation=true还要近性方向一致性检查(mbCheckOrientation在此类构造时初始化)
int ORBmatcher::SearchForTriangulation(KeyFrame *pKF1, KeyFrame *pKF2, cv::Mat F12,
                                       vector<pair<size_t, size_t> > &vMatchedPairs, const bool bOnlyStereo)
~~~s

6,根据不同情况分别采用以下3种方法之一进行计算vMatchedIndices中匹配特征对对应的3d坐标。
~~~s
1,用三角化计算新地图点的3d坐标
2,用mpCurrentKeyFrame中的3d坐标作为新地图点的3d坐标
3,用pKF2中的3d坐标作为新地图点的3d坐标

7,通过以下条件检查上一步中计算的3d坐标是否满足精度

1,检查在两帧中深度是否为正
2,检查在两帧中的重投影误差是否
		<=5.991*sigmaSquare2(对于单目特征点)
		<=7.8*sigmaSquare2(对于双目特征点)
		sigmaSquare2是特征点在该帧所在的金字塔尺度的平方
3,检查尺度(比)的一致性
		即地图点到两光心的距离之比和特征点在两帧上的所在的金字塔尺度之比是否接近

8,为通过第7步检查的3d坐标,生成地图点。
在mpCurrentKeyFrame和pKF2中添加对新地图点的观测
在新地图点中添加对mpCurrentKeyFrame和pKF2的记录
计算新地图点的描述子,更新其mfMaxDistance, mfMinDistance, mNormalVector等参数
将地图点添加到Map和LocalMap的mlpRecentAddedMapPoints中

4,地图点融合SearchInNeighbors();

若mlNewKeyFrames为空才进行地图点融合,以此减少计算量。

SearchInNeighbors()函数:匹配 mpCurrentKeyFrame和[共视帧以及共视帧的共视帧]之间的地图点和特征,融合有关地图点(不生成新地图点),更新mpCurrentKeyFrame的共视信息

5,LocalBA

LocalBA不是必然会进行的。只有当mlNewKeyFrames为空且没有外部操作终止本线程,并且地图中的关键帧数>2时才进行。
Optimizer::LocalBundleAdjustment(mpCurrentKeyFrame,&mbAbortBA, mpMap);

//参与优化的帧(非Fixed):pKF及其权重>15的关键帧
//参与优化的地图点:非Fixed帧匹配的所有地图点
//参与优化的帧(Fixed):参与优化的地图点的所有观测帧(除了非Fixed的帧)
//初步优化,然后根据pbStopFlag判断是否进行二次优化
//二次优化,设置初步优化后残差过大或地图点深度为负的边不再优化,取消所有边的核函数的边不再优化,进行二次优化
//将二次优化后残差过大或地图点深度为负的边涉及的关键帧和地图点,取消对彼此的记录
//保存优化结果,对优化涉及的所有关键帧和地图点都更新为优化结果
void Optimizer::LocalBundleAdjustment(KeyFrame *pKF, bool* pbStopFlag, Map* pMap)

6,关键帧剪裁 KeyFrameCulling();

//冗余的关键帧的删除
//待检查关键帧:mpCurrentKeyFrame的共视关键帧(权重>15)
//对待检查关键帧中的每一帧pKF检查是否满足:nRedundantObservations>0.9*nMPs,若满足则该帧冗余。
//      nRedundantObservations —— 冗余观测数:对于双目/RGBD相机,是[在pKF中为近stereo地图点]且[在任意其他3个关键帧中有尺度满足(质量好)的观测]的地图点数
//                                              对于单目相机,是在任意其他3个关键帧中有尺度满足(质量好)的观测]的地图点数
//      nMPs                   —— 观测数:     对于双目/RGBD相机,是[在pKF中为近stereo地图点]
//                                               对于单目相机,是观测地图点数
/对于冗余的关键帧,设置其为坏帧(mbBad = true),删除其他帧、地图点、地图对于该帧的记录,但不删除该帧

KeyFrameCulling();

7,向闭环检测线程添加一个新的关键帧

mpLoopCloser->InsertKeyFrame(mpCurrentKeyFrame);
ORB-SLAM2局部建图线程 ORB SLAM2 Localmapping线程 阅读详情

相关推荐

orbslam2的LocalMapping线程(1)

LocalMapping()

batmanShu的博客 439

ORB-SLAM3 LocalMapping类源码分析(一)

2021SC@SDUSC

qq_53377744的博客 700

ORBSLAM2总结之-LocalMapping.cpp

/** * @file LocalMapping.cc * @author guoqing (1337841346@qq.com) * @brief 局部建图线程 * @version 0.1 * @date 2019-04-29 * * @copyright Copyright (c) 2019 * */ /** * This file is part of ORB-SLAM2. * * Copyright (C) 2014-2016 Raúl Mur-Artal <raul

joun772的博客 396

orbslam2稠密版建图

slam

darren_pty 8448

ORB-SLAM2项目实战(3) — ORB-SLAM2稠密地图重建

文章参考部分开源代码和报错文章。

几度春风里的博客 1万+

即梦文生视频逆向接口部署使用

有的小伙伴不知道这个地址如何填写,你可以理解是步骤3上提供的 服务器或者本地电脑IP 地址(不要写 http://127.0.0.1 或者http://localhsot ) 是 (192.168.XXX.XXX 参考)

weixin_44245188的博客 3183

【ORB-SLAM2代码】(二)建图

mDescriptor属性 ComputeDistinctiveDescriptors() 由于一个MapPoint会被许多相机观测到,因此在插入关键帧后,需要判断是否更新当前点的最适合的描述子. 先获得当前点的所有描述子,然后计算描述子之间的两两距离,最好的描述子与其他描述子应该具有最小的距离中值 Visible属性表示: * 1. 该MapPoint在某些帧的视野范围内,通过Fram...

陋室逢雨 7221

嵌入式存储实战:FAL+SFUD+flashDB三件套在STM32上的完整移植指南(附避坑技巧)

本文提供了一套在STM32上完整移植FAL、SFUD与flashDB嵌入式存储框架的实战指南。详细解析了从SPI驱动配置、SFUD设备识别、FAL抽象层分区到flashDB键值数据库初始化的全流程,并分享了关键的避坑技巧与性能优化建议,帮助开发者构建稳定可靠的嵌入式存储系统。

rnn9storyteller的博客 1013

orbslam2代码解读(3):localmapping局部建图线程

这个localmapping局部建图线程还是比较简单的,就是处理关键帧,处理完毕就执行一个局部BA的优化。最后给回环线程留了一个队列,用于检测是否有回环。

Son_of_the_Bronx的博客 1205

对LSTM中每个batch都初始化隐含层的理解

不知道有没有人和我有一样疑惑 在LSTM相关的代码中,为什么每个batch都会将隐藏层重新初始化, 这样不会把以前训练出来的参数丢掉吗?? 比如 代码来自GitHub 看了一些解释是h与c是状态,不是参数,每个batch中都需要初始化为0,LSTM 中的参数是W,b。 网络中训练的是参数,不是状态。 说真的。。。当时我没怎么看懂。。。 咨询了实验室的师兄后,我有了自己的理解 产生误解的主要原因是我对RNN和LSTM的结构理解不深入,我们通常看到RNN结构图基本都是这样的 ...

Chauncey_Wang的博客 5910

红外弱小目标检测:IPI算法解读及MATLAB复现

参考文献:[1]C. Gaoet al., “Infrared Patch-Image Model for Small Target Detection in a Single Image,” vol. 22, no. 12, pp. 4996–5009, 2013. 本文整理????论文笔记,并附MATLAB实现代码。 一、阅读笔记 1. 摘要 IPI算法是单帧检测算法; 利用背景的非局部子相关性(non-local self-correlation ofbackground),将目标检测转..

小草莓的魔法笔记 1万+

读懂ORBSLAM2——LocalMapping线程

流程图 LocalMapping线程负责对新加入的KeyFrames和MapPoints筛选融合,剔除冗余的KeyFrames和MapPoints,维护稳定的KeyFrame集合,传给后续的LoopClosing线程。 主要的功能点在: 处理新的关键帧ProcessNewKeyFrame() 剔除不合格地图点MapPointCulling() 三角化恢复新地图点CreateNewMapPoint...

xiaohu的博客 2031

STM32实战:如何用GPS信号同时同步海康摄像头和Livox Mid-360雷达(附完整接线图)

本文详细介绍了如何利用STM32实现GPS信号分频,同步海康摄像头和Livox Mid-360雷达的时间同步方案。通过硬件架构设计、STM32信号处理核心实现及设备接口规范,解决了多传感器数据融合中的时间对齐难题,适用于自动驾驶和机器人导航领域。

weixin_29182481的博客 595

图解ORBSLAM2流程

这篇博文主要是梳理ORBSLAM2的流程,对于细节暂时不会很详细的描述(之后的博文会深究细节),且本博文暂时只描述ORBSLAM2中的Monocular(单目)情况。 在ORBSLAM2中,主要的三个线程是Tracking、LocalMapping、LoopClosing。三个线程的创建都是在System.cpp中,也就是在System类中的构造函数中创建了这三个线程。 以mono_tum.c...

zzpzm的博客 4881

教你如何阅读Autosar代码(6):常量变量定义

编译器抽象应该为常量的声明和定义定义CONST宏。编译器抽象应该定义VAR宏来声明和定义变量。memclass:常量本身的分类;memclass:变量本身的分类;vartype:变量的类型;type:常量的类型;

wdconan001的博客 958

机器人动力学仿真软件:Webots_(14).机器人声音仿真

Webots 中的声音仿真主要通过Sound和两种节点来实现。Sound节点用于播放预定义的音频文件,而节点则允许在仿真过程中动态生成和播放声音。这些节点可以用于模拟机器人的语音输出、报警声、环境噪音等。以下是一个示例,展示如何在控制器代码中播放预定义的声音。// 控制器代码(.c) # include <webots/robot.h> # include <webots/sound.h> # define TIME_STEP 64 const char * sound_name = "sound";

kkchenjj的博客 1310

ORBSLAM2总结之-LocalMapping线程

前言 本文结合其余的ORBSLAM2的资料,对ORBLSAM2源码进行注释,感谢知识星球、泡泡机器人感谢吴博! 源码是知识星球小六等人的带注释版本。 LocalMapping线程主要用来处理从Tracking线程传过来的关键帧。 个人理解是: Tracking线程只要是完成对当前帧的追踪,以及这个帧的地图点相关信息之类的。 在LocalMapping中只要就是处理这个新的关键帧。 注意:处理新的关键帧是在缓冲队列中处理,处理完了后,要从缓存队列中删掉。 LocalMapping主要流程如下图所示: 上面的

joun772的博客 453

《谷歌数据分析方法》脑图笔记

目录壹、脑图笔记贰、《谷歌数据分析方法》脑图文稿[^1]一、 反思数据分析二、选择数据分析工具的最佳策略第一步:选择数据分析工具前要回答的3个关键问题第二步:选择数据分析工具前要问供应商的10个问题第三步:如何有效地试用数据分析工具第四步:确定合作前的协议,检查供应商的服务条款三、点击流分析的精彩世界:指标8个关键网站指标数据分析指标揭秘关键网站指标的战略性策略四、成功的关键:衡量绩效关注“少数关键指标”衡量非电子商务网站的成功衡量B2B网站五、调研和测试永不过时的3个最佳调研问题选择线上调研供应商的8个建

积跬步,慕至千里的博客 2925

ORB-SLAM2中LocalMapping线程主要流程梳理

一、LocalMapping线程简述 在ORB-SLAM2当中,LocalMapping作为一个线程在系统启动后就一直在运行,只是在Tracking线程“生产出”新的关键帧并插入到LocalMapping线程中的mlNewKeyFrames列表后,LocalMapping线程检测到该列表中有关键帧后开始处理这些新插入的关键帧(CheckNewKeyFrames函数用来检测mlNewKeyFram...

1365

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

ssm框架搭建

这个是一个在idea上成功跑起来的ssm框架项目,保存在这里方便以后使用直接下载

ORBSLAM2之LocalMapping线程

目录LocalMapping线程概述一、 处理新关键帧ProcessNewKeyFrame()二、 剔除质量不好的MapPoint MapPointCulling()三、 三角化创建新MapPoint CreateNewMapPoints()四、 MapPoint融合五、局部BA六、删除冗余关键帧KeyFrameCulling()七、将当前关键帧插入闭环检测队列 LocalMapping线程概述   此线程主要用于处理Tracking线程发来的关键帧,更新关键帧和MapPoint之间的关系,对M

qq_37340588的博客 545

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

【代码阅读】ORBSLAM2

ORBSLAM2源代码阅读记录,根据程序运行顺序整理了代码的实现细节

博客标题不能为空我也没办法 1760

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

一起学ORBSLAM2(11)ORBSLAM的localmapping

转载请注明原创地址:https://blog.youkuaiyun.com/qq_30356613/article/category/6897125ORBSLAM的局部建图线程实际做的工作是来维护全局map以及管理关键帧的,对tracking得到的关键帧进行筛选融合,以及对关键帧中的地图点进行融合,剔除冗余的关键帧和地图点,维护一个稳定的全局map,并将筛选后的关键帧提供给回环检测使用。局部建图线程主函数流程...

蚁族的坚持的博客 3804

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

@TOC

Mr.Andy的博客 2020

ORBSlam2学习研究(Code analysis)-ORBSlam2中的视觉里程计LocalMapping

LocalMapping线程介绍ORBSlam2中的视觉里程计VO不仅仅包含Tracking线程,LocalMapping也是VO中的一部分。

Xuefeng_BUPT的博客 5980

ORBSLAM的LocalMapping模块和Tracking模块的接口讲解

摘要:ORB-SLAM中Tracking线程与LocalMapping线程通过关键帧队列实现交互。当Tracking线程检测到需要新增关键帧时,会调用InsertKeyFrame()将其推入mvpNewKeyFrames队列,并设置mbAbortBA标志中断当前优化。LocalMapping线程通过3ms间隔的忙等机制检查队列状态,处理新关键帧时执行地图点更新、剔除、创建及局部优化等操作。整个过程采用生产者-消费者模式,但没有使用条件变量,而是通过队列检测和定时休眠实现线程唤醒。

weixin_43851636的博客 391
上一篇: ubuntu18.04系统双显卡笔记本安装nvidia-driver、cuda(toolkit)、cuDNN、pytorch
下一篇: SLAM系统发展
isErik
博客等级 码龄9年 38粉丝 54原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值