ORB-SLAM中优化使用g2o库,先复习一下g2o的用法,上类图

其中SparseOptimizer就是我们需要维护的优化求解器,他是一个优化图,也是一个超图(包含若干顶点和一元二元多元边),怎样定义图的顶点(优化变量_estimate)和边(误差项_error)是用户需要考虑的问题,可以从g2o/types查找是否已经有定义好的顶点或边,若没有,需要自己去实现。

自己实现的时候注意,基本都是去继承BaseVertex<D,T>; BaseUnaryEdge<D,E,VertexXi>...这几个模板类,根据需要实现(override)虚函数.

  • virtual void setToOriginImpl() 设定优化变量0点 _estimate = 0 ;
  • virtual void oplusImpl(const double* v)实现优化变量的增量计算,特别是优化变量不在欧式空间中,没有的"+"定义时。例如李代数中,需要使用左乘或者右乘定义而不是直接的加法;
  • void computeError() 计算估计值和测量值之间的误差项_error
  • virtual void linearizeOplus() 计算雅可比的解析形式_jacobianOplus[i],每一个雅可比的类型为MatrixX::MapType, 参考Eigen::Map类 https://eigen.tuxfamily.org/dox/classEigen_1_1Map.html,可以认为是将一块内存数据构造成一个矩阵,比较灵活地适应相对各个优化变量的雅可比形式。

这张类图的下半部分就是我们初始化优化求解器时需要指定的求解方法。

求解的梯度下降算法可以选择GN,LM(最常用),或者DogLeg;

算法求解器还包括两部分,

  • 计算目标函数雅可比和海塞(或者近似的海塞),以及执行Schur complement的BlockSolver,需要指定优化变量的维度,常见的有

    •   //variable size solver
      using BlockSolverX = BlockSolverPL<Eigen::Dynamic, Eigen::Dynamic>; // solver for BA/3D SLAM
      using BlockSolver_6_3 = BlockSolverPL<, >; // solver fo BA with scale
      using BlockSolver_7_3 = BlockSolverPL<, >; // 2Dof landmarks 3Dof poses
      using BlockSolver_3_2 = BlockSolverPL<, >;

      可以设置为动态的BlockSolverX

  • 求解线性方程组 Hx = b (linear problem constructed from _jacobianOplus and _error)的线性求解器,完全采用第三方的线性代数库,主要采用Cholesky分解和PCG迭代,具体可以选择的有
    • Cholmod,CSparse (以上两者为比较著名的线性代数库),
    • PCG (pre-conditioner is block Jacobi),
    • Dense(dense Cholesky decomposition),
    • 或者ORB-SLAM中使用的Eigen(sparse Cholesky decoposition from Eigen)。

因此,ORB-SLAM中优化求解器初始化过程如下:

g2o::SparseOptimizer optimizer;
g2o::BlockSolver_6_3::LinearSolverType * linearSolver;
// 线性方程求解器
linearSolver = new g2o::LinearSolverEigen<g2o::BlockSolver_6_3::PoseMatrixType>();
// 稀疏矩阵块求解器
g2o::BlockSolver_6_3 * solver_ptr = new g2o::BlockSolver_6_3(linearSolver);
// 梯度下降算法
g2o::OptimizationAlgorithmLevenberg* solver = new g2o::OptimizationAlgorithmLevenberg(solver_ptr);
optimizer.setAlgorithm(solver);

ORB中使用的这些优化函数是非常重要的,在视觉SLAM中有很强的通用性,自己实现的时候完全可以参考其实现方法。分为:

1. BundleAdjustment()

  • GlobalBundleAdjustment():用于单目初始化的CreateInitialMapMonocular函数以及闭环优化的RunGlobalBundleAdjustment函数(在闭环结束前新开一个线程,全局优化,在此之前会OptimizeEssentialGraph,论文中说其实这里全局优化提升的精度有限)。
  • LocalBundleAdjustment():用于LocalMapping线程中剔除关键帧之前的局部地图优化。

2. PoseOptimization()

  • 只优化当前帧pose,地图点固定。
  • 用于LocalTracking中运动模型跟踪,参考帧跟踪,地图跟踪TrackLocalMap,重定位。

3. OptimizeEssentialGraph()

  • EssentialGraph包括所有的关键帧顶点,但是优化边大大减少,包括spanning tree(生成树),共视权重θ>100的边,以及闭环连接边。
  • 用于闭环检测Sim3调整后优化。

4. OptimizeSim3()

  • 在用RANSAC求解过Sim3,以及通过Sim3匹配更多的地图点后,对当前关键帧,闭环关键帧,以及匹配的地图点进行优化,获得更准确的Sim3位姿,再去下一步的闭环调整。

使用到的g2o顶点包括:

1. VertexSE3Expmap():SE(3)位姿

2. VertexSim3Expmap():Sim(3)位姿

3. VertexSBAPointXYZ():地图点坐标

使用到的g2o边包括:

1. EdgeSE3ProjectXYZ():BA中的重投影误差(3D-2D(u,v)误差),将地图点投影到相机坐标系下的相机平面。

2. EdgeSE3ProjectXYZOnlyPose():PoseEstimation中的重投影误差,将地图点投影到相机坐标系下的相机平面。优化变量只有pose,地图点位置固定,是一边元,双目中使用的是EdgeStereoSE3ProjectXYZOnlyPoze()。

3. EdgeSim3():Sim3之间的相对误差。优化变量只有Sim3表示的pose,用于OptimizeEssentialGraph。

4. EdgeSim3ProjectXYZ():重投影误差。优化变量Sim3位姿与地图点,用于闭环检测中的OptimizeSim3。

ORB-SLAM(十二)优化的更多相关文章

  1. SLAM中的优化理论(二)- 非线性最小二乘

    本篇博客为系列博客第二篇,主要介绍非线性最小二乘相关内容,线性最小二乘介绍请参见SLAM中的优化理论(一)-- 线性最小二乘.本篇博客期望通过下降法和信任区域法引出高斯牛顿和LM两种常用的非线性优化方 ...

  2. [十二省联考2019]字符串问题——后缀自动机+parent树优化建图+拓扑序DP+倍增

    题目链接: [十二省联考2019]字符串问题 首先考虑最暴力的做法就是对于每个$B$串存一下它是哪些$A$串的前缀,然后按每组支配关系连边,做一遍拓扑序DP即可. 但即使忽略判断前缀的时间,光是连边的 ...

  3. Mysql优化(出自官方文档) - 第十二篇(优化锁操作篇)

    Mysql优化(出自官方文档) - 第十二篇(优化锁操作篇) 目录 Mysql优化(出自官方文档) - 第十二篇(优化锁操作篇) 1 Internal Locking Methods Row-Leve ...

  4. 高博-《视觉SLAM十四讲》

    0 讲座 (1)SLAM定义 对比雷达传感器和视觉传感器的优缺点(主要介绍视觉SLAM) 单目:不知道尺度信息 双目:知道尺度信息,但测量范围根据预定的基线相关 RGBD:知道深度信息,但是深度信息对 ...

  5. 《SLAM十四讲》个人学习知识点梳理

    0.引言 从六月末到八月初大概一个月时间一直在啃SLAM十四讲[1]这本书,这本书把SLAM中涉及的基本知识点都涵盖了,所以在这里做一个复习,对这本书自己学到的东西做一个梳理. 书本地址:http:/ ...

  6. 视觉slam十四讲第七章课后习题6

    版权声明:本文为博主原创文章,转载请注明出处: http://www.cnblogs.com/newneul/p/8545450.html 6.在PnP优化中,将第一个相机的观测也考虑进来,程序应如何 ...

  7. 视觉slam十四讲第七章课后习题7

    版权声明:本文为博主原创文章,转载请注明出处:http://www.cnblogs.com/newneul/p/8544369.html  7.题目要求:在ICP程序中,将空间点也作为优化变量考虑进来 ...

  8. 《视觉SLAM十四讲》第2讲

    目录 一 视觉SLAM中的传感器 二 经典视觉SLAM框架 三 SLAM问题的数学表述 注:原创不易,转载请务必注明原作者和出处,感谢支持! 本讲主要内容: (1) 视觉SLAM中的传感器 (2) 经 ...

  9. 我的MYSQL学习心得(十二) 触发器

    我的MYSQL学习心得(十二) 触发器 我的MYSQL学习心得(一) 简单语法 我的MYSQL学习心得(二) 数据类型宽度 我的MYSQL学习心得(三) 查看字段长度 我的MYSQL学习心得(四) 数 ...

  10. 【腾讯Bugly干货分享】腾讯验证码的十二年

    本文来自于腾讯bugly开发者社区,未经作者同意,请勿转载,原文地址:http://dev.qq.com/topic/581301b146dfb1456904df8d Dev Club 是一个交流移动 ...

随机推荐

  1. 1.Jdeveloper打印出完整日志(-Djbo.debugoutput=console)

    有时候在JDeveloper中需要打印出来比较系统和完整的ADF运行时日志 例如,想查看VO当前执行的是哪个View Criteria,运行的完整SQL语句到底如何 以及当前Binding Varia ...

  2. 在servlet中使用Spring注入

    修改servlet 的 init 方法,添加以下代码: SpringBeanAutowiringSupport.processInjectionBasedOnServletContext(this, ...

  3. 在网页中使用Markdown

    在网站中使用markdown有两种方式,一种是通过后端(php等)把markdown语法文本转换为html代码,输出到浏览器:另一种是通过javascript代码直接在浏览器中转换. 我在这里使用的是 ...

  4. 关于H5 移动端css 文本超出时省略号 失效的问题

    之前写代码的时候遇到一个问题,就是用了下面这段css代码来让文字超出范围隐藏并显示省略号. overflow: hidden; text-overflow: ellipsis; display: -w ...

  5. 10 OCP知识点讲解 之 什么是Buffer Cache?

    OCP知识点讲解 之 什么是Buffer Cache? 分类: Oracle 2012-06-22 17:36:54   一.Buffer cache作用: Buffer cache是Oracle建立 ...

  6. CSS、JavaScript学习过程

    初学JavaScript,通过博客记录自己学习过程中遇到的问题.(包含少量CSS) 零碎记录 JavaScript 输出 type="text/javascript" 那些老旧的实 ...

  7. ELK6.7.0 Windows 环境本地安装

    安装环境环境准备 第一次写博文,排版比较乱,理解万岁 ELK 6.7.0三件套 下载地址:https://www.elastic.co/cn/downloads/ windows环境下默认已配置jdk ...

  8. Colored Boots题解

    题目来自Codeforce 1141Dhttp://codeforces.com/problemset/problem/1141/D 因为是全英文题面,就先简单的阐述一下题面. 首先输入一个数n,然后 ...

  9. centos7.3 vsftpd 多用户配置

    1. 安装vsftpd及pam认证服务软件 yum install vsftpd* -y yum install pam* libdb-utils libdb* --skip-broken -y #设 ...

  10. python3 练习题100例 (四)

    题目四:输入某年某月某日,判断这一天是这一年的第几天? #!/usr/bin/env python3 # -*- coding: utf-8 -*- """ 题目四:输入 ...