SLAM中的marginalization 和 Schur complement

2023-05-16

在视觉SLAM的很多论文中,会大量或者偶尔出现marginalization这个词(翻译为边缘化),有的论文是特地要用它,比如sliding window slam [2], okvis [3], dso [4]。而有的论文是简单的提到,比如g2o[1],orbslam。因此,很有必要对这个概念进行了解。

##marg 基础
在我们这个工科领域,它来源于概率论中的边际分布(marginal distribution)。如从联合分布p(x,y)去掉y得到p(x),也就是说从一系列随机变量的分布中获得这些变量子集的概率分布。回忆了这个概率论中的概念以后,让我们转到SLAM的Bundle Adjustment上,随着时间的推移,路标特征点(landmark)和相机的位姿pose越来越多,BA的计算量随着变量的增加而增加,即使BA的H矩阵是稀疏的,也吃不消。因此,我们要限制优化变量的多少,不能只一味的增加待优化的变量到BA里,而应该去掉一些变量。那么如何丢变量就成了一个很重要的问题!比如有frame1,frame2,frame3 以及这些frame上的特征点pt1…ptn。新来了一个frame4,为了不再增加BA时的变量,出现在脑海里的直接做法是把frame1以及相关特征点pt直接丢弃,只优化frame2,frame3,frame4及相应特征点。然而,这种做法好吗?

Gabe Sibley [2]在他们的论文中就明确的说明了这个问题。直接丢掉变量,就导致损失了信息,frame1可能能更多的约束相邻的frame,直接丢掉的方式就破坏了这些约束。在SLAM中,一般概率模型都是建模成高斯分布,如相机的位姿都是一个高斯分布,轨迹和特征点形成了一个多元高斯分布p(x1,x2,x3,pt1…),然后图优化或者BA就从一个概率问题变成一个最小二乘问题。因此,从这个多元高斯分布中去掉一个变量的正确做法是把他从这个多元高斯分布中marginalize out.

这marginalize out具体该如何操作呢?Sliding widow Filter [2]中只是简单的一句应用Schur complement(舍尔补). 我们知道SLAM中的图优化和BA都是最小二乘问题,如下图所示(ref.[1])
这里写图片描述
pose graph和BA中,误差函数 e e e是非线性的,这个非线性最小二乘问题可以通过高斯牛顿迭代求得,即
H δ x = b H\delta x= b Hδx=b
其中 H = J T W J , b = J W e H=J^TWJ, b=JWe H=JTWJ,b=JWe J J J是误差对位姿等的雅克比, W W W是权重。一般这个H矩阵也称为信息矩阵,并且H矩阵是稀疏的,这些都是SLAM中的基础知识,我这里啰嗦了下。

要求解这个线性方程,可以用QR分解什么的,但是这里我们关注marginalize. 也就是说只去求解我们希望保留的变量,那些我们要marg的变量就不关心了,从而达到减少计算的目的。假设变量x中可以分为保留部分和marg部分,那么上面的线性方程可以写成如下形式:
这里写图片描述
这里我们要marg掉 x a x_a xa,而计算 x b x_b xb, 对上面这个方程进行消元得到:
这里写图片描述
其中 Λ b T Λ a − 1 Λ b \Lambda ^T_{b}\Lambda ^{-1}_{a}\Lambda _{b} ΛbTΛa1Λb就称为 Λ a \Lambda _{a} Λa Λ b \Lambda _{b} Λb中的schur complement。有了这个上三角形式,我们就可以直接计算出 δ x b \delta x_{b} δxb了:
( Λ c − Λ b T Λ a − 1 Λ b ) δ x b = g b − Λ b T Λ a − 1 g a (\Lambda _{c}-\Lambda ^T_{b}\Lambda ^{-1}_{a}\Lambda _{b} )\delta x_{b}=g_b-\Lambda ^T_{b}\Lambda ^{-1}_{a}g_a (ΛcΛbTΛa1Λb)δxb=gbΛbTΛa1ga
这样我们就能够迭代的更新部分变量,从而维持计算量不增加。在上面这个过程中,我们要注意,构建出来的Hx=b是利用了marg变量的信息,也就是说我们没有人为的丢弃约束,所以不会丢失信息,但是计算结果的时候,我们只去更新了我们希望保留的那些变量的值。在slam的过程中,BA不断地加入新的待优化的变量,并marg旧的变量,从而使得计算量维持在一定水平。这就是sliding window filter, okvis, dso这些论文中marg的应用。

当然,上面如果你想去更新marg变量也是可以的,不是说只能计算 x b x_b xb,因为方程是完整的,只是这里我们强调只计算 x b x_b xb。在g2o[1]的论文III-D部分,公式(25),(26)就是两部分都计算:
这里写图片描述
他这里是把变量分为相机位姿 x p x_p xp和特征点 x l x_l xl两部分,然后利用schur complement先算相机位姿,再算特征点位姿,充分利用H矩阵的稀疏性加速计算。g2o算ba的example程序里就是把特征点设置为marginalize,这个在orbslam的local ba里也能看到。然而这种用法不像我们前面提到的那样真正marg out变量,这里被设为marg的那些特征点还是计算了值。这和我们这里的主题是有点点不同的。

让我们从g2o中回到marginalize的本意上去,也就是说只更新部分变量,而不是所有变量。从上面的过程中,貌似marg也就那么回事,简单得很,实际上水很深,具体后面再提。现在让我们从概率的角度去了解下这个东西的背后,幸好有人提了这个问题stackoverflow link。
这里写图片描述
一句话总结如下:要把一部分变量从多元高斯分布从分离出来,其实协方差矩阵很好分离,难分的是信息矩阵(协方差的逆),因为我们通常在SLAM里知道的是H矩阵,而不是协方差矩阵。对于H矩阵的分离,需要用到schur complement来分割。比如分割后能得到
这里写图片描述

##marg 深入
通过上面的知识点,我们知道了marg的过程,以及使用schur complement来实现。然而[2]论文中对marg的过程进行了更详尽的分析。这些分析总结出了一些技巧,也就是okvis和dso论文中常常提到的为了保持H矩阵的稀疏性,我们采取了这样那样的规则。
视觉SLAM的Bundle Adjustment中的Hessian矩阵一般是如下的结构
这里写图片描述
左上角是雅克比对pose求导并对应相乘得到的,右下角是和特征点相关的,绿色部分是pose和landmark之间交叉的。现在我们来看一看marg一个变量是如何影响H矩阵的稀疏性的。假设有四个相机pose,以及6个特征点 x m x_m xm,每个pose观测到三个特征点landmark,图关系如下:
这里写图片描述
现在我们先把pose1给marg掉,然后再marg掉特征点 x m 1 x_{m1} xm1,看看H矩阵如何变化。
这里写图片描述
图1是原始的H矩阵,这个图中的H和前面的H矩阵不一样,这里右下角是pose相关部分,左上角是特征点相关部分。图2是把H矩阵中和pose1相关的部分移动到H矩阵的左上角。图3是marg掉pose1以后的H矩阵,用斜线标记的部分是待marg的特征点1. 实际上marg以后的图3对应前面求 δ x b \delta x_b δxb时的矩阵 ( Λ c − Λ b T Λ a − 1 Λ b ) (\Lambda _{c}-\Lambda ^T_{b}\Lambda ^{-1}_{a}\Lambda _{b} ) (ΛcΛbTΛa1Λb)。可以看到图3和图2中去掉斜线部分对比的话,变得稠密了。也就是说,marg掉一个位姿,会使得剩余的H矩阵中有3个地方会fill-in, 图3中的颜色加重区域:a. 所有在位姿1能够观测到的landmark之间会fill-in,图3的左上角应该和图2中一样是6个小方块,结果marg以后和pose1相关的那3个小的方块变成了一个稠密的块。b. 和marg掉的pose1相连的pose2, 右下角区域中的左上角颜色加重部分。c. pose2跟被pose1观测到的那些特征点之间也会有fill-in. 这时候,图关系变成了入下:
这里写图片描述
注意,xm1,xm2,xm3之间相互连接起来了,并且xm1和xp2之间也连起来了,对应上面提到的这三点。接下来,就是marg掉特征xm1,H矩阵由3变成了4. 这时候的fill-in也是颜色加重区域。由于marg掉xm1之前不被任何其他pose观测到,而marg掉pose1以后,现在只和pose2相连,因此引入的fill-in还不是很多。这时候对应的图关系如下:
这里写图片描述
marg特征点1的这个过程这也给我们启示,就是marg特征点的时候,我们要marg那些不被其他帧观测到的特征点。因为他们不会显著的使得H变得稠密。对于那些被其他帧观测到的特征点,要么就别设置为marg,要么就宁愿丢弃,这就是okvis和dso中用到的一些策略。

虽然上面这些总结在marg的过程中很重要,但是我认为更重要的是关于marg过程中consistency的讨论。dso论文中提到计算H矩阵的雅克比时用FEJ (first estimate jacobian) [5],okvis论文中也提到要

fix the linearization point around x 0 x_0 x0, the value of x x x at the time of marginalization.

因为迭代过程中,状态变量会被不断更新,计算雅克比时我们要fix the linearization point。 所谓linearization point就是线性化时的状态变量,即求雅克比时的变量,因为计算雅克比是为了泰勒展开对方程进行线性化。我们要固定在点x0(marg 时的状态变量)附近去计算雅克比,而不是每次迭代更新以后的x。[7]是2016年IROS的论文,对这个原因表述的很清楚也容易阅读(套用张腾大神的话包教包会,感谢他的推荐), [6][5]是两篇年代更久一点的论文,这两篇论文都很有裨益,但是难读,单单这个consistency分析就值得仔细去看看,因为它直接涉及到优化结果。

为了更直观的理解上述这个结果,“泡泡机器人”里部分成员对这个过程进行了讨论,TUM的杨楠请教了其师兄DSO作者Engel。Engel用一张图就解释了这个过程:
这里写图片描述
在刘毅(稀疏毅),王京,晓佳等人讨论下,对这张图作出了如下解释:四张能量图中,第一张是说明能量函数 E E E由两个同样的非线性函数 E 1 E_1 E1 E 2 E_2 E2组成,我们令函数 E = 0 E=0 E=0,这时方程的解为 x y = 1 xy=1 xy=1,对应图中深蓝色的一条曲线。第二张能量函数图中的 E 1 ′ E'_1 E1对应函数 E 1 E_1 E1在点(0.5,1.4)处的二阶泰勒展开,第三张能量函数图中的 E 2 ′ E'_2 E2对应函数 E 2 E_2 E2在点(1.2,0.5)处的二阶泰勒展开。注意这两个近似的能量函数 E 1 ′ E'_1 E1 E 2 ′ E'_2 E2是在不同的线性点附近对原函数展开得到的。最后一张图就是把这个近似得到的能量函数合并起来,对整个系统 E E E的二阶近似。从第四个能量函数图中,我们发现一个大问题,能量函数为0的解由以前的一条曲线变成了一个点,不确定性的东西变得确定了,专业的术语叫不可观的状态变量变得可观了,说明我们人为的引入了错误的信息。回到marg过程,上面这个例子告诉我们,marg时,被marg的那些变量的雅克比已经不更新了,而此时留在滑动窗口里的其他变量的雅克比要用和marg时一样的线性点,就是FEJ去算,不要用新的线性点了。有了这些基础以后,大家可以再去看看王京,张腾大神们在知乎上关于FEJ更理论的表述,链接请戳。

由于我还没真正接触过first estimate jocabian的代码,所以对它理解还是停留在paper上,可能理解有偏差,还需要读完dso的代码,加深理解以后,我再对博客进行补充。如果有读者很熟悉这部分,欢迎指教,谢谢。

(转载请注明作者和出处:http://blog.csdn.net/heyijia0327 未经允许请勿用于商业用途)

ref:
[1] 《 g2o: A General Framework for Graph Optimization 》
[2] 《 Sliding Window Filter with Application to Planetary Landing 》
[3] 《 Keyframe-Based Visual-Inertial SLAM Using Nonlinear Optimization 》ijrr 2014 这个详细些
[4] 《 Direct Sparse Odometry 》
[5] 《Analysis and Improvement of the Consistency of Extended Kalman Filter based SLAM》
[6] 《Motion Tracking with Fixed-lag Smoothing: Algorithm and Consistency Analysis》
[7] 《Decoupled, Consistent Node Removal and Edge Sparsification for Graph-based SLAM》

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

SLAM中的marginalization 和 Schur complement 的相关文章

  • SLAM笔记(四)运动恢复结构的几何数学(本征矩阵、单应矩阵、基础矩阵)

    1 间接法进行运动恢复的前提假设 对于结构与运动或视觉三维重建中 通常假设已经通过特征匹配等方法获取了匹配好的点对 先求出匹配点对再获取结构和运动信息的方法称作间接法 间接法最重要的三个假设是 1 拥有一系列两帧之间的匹配点对 但同时假设匹
  • SLAM入门

    SLAM定义 SLAM Simultaneous localization and mapping 同时定位 我在哪里 与建图 我周围有什么 当某种移动设备 汽车 扫地机 手机 无人机 机器人 从一个未知环境的未知地点出发 在运动过程中 通
  • 《视觉SLAM十四讲》第一版源码slambook编译调试

    slambook master ch2 编译正常 log如下 slambook master ch2 mkdir build cd build cmake make j8 The C compiler identification is G
  • 基于深度相机的三维重建技术

    本文转载自http www bugevr com zblog id 14 原创作者bugeadmin 转载至我的博客 主要是为了备份 日后查找方便 谢谢原创作者的分享 三维重建 3D Reconstruction 技术一直是计算机图形学和计
  • 【SLAM】卡尔曼滤波(Kalman Filter)

    卡尔曼滤波 Kalman filter 一种利用线性系统状态方程 通过系统输入输出观测数据 对系统状态进行最优估计的算法 由于观测数据中包括系统中的噪声和干扰的影响 所以最优估计也可看作是滤波过程 卡尔曼滤波器的原理解释如下 首先 我们先要
  • rtabmap安装与使用

    参考 ubuntu18 04安装Rtabmap 具体详细步骤 教你手把手运行基于ZED的rtab map ZED入门 利用RTAB MAP做SLAM ubuntu16 04 ROS Kinetic rtabmap 源码 非ros版本 安装运
  • 单目视觉里程记代码

    在Github上发现了一个简单的单目vo 有接近500星 链接如下 https github com avisingh599 mono vo 这个单目里程计主要依靠opencv实现 提取fast角点并进行光流跟踪 然后求取本质矩阵并恢复两帧
  • 深度相机Kinect2.0三维点云拼接实验(一)

    文章目录 摘要 Kinect2 0简介 工作原理 RGB相机成像原理 深度相机成像原理 总结 参考文献 摘要 Kinect2 0是微软推出的一款RGB D相机 它即支持普通相机的拍摄 也支持脉冲测量深度信息 本系列文章基于该传感器给出基本的
  • vscode配置eigen3

    目录 1 头文件包含 2 c cpp properties json 3 CMakeList txt 4 完整代码 1 头文件包含 Eigen 核心部分 include
  • 图像匹配算法

    图像匹配算法分为3类 基于灰度的匹配算法 基于特征的匹配算法 基于关系的匹配算法 1 基于灰度的模板匹配算法 模板匹配 Blocking Matching 是根据已知模板图像到另一幅图像中寻找与模板图像相似的子图像 基于灰度的匹配算法也称作
  • PnP 问题

    欢迎访问我的博客首页 PnP 问题 1 DLT 2 P3P 3 G2O 求解 PnP 3 1 单目 3 2 双目 4 自定义顶点与边优化内参 4 1 二元边 4 2 三元边 4 3 总结 5 参考 PnP Perspective n Poi
  • SLAM-hector_slam 简介与使用

    hector slam功能包使用高斯牛顿方法 不需要里程计数据 只根据激光信息便可构建地图 所以他的总体框架如下 hector slam功能包 hector slam的核心节点是hector mapping 它订阅 scan 话题以获取SL
  • 高斯牛顿法求非线性最小二乘的步骤和c++代码实现

    slam图优化的本质是一个非线性优化问题 Gauss Newton求解步骤 1 线性化误差函数 2 构建线性系统 3 求解线性系统 4 更新解 并不断迭代直至收敛 一个简单的代码实现 一维参数xy 高维变为对应的矩阵即可 include
  • LeGO-LOAM代码详细注释版

    学习LeGO LOAM时 写的代码注释github代码链接 一部分注释来自github用户wykxwyc 一部分来自网上查阅 还有一部分是自己的理解 持续更新中
  • 1-如何安装ROS

    如何安装ROS 大家好 我是如何 今天尝试在Ubantu下安装ROS Robot Operating System 测试环境 虚拟机VMware Ubantu20 04 准备步骤 添加ROS软件源 sudo sh c echo deb ht
  • 【Pytorch论文相关代码】使用SOLD2预训练好的模型检测与匹配线段(自己的数据集)

    文章目录 前言 使用流程 检测与匹配结果 前言 论文链接 SOLD2 Self supervised Occlusion aware Line Description and Detection 论文源码 https github com
  • SLAM练习题(十一)—— G2O实战

    SLAM 学习笔记 写在前面的话 算是一点小小的感悟吧 估计位姿的方法有线性方法和非线性方法 线性方法就是特征点法中的2D 2D的对极约束 3D 2D的PnP问题 非线性方法有BA优化 它将位姿的估计问题转换成了一个误差关于优化量的最小二乘
  • LIO-SAM运行自己数据包遇到的问题解决--SLAM不学无数术小问题

    LIO SAM 成功适配自己数据集 注意本文测试环境 Ubuntu18 04 ROS melodic版本 笔者用到的硬件以简单参数 激光雷达 速腾聚创16线激光雷达 RS Lidar 16 IMU 超核电子CH110型 9轴惯导 使用频率1
  • Ubuntu18.04安装Autoware1.15(解决Openplanner无法绕障的问题:Openplanner2.5)

    文章目录 一 下载Autoware1 15源码 二 安装依赖 三 修改CUDA版本 四 编译以及报错解决 编译 1 报 undefined reference to cv Mat Mat 的错就按照下面方式改相应包 2 遇到OpenCV的C
  • 空索引向量的补集又是空索引向量

    我知道这个问题已经发布 但答案是用其他方式解决给定问题的技巧 但核心问题仍未得到解答 问题是这样的 somevector lt 1 5 emptyindeces lt vector somevector emptyindeces retur

随机推荐

  • SLA技术3D打印机的原理

    SLA是Stereo lithography Appearance的缩写 xff0c 即立体光固化成型法 用特定波长与强度的激光聚焦到光固化材料表面 xff0c 使之由点到线 xff0c 由线到面顺序凝固 xff0c 完成一个层面的绘图作业
  • STM32F103C8T6读取气压计MS5611,I2C读取模式

    笔者最近想用气压计模块来测一下相对高度 xff0c 使用的元器件如下图所示 所使用的最小系统板 所使用的气压计模块 其实读取还是蛮简单的 xff0c 根据核心板引脚图选择I2c接口 xff0c 然后借鉴正点原子的模拟i2c程序 xff0c
  • keil 的头文件

    许多初学者使用网上下载的程序时都会遇到这样一个问题 xff0c 就是头文件找不到 我想就这个问题说明一下 首先 xff0c 我们用到的KEIL有几种版本的 xff0c 头文件也不同 有reg51 h和at89x51 h两种比较常见 at89
  • 关于串口的初始化Uart_Init(0, 115200)

    void Uart Init int pclk int baud int i if pclk 61 61 0 因为Main c 中定义了 GLOBAL CLK 61 1 所以 PCLK 在 option h 中定义 在Main c 中的设置
  • 【学习笔记】Ubuntu双系统+搭建个人服务器

    Ubuntu双系统 43 搭建个人服务器 前言1 Ubuntu 43 Win双系统1 1 制作U盘启动盘1 2 系统分盘1 3 安装Ubuntu系统 2 搭建个人服务器2 1 设置root2 2 配置ssh2 3 向日葵连接 3 内网穿透3
  • IMU 测量模型和运动学模型

    一 概念 高斯白噪声 测量噪声是AD转换器件引起的外部噪声 xff0c 波动激烈的测量白噪声 随机游走 这里指零偏Bias 随机游走噪声 xff0c 是传感器内部机械 温度等各种物理因素产生的传感器内部误差的综合参数 xff0c 是变化缓慢
  • java参数校验注解

    java参数校验注解 java中前后台参数传递时如何对参数进行校验 校验主要使用到 javax validation类 一 引入依赖 SpringBoot的web组件中已引入validation的jar包 xff0c 但也可自行引入 spa
  • SpringBoot集成阿里easyexcel(三)CellWriteHandler图片转换

    继承单元格处理器 xff0c 通过重写不同方法 xff0c 对单元格进行处理 span class token keyword public span span class token keyword class span span cla
  • 使用Mybatis-plus拦截加密数据

    使用Mybatis plus拦截加密数据 使用自定义注解来标识需要加密的po和字段 xff0c 并通过mybaitsplus的插件工具类Interceptor类来实现对数据的拦截与加密转换操作 一 自定义加密注解 作用在类上的注解 pack
  • SpringBoot集成阿里easyexcel(四)Converter导入导出数据转换器

    SpringBoot集成阿里easyexcel xff08 四 xff09 Converter导入导出数据转换器 通过com alibaba excel converters Converter转换器实现Excel导入导出时Java数据与E
  • SpringBoot集成Ehcache缓存

    SpringBoot集成Ehcache缓存 Ehcache有两种缓存方式 xff0c 分别是堆内存 磁盘 xff08 非堆内存 xff09 一 堆内存缓存 也就是MemoryStore xff0c 速度最快 xff0c 不适合存放大量数据
  • Spring的切面编程(AOP)概念与使用AOP实现日志记录

    Spring的切面编程 xff08 AOP xff09 概念与使用 一 面向切面编程 定义 面向切面编程 xff08 AOP xff09 是通过预编译方式和运行期间动态代理实现程序功能的统一维护的一种技术 作用 xff1a 利用AOP对业务
  • 关于intrins.h头文件的介绍

    在单片机中应用最多的当然就是移位函数 xff0c 利用移位函数可以更简便的实现流水灯等效果 移位函数 移位函数名 左移 span class token function crol span span class token punctua
  • 大批量数据分批批量插入或更新(Mybatis+MySQL)

    大批量数据分批批量插入或更新 在MySQL数据库的前提下 xff0c 插入或更新大批量数据 首先批量插入需要考虑到以下几个因素 xff1a 数据库一次可以承受多大或者多少条数据的插入批量插入是否会占用Mysql资源太久 xff0c 影响系统
  • VSCode配置C++开发环境

    更新细节 2020 7 3 更新细节及排版 2022 6 9 昨天从下午一直研究到晚上十一点 xff0c 查阅了很多博客资料 xff0c 还是没配置好VSCode的C 43 43 开发环境 xff0c 今天早上又弄了一下 xff0c 现在O
  • stm32模拟输出PPM信号

    PPM信号周期为20ms xff0c 分成10分代表10个通道信号 xff0c 也就是2ms代表一个信号 0 5ms代表一个通道信号的开始 xff0c 所以0 5ms 2ms为通道范围控制 LED p1 39 A 39 8 IO口初始化 x
  • 使用JSON.parse,解决ie6-7上JSON未定义问题

    使用JSON parse时出现JSON未定义问题 xff0c JSON不是标准的javascript类型 xff0c 一些高级的浏览器支持 xff0c 但一些老一点的浏览器不支持JSON 如ie6 7 若需要 ie6 7 支持JSON只需要
  • C语言中的大小端转换与高低位颠倒

    在说大小端高低位之前 xff0c 肯定要说明数据在计算机内是如何存储的 在计算机中 xff0c 我们将数据分割成了一个一个的字节 xff08 byte xff09 xff0c 而每个字节又有8位 xff08 bit xff09 一个字节 x
  • C语言库函数中的Strcat函数

    一 Strcat函数的参数 Strcat函数所引用的头文件是 lt string h gt char strcat char strDestination const char strSource 参数说明 xff1a strDestina
  • SLAM中的marginalization 和 Schur complement

    在视觉SLAM的很多论文中 xff0c 会大量或者偶尔出现marginalization这个词 翻译为边缘化 xff0c 有的论文是特地要用它 xff0c 比如sliding window slam 2 okvis 3 dso 4 而有的论