建图模块

mapping_module在初始化系统的时候进行实例化,在构建实例的时候会实例化local_map_cleaner和local_bundle_adjuster。系统启动的时候会在另外一个线程中启动该模块。

// src/openvslam/system.cc:78
mapper_ = new mapping_module(map_db_, camera_->setup_type_ == camera::setup_type_t::Monocular); // src/openvslam/system.cc:123
mapping_thread_ = std::unique_ptr<std::thread>(new std::thread(&openvslam::mapping_module::run, mapper_));

对新增的关键帧进行建图

// src/openvslam/mapping_module.cc:128
void mapping_module::mapping_with_new_keyframe()
对新增的关键帧进行建图mapping_with_new_keyframe
取出队列中最早放入的关键帧
设置原始关键帧ID
将新关键帧保存入数据库store_new_keyframe
计算当前关键帧的BoW特征向量
获取当前关键帧的lm
如果当前关键帧可以观测到该lm,将lm添加入local_map_cleaner的fresh_landmarks中
否则
添加lm的观测
更新lm几何信息
计算lm的描述子
更新图连接update_connections
获取图关键帧所有lm
统计出共视关键帧以及共视lm数量情况,筛选出共视lm大于15的关键帧weight_covisibility_pairs
寻找出共视lm数量最多的关键帧当做最近的共视关键帧
图中添加连接add_connection
对weight_covisibility_pairs进行降序排列,更新ordered_covisibilities_和ordered_weights_
更新生成树。最近的共视关键帧设置为父树,当前关键帧为子树
存储关键帧
去除冗余的lm(remove_redundant_landmarks)
移除的逻辑
1. observed_ratio小于观测门限,需要从局部地图buffer和数据库中移除;
2. 如果lm被添加之后一段时间内,被观测到的其他帧观测到的次数<=2,则认为时无效帧,需要从局部地图buffer和数据库中移除;
3. 如果lm被添加之后一段时间内被多次观测到,则认为该lm有效,只从局部地图buffer中移除;
依据当前关键帧和共视关键帧重新三角化lm(create_new_landmarks)
获取当前关键帧权重高的共视关键帧
逐个计算当前关键帧与共视关键帧之间的本质矩阵
利用本质矩阵计算出两关键帧lm的匹配情况
三角化匹配的lm,三角化成功的点将添加入库
检测处理重复的lm(update_new_keyframe)
获取两层共视关键帧
融合重复的lm(fuse_landmark_duplication)
获取当前帧的lm
逐个共视关键帧去重(replace_duplication)
如果lm没有被共视关键帧观测到
将lm重投影至该共视关键帧,提取共视关键帧投影区域附近的特征点,如果相似度很高且重投影误差很小,
使用共视关键帧的lm点取代当前的lm,如果共视关键帧没有对应的lm则把当前lm添加到共视关键帧
获取所有共视关键帧的lm集合再次进行去重(replace_duplication)
这里和上面去重输入参数是不一样的,这里的关键帧是当前关键帧,lm是共视关键帧lm集合
更新当前帧lm几何信息和图连接
进行局部地图BA(local_bundle_adjuster)
祛除冗余的关键帧remove_redundant_keyframes
获取当前关键帧的共视关键帧
逐个共视关键帧计算冗余观测count_redundant_observations
获取当前共视关键帧的lm
逐个lm统计其共视关键帧数量,如果不小于3个就认为lm是冗余的num_redundant_obs++
lm深度有效就认为是有效的lm,num_valid_obs++
如果num_redundant_obs / num_valid_obs > 0.9,则认为该共视关键帧是冗余的,移除掉
将新的关键帧发送给全局优化模块队列

观测门限清理

在跟踪模块优化局部地图optimize_current_frame_with_local_map时,首先会统计出当前帧可以被观测到的lm,会调用lm->increase_num_observable(),位姿优化后统计inlier的lm,调用lm->increase_num_observed(),因此num_observed_记录的是跟踪过程中真正有效的lm,num_observable_记录的是局部地图中可以被当前帧观测到的lm,如果num_observed_ / num_observable_的值很小的话,说明该lm对位姿评估没有太大意义,可以从局部地图buffer和数据库中清除掉。

// src/openvslam/tracking_module.cc:340
bool tracking_module::optimize_current_frame_with_local_map()

全局优化模块

和建图模块一样, 全局优化模块global_optimization_module在初始化系统的时候进行实例化,在构建实例的时候会实例化graph_optimizer、loop_detector和loop_bundle_adjuster。系统启动的时候会在另外一个线程中启动该模块。

// src/openvslam/system.cc:80
global_optimizer_ = new global_optimization_module(map_db_, bow_db_, bow_vocab_, camera_->setup_type_ != camera::setup_type_t::Monocular); // src/openvslam/system.cc:124
global_optimization_thread_ = std::unique_ptr<std::thread>(new std::thread(&openvslam::global_optimization_module::run, global_optimizer_));

run
取出队列中最早放入的关键帧
设置标记保证在回环检测和校正期间关键帧不被擦除
将关键帧传入回环检测模块
检测回环候选detect_loop_candidates
回环检测功能被禁用或者刚刚被校正过,则不需要检测回环候选,直接将关键帧添加到bow_db
1. 通过查询BoW数据库来搜索循环候选者
在查询之前,计算当前关键帧和每个共视关键帧之间的BoW相似性的最小分数
获取回环候选acquire_loop_candidates
获取与当前关键帧相连的关键帧集合(通过graph_node)
统计当前关键帧和其他关键帧共享单词数量情况
将最大共享单词数量*0.8作为最小共享单词门限
计算共享单词数满足条件的候选关键帧于当前关键帧的bow得分
挑选出不大于最小分数候选关键帧对儿score_keyfrm_pairs
计算每个候选关键帧(score_keyfrm_pairs)邻域的得分并取总和best_total_score
大于best_total_score*0.75才为有效的候选帧
没有回环候选帧将当前关键帧添加到BoW database
2. 寻找连续关键帧集合find_continuously_detected_keyframe_sets
逐个查看回环候选关键帧
获取相连的关键帧集合
检测与之前连续关键帧集合是否相连,如果相连,添加入当前连续关键帧集合
3. 将连接数大于2的关键帧放入回环候选
4. 保存当前连续关键帧集合以便下次使用
如果当前关键没有找到回环候选,那么当前帧是可以被删除的
验证回环并且从中选出一个validate_candidates
使用线性和非线性的方式评估当前关键帧和候选关键帧的sim3,挑选出回环候选帧
校正回环correct_loop
获取当前关键帧的共视关键帧
获取回环校正前的共视关键帧的Sim3s_nw
计算回环校正后的共视关键帧的Sim3s_nw
校正共视关键帧中的lm的位置信息
校正共视关键帧的位姿信息
处理回环融合带来的重复lm(replace_duplicated_landmarks)
用回环候选关键中的lm替换当前帧中的lm
使用match::fuse检测重复的关键点
获取新的连接关系,进行图优化sim3
优化的变量只有关键帧位姿,优化完成后使用优化的结果调整landmark
添加回环边
最后进行loop BA

问题

  1. 搞清楚线性和非线性sim3;

第五篇 openvslam建图与优化模块梳理的更多相关文章

  1. 前端工程师技能之photoshop巧用系列第五篇——雪碧图

    × 目录 [1]定义 [2]应用场景 [3]合并[4]实现[5]维护 前面的话 前面已经介绍过,描述性图片最终要合并为雪碧图.本文是photoshop巧用系列第五篇——雪碧图 定义 css雪碧图(sp ...

  2. 【bzoj3073】[Pa2011]Journeys 线段树优化建图+堆优化Dijkstra

    题目描述 Seter建造了一个很大的星球,他准备建造N个国家和无数双向道路.N个国家很快建造好了,用1..N编号,但是他发现道路实在太多了,他要一条条建简直是不可能的!于是他以如下方式建造道路:(a, ...

  3. 深入理解javascript作用域系列第五篇——一张图理解执行环境和作用域

    × 目录 [1]图示 [2]概念 [3]说明[4]总结 前面的话 对于执行环境(execution context)和作用域(scope)并不容易区分,甚至很多人认为它们就是一回事,只是高程和犀牛书关 ...

  4. 洛谷 P5471 - [NOI2019] 弹跳(二维线段树优化建图+堆优化存边)

    题面传送门 一道非常有意思的题(大概可以这么形容?) 首先看到这类一个点想一个区域内连边的题目可以很自然地想到线段树优化建图,只不过这道题是二维的,因此需要使用二维线段树优化建图,具体来说,我们外层开 ...

  5. 第五篇:数据备份、pymysql模块

    http://www.cnblogs.com/linhaifeng/articles/7525619.html#_label3 一 IDE工具介绍 生产环境还是推荐使用mysql命令行,但为了方便我们 ...

  6. python、第五篇:数据备份、pymysql模块

    一 IDE工具介绍 生产环境还是推荐使用mysql命令行,但为了方便我们测试,可以使用IDE工具 下载链接:https://pan.baidu.com/s/1bpo5mqj 掌握: #1. 测试+链接 ...

  7. Python自动化 【第五篇】:Python基础-常用模块

    目录 模块介绍 time和datetime模块 random os sys shutil json和pickle shelve xml处理 yaml处理 configparser hashlib re ...

  8. 第六篇 视觉slam中的优化问题梳理及雅克比推导

    优化问题定义以及求解 通用定义 解决问题的开始一定是定义清楚问题.这里引用g2o的定义. \[ \begin{aligned} \mathbf{F}(\mathbf{x})&=\sum_{k\ ...

  9. Python 第五篇(上):算法、自定义模块、系统标准模块(time 、datetime 、random 、OS 、sys 、hashlib 、json和pickle)

    一:算法回顾: 冒泡算法,也叫冒泡排序,其特点如下: 1.比较相邻的元素.如果第一个比第二个大,就交换他们两个. 2.对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对.在这一点,最后的元素应 ...

随机推荐

  1. 7个Python小坑,给新手党的福利

    Python语言简单易用,但容易给新入门的朋友造成一些微妙的,难以捕捉的错误,稍不注意就入坑了. 因此,今天给大家总结一些易犯的小错误,让你轻松进行不踩坑的Python学习. 1.缩进,符号和空格不正 ...

  2. 何为http?何为RPC?

    RPC(即Remote Procedure Call,远程过程调用)和HTTP(HyperText Transfer Protocol,超文本传输协议)他们最本质的区别,就是RPC主要工作在TCP协议 ...

  3. 连续线性空间排序 起泡排序(bubble sort),归并排序(merge sort)

    连续线性空间排序 起泡排序(bubble sort),归并排序(merge sort) 1,起泡排序(bubble sort),大致有三种算法 基本版,全扫描. 提前终止版,如果发现前区里没有发生交换 ...

  4. mybatis与hibernate的区别持久层对比【面试题】

    Mybatis技术特点: 好处: 通过直接编写SQL语句,可以直接对SQL进行性能的优化: 学习门槛低,学习成本低.只要有SQL基础,就可以学习mybatis,而且很容易上手: 由于直接编写SQL语句 ...

  5. 初学JavaScript正则表达式(十)

    前瞻与后顾 断言 === assert 符合断言为正向,不符合为负向 例 'a2*3'.replace(/\w(?=\d)/g,'x') ------- x2*3 看看'\d'前面是不是'\w',如果 ...

  6. 2. Go语言—包概念

    一.包的概念 和python一样,把相同功能的代码放到一个目录,称之为包 包可以被其他包引用(若包中变量/函数被其他包调用,名需大写) main包是用来生成可执行文件,每个程序只有一个main包 包的 ...

  7. day76_10_23自定义签发token,其他drf组件

    一.签发token的原理 当认证类authentication_classes是JSONWebTokenAuthentication时,其父类JSONWebTokenAPIView只有post 方法, ...

  8. 读取只包含标签的xml

    什么是XML XML是可扩展标记语言(Extensible Markup Language)的缩写,其中标记是关键部分.用户可以创建内容,然后使用限定标记标记它,从而使每个单词.短语或块成为可识别.可 ...

  9. [C1] 线性回归(Linear Regression)

    线性回归(Linear Regression with One / Multiple Variable) 定义符号(Symbol Definition) m = 数据集中训练样本的数量 n = 特征的 ...

  10. Python IO 模式

    IO 模式 对于 Linux 的 network IO: 一次 IO 访问(以read举例),数据会先被拷贝到操作系统内核的缓冲区中,然后才会从操作系统内核的缓冲区 copy 到应用程序的地址空间.所 ...