第五篇 openvslam建图与优化模块梳理
建图模块
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
问题
- 搞清楚线性和非线性sim3;
第五篇 openvslam建图与优化模块梳理的更多相关文章
- 前端工程师技能之photoshop巧用系列第五篇——雪碧图
× 目录 [1]定义 [2]应用场景 [3]合并[4]实现[5]维护 前面的话 前面已经介绍过,描述性图片最终要合并为雪碧图.本文是photoshop巧用系列第五篇——雪碧图 定义 css雪碧图(sp ...
- 【bzoj3073】[Pa2011]Journeys 线段树优化建图+堆优化Dijkstra
题目描述 Seter建造了一个很大的星球,他准备建造N个国家和无数双向道路.N个国家很快建造好了,用1..N编号,但是他发现道路实在太多了,他要一条条建简直是不可能的!于是他以如下方式建造道路:(a, ...
- 深入理解javascript作用域系列第五篇——一张图理解执行环境和作用域
× 目录 [1]图示 [2]概念 [3]说明[4]总结 前面的话 对于执行环境(execution context)和作用域(scope)并不容易区分,甚至很多人认为它们就是一回事,只是高程和犀牛书关 ...
- 洛谷 P5471 - [NOI2019] 弹跳(二维线段树优化建图+堆优化存边)
题面传送门 一道非常有意思的题(大概可以这么形容?) 首先看到这类一个点想一个区域内连边的题目可以很自然地想到线段树优化建图,只不过这道题是二维的,因此需要使用二维线段树优化建图,具体来说,我们外层开 ...
- 第五篇:数据备份、pymysql模块
http://www.cnblogs.com/linhaifeng/articles/7525619.html#_label3 一 IDE工具介绍 生产环境还是推荐使用mysql命令行,但为了方便我们 ...
- python、第五篇:数据备份、pymysql模块
一 IDE工具介绍 生产环境还是推荐使用mysql命令行,但为了方便我们测试,可以使用IDE工具 下载链接:https://pan.baidu.com/s/1bpo5mqj 掌握: #1. 测试+链接 ...
- Python自动化 【第五篇】:Python基础-常用模块
目录 模块介绍 time和datetime模块 random os sys shutil json和pickle shelve xml处理 yaml处理 configparser hashlib re ...
- 第六篇 视觉slam中的优化问题梳理及雅克比推导
优化问题定义以及求解 通用定义 解决问题的开始一定是定义清楚问题.这里引用g2o的定义. \[ \begin{aligned} \mathbf{F}(\mathbf{x})&=\sum_{k\ ...
- Python 第五篇(上):算法、自定义模块、系统标准模块(time 、datetime 、random 、OS 、sys 、hashlib 、json和pickle)
一:算法回顾: 冒泡算法,也叫冒泡排序,其特点如下: 1.比较相邻的元素.如果第一个比第二个大,就交换他们两个. 2.对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对.在这一点,最后的元素应 ...
随机推荐
- C#上手练习3(while、do while语句)(添加机器人聊天)
C# while 循环与 for 循环类似,但是 while 循环一般适用于不固定次数的循环. while 循环的语法形式如下. while(布尔表达式){ 语句块;} while 语句执行的过 ...
- go-goroutine 和 channel
goroutine 和 channel goroutine-看一个需求 需求:要求统计 1-9000000000 的数字中,哪些是素数? 分析思路: 1) 传统的方法,就是使用一个循环,循环的判断各个 ...
- concurrent.futures模块简单介绍(线程池,进程池)
一.基类Executor Executor类是ThreadPoolExecutor 和ProcessPoolExecutor 的基类.它为我们提供了如下方法: submit(fn, *args, ** ...
- Java基础—面向对象的三大特性
面向对象有三大特性分别是继承.封装和多态. (1)继承:继承是一种联结类的层次模型,并且允许和鼓励类的重用,它提供了一种明确表述共性的方法.对象的一个新类可以从现有的类中派生,这个过程称为类继承.新类 ...
- 如何在HTML中设置文本的大小写
text-transform属性介绍 text-transform属性就是设置HTML页面中的标签里面的文本大小写,text-transform属性常用的属性值有三种:capitalize.upper ...
- react 地图发布 cesium 篇
上篇文章介绍了如何搭建 react cesium 开发环境.在开发环境下,项目一切运行正常.最近把项目打包发布出来,却遇见了 cesium 不能正确初始化.打开浏览器的调试面板,出现好多 404,资源 ...
- 使用AVFoundation完成照片拍摄存储相册, 开启关闭闪光灯, 切换摄像头
在开启这个旅程之前, 请记住, AVFoundation是一个复杂的工具. 在很多情况下, 我我们使用苹果默认的API(比如:UIImagePickerController)就足够了. 在您阅读之前, ...
- Element-ui中自定义表单校验规则
先看一个场景图: 给一个标签el-tag添加表单的校验,且在内容有了以后关闭校验 看代码: <el-form-item class="baseinfo-tags" label ...
- win10让屏幕壁纸动态变化某文件夹下的图片
首先,请大家在Win10系统中,点击桌面上的“开始菜单”,在开始菜单中,选择“设置”选项,进入Win10系统设置页面. 进入Win10系统设置页面以后,点击页面中的“个性化”选项,进入系统个性化页 ...
- C++ class外的==重载,判断相等,测试等于,重载示例。二元操作符
#include <iostream> // overloading "operator == " outside class // == 是二元操作符 /////// ...