Monocular slam 的理论基础(1)

2023-05-16

前言

  LSD-SLAM和ORB-SLAM的出现,使得单目slam最近成为了研究热点。单目SLAM一般处理流程包括track和map两部分。所谓的track是用来估计相机的位姿。而map部分就是计算pixel的深度,如果相机的位姿有了,就可以通过三角法(triangulation)确定pixel的深度,把这些计算好深度的pixel放到map里就重建出了三维环境。

主要内容

  在单目SLAM的学习过程中,需要较多的视觉几何的基础知识。这些基础知识中,有很多会令初学者晕头转向。比如,如何从本征矩阵E中如何恢复旋转R和平移T;比如,论文中经常提到的尺度scale是怎么来的;比如,怎么从单目获取的图像序列中获取场景的深度信息。
  博客分为两部分:本篇博客主要讲相机位姿估计,下一篇博客将结构恢复(深度提取)。

对极几何

两个摄像机的光心 C0C1 ,三维空间中一点 P ,在两幅图像中的位置为p0p1。如下图所示:
这里写图片描述
由于 C0C1P 三点共面,得到:
这里写图片描述
p0 在坐标系 C0 中的表示,以及 p1 在坐标系 C1 中的表示为:
   p0=x0y01c0   和  p1=x1y11c1

请特别注意
  这里的 pi 是在摄像机坐标系 Ci 中的表示,而我们从图像平面得到的 (u,v,1)T 是在图像坐标系下的表示。我们知道从摄像机坐标系到图像坐标系,是左乘了一个内参数矩阵 K 。所以根据图像坐标中的(u,v)得到其在摄像机坐标系下的坐标 p 需要左乘内参数的逆矩阵K1。在摄像机坐标系中的表示就称为normalized coordinates(hartley 书的第257页)。在程序中得到p的坐标代码演示如下:

这里写图片描述

这时,由共面得到的向量方程可写成:

这  (1)
其中,t是两个摄像机光心的平移量;R是从坐标系 C1 到坐标系 C0 的旋转变换,左乘旋转矩阵R的目的是把向量 C1p1 在坐标系 C1 下的表示旋转到坐标系 C0 下,注意点 p1 是在坐标系 C1 中的表示。
  一个向量a叉乘一个向量b可以表示为一个反对称矩阵乘以向量b的形式这时由向量a表示的反对称矩阵(skew symmetric matrix)如下:
这里写图片描述
所以式1可以写成:
这里写图片描述
我们用 [t]× 来表示t向量组成的反对称矩阵。在之前那篇讲lie的代数中,我们用 t^ 表示的向量t的反对称矩阵,在这边博客中这种表示也会采用(写起来方便)。
  本征矩阵 E 定义为 E=[t]×R ,它是一个3x3的矩阵:
这里写图片描述
本征矩阵的性质:
  一个3x3的矩阵是本征矩阵的充要条件是对它奇异值分解后,它有两个相等的奇异值,并且第三个奇异值为0。牢记这个性质,它在实际求解本征矩阵时有很重要的意义。这个性质的证明见Hartley的著作《Multiple view geometry》的第258页。

计算本征矩阵E、尺度scale的来由

将矩阵相乘的形式拆开得到
这里写图片描述
上面这个方程左边进行任意缩放都不会影响方程的解
   (x0x1x0y1x0y0x1y0y1y0x1y11)E33E11/E33E12/E33E13/E33...1=0
所以E虽然有9个未知数,但是有一个变量 E33 可以看做是缩放因子,因此实际只有8个未知量,这里就是尺度scale的来由,后面会进一步分析这个尺度。
  AX=0,x有8个未知量,需要A的秩等于8,所以至少需要8对匹配点。有了匹配点后,就只需要求解最小二乘问题了,上面这个方程的解就是矩阵A进行SVD分解 A=UΣVT 后,V矩阵最右边那一列的值。另外如果这些匹配点都在一个平面上那就会出现A的秩小于8的情况,这时会出现多解,会让你计算的E可能是错误的。上面是计算本征矩阵E的八点法,大家也可以去看看wiki的详细说明wiki链接。
  上面使用8点法计算E的过程使用的约束是 pT0Ep1=0 。另外 E 这个矩阵它自身还有一个很棒的约束:

这里写图片描述
这个矩阵约束实际上是9个子约束,每个子约束都是对应矩阵元素相减等于0wiki链接。利用这个约束去求解E就是五点法的思路,具体算法可以看 David Nister的论文。
  然而在实际计算过程中,匹配点坐标存在误差,这会使得计算出的E可能不会满足之前提到的那条性质,所以我们需要把计算出的E投影到真正的本征矩阵空间,也就是使得它的三个奇异值中两个相等,一个为0。投影的方法如下,实际就是强制改变这个矩阵的奇异值,具体证明见YI Ma著作《An Invitation to 3D vision》的第86页。
这里写图片描述

在应用的时候,考虑到E矩阵反正已经是缩放了的,所以更多的是直接令奇异值为(1,1,0),程序如下:
这里写图片描述

有了本征矩阵E,就可以从E中恢复平移t和旋转R。

特征点匹配

在讲解恢复R,T前,稍微提一下特征点匹配的方法。常见的有如下两种方式:
1. 计算特征点,然后计算特征描述子,通过描述子来进行匹配,优点准确度高,缺点是描述子计算量大。
2. 光流法:在第一幅图中检测特征点,使用光流法(Lucas Kanade method)对这些特征点进行跟踪,得到这些特征点在第二幅图像中的位置,得到的位置可能和真实特征点所对应的位置有偏差。所以通常的做法是对第二幅图也检测特征点,如果检测到的特征点位置和光流法预测的位置靠近,那就认为这个特征点和第一幅图中的对应。在相邻时刻光照条件几乎不变的条件下(特别是单目slam的情形),光流法匹配是个不错的选择,它不需要计算特征描述子,计算量更小。

从本征矩阵恢复R、T,尺度scale的进一步分析

  我们知道本征矩阵 E 定义为 E=[t]×Rt^R。可以用下面的计算式从本征矩阵中恢复R和T, T^ 表示T的反对称矩阵:

这里写图片描述
其中 RZ(π/2) 表示绕Z轴旋转90度得到的旋转矩阵:
这里写图片描述
从R,T的计算公式中可以看到R,T都有两种情况,组合起来R,T有4种组合方式。由于一组R,T就决定了摄像机光心坐标系C的位姿,所以选择正确R、T的方式就是,把所有特征点的深度计算出来,看深度值是不是都大于0,深度都大于0的那组R,T就是正确的。
这里写图片描述

但是特征点深度怎么计算出来呢?这部分的推导见下一篇博客。
  这里我们有必要进一步的分析下尺度scale,从R,T的计算公式中,可以发现平移向量 t E的奇异值 Σ 有关。再回顾一下之前求 E 时候的方程以及提到的伸缩:
AE=AUΣV=0AsE=AUsΣV=0
所以,之前推导过程中所有对E进行的尺度伸缩实际上都是作用在奇异值 Σ 上。也就是说这个尺度scale实际作用的是两个相机之间的平移,图示如下:
这里写图片描述这个图简单明了的演示了这种平移缩放作用。从图中也可以看出,由于尺度scale的关系,不同的t,决定了以后计算点P的深度也是不同的,所以恢复的物体深度也是跟尺度scale有关的,这就是论文中常说的结构恢复structure reconstruction,只是恢复了物体的结构框架,而不是实际意义的物体尺寸。并且要十分注意,每两对图像计算E并恢复R,T时,他们的尺度都不是一样的,本来是同一点,在不同尺寸下,深度不一样了,这时候地图map它最头痛了,所以这个尺度需要统一。
  那么如何让scale之间统一呢?如果你一直采用这种2d-2d匹配计算位姿的方式,那每次计算的t都是在不同尺度下的,Davide Scaramuzza的论文《Visual odometry I》的computing the relative scale那部分讲了一种方法使得相邻位姿间的不同的尺度s经过缩放进行统一。我们已经知道出现尺度不一致是由于每次都是用这种计算本征矩阵的方式,而尺度就是在计算E时产生的。所以尺度统一的另一种思路就是后续的位姿估计我不用这种2d-2d计算本征 E <script type="math/tex" id="MathJax-Element-723">E</script>的方式了,也就说你通过最开始的两帧图像计算E恢复了R,T,并通过三角法计算出了深度,那我就有了场景点的3D坐标,后续的视频序列就可以通过3Dto2d(opencv里的solvePnp)来进行位姿估计,这样后续的视频序列就不用计算本征矩阵从而绕过了尺度,所以后续的视频序列的位姿和最开始的两帧的尺度是一样的了。但是,这样计算又会产生新的问题–scale drift。因为,两帧间的位姿总会出现误差,这些误差积累以后,使得尺度不再统一了,如下图所示(借用@清华大学王京同学的图,很容易帮助理解):
这里写图片描述
随着相机位姿误差的积累,地图中的四个点在第二帧的位置相对于第一帧中来说像是缩小了一样。位姿误差累计导致尺度漂移这一点,对照上面讲尺度不确定问题时的那个图就很容易理解。关于如何纠正这个scale drift的问题很多单目slam里都提到了,所以这里不再深入。
  相机的轨迹有了,接下来就是structure reconstruction 了,我们下篇博客见。
(转载请注明作者和出处: http://blog.csdn.net/heyijia0327 未经允许请勿用于商业用途)
reference:
参考的文献我直接在博客中说明了,这里不再一一列举,祝好运,白巧克力。

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

Monocular slam 的理论基础(1) 的相关文章

  • 编程之美 -- 中国象棋将帅问题

    下过中国象棋的朋友都知道 xff0c 双方的 将 和 帅 相隔遥远 xff0c 并且它们不能照面 在象棋残局中 xff0c 许多高手能利用这一规则走出精妙的杀招 假设棋盘上只有 将 和 帅 二子 xff08 为了下面叙述方便 xff0c 我
  • C++单元测试工具 -- CppUnit

    CppUnit 作为C 43 43 语言的一款测试工具 xff0c 其实也是一个开源项目 xff0c 与JUnit一样 xff0c 用来方便开发人员进行单元测试的工具 项目地址 xff1a http sourceforge net apps
  • 拒绝游戏!发愤图强!

    立帖为证 xff01 xff01 xff01
  • C++ STL — 第6章 STL容器(二)deque

    C 43 43 STL容器deque和vector很类似 xff0c 也是采用动态数组来管理元素 使用deque之前需包含头文件 xff1a include lt deque gt 它是定义在命名空间std内的一个class templat
  • C++ STL — 第6章 STL容器(三)list

    一 list基础 List使用一个双向链表来管理元素 图一显示了list的结构 图一 list的结构 任何型别只要具备赋值和可拷贝两种性质 xff0c 就可以作为list的元素 二 list的功能 list的内部结构和vector和dequ
  • STL list remove和sort函数

    include lt iostream gt include lt list gt include lt iterator gt using namespace std bool cmp int a int b return a gt b
  • 排序 -- 简单选择排序

    选择排序 思想 xff1a 每一趟 n i 43 1 xff08 i 61 1 2 3 n 1 xff09 个记录中选择关键字最小的记录作为有序序列的第i个记录 简单选择排序 xff1a 通过n i次关键字间的比较 xff0c 从n i 4
  • HDOJ 1106 排序

    题目地址 xff1a http acm hdu edu cn showproblem php pid 61 1106 Problem xff1a 输入一行数字 xff0c 如果我们把这行数字中的 5 都看成空格 xff0c 那么就得到一行用
  • Jetson Xavier、Jetson TX2、 1080(Ti)、2080显卡运行深度学习模型性能对比(英伟达开发平台VS常用显卡)

    前言 xff1a 英伟达的Jetson TX2使得很多人认为深度学习模型终于可以像嵌入式开发平台那样做到小型化了 xff0c 不用再跑在高配计算机或者服务器上面了 xff0c 但是实际上Jetson TX2开发板的性能和深度学习常用到的10
  • 独家!了不起的UP系列产品,不一样的开发板 — UP Squared Board(二)

    UP 系列家族的成员 xff0c 经过团队经年累月的精心研发 xff0c 产品已不断丰富起来 先后开发出了第二代产品UP Squared 与第一代产品UP Board相比 xff0c 拥有 高性能低功耗的 UP Squared 似乎更令人兴
  • STM32连接--OneNET,阿里云(MQTT协议)详细教程

    x1f495 对于物联网工程 xff0c 不可或缺的必然是连接上云 xff0c 今天本人总结了上云经验 xff0c 希望对大家起到帮助哦 有用的话记得点赞收藏哦 关于如何连接OneNET OneNET https open iot 1008
  • HTTP Digest接入方式鉴权认证流程

    HTTP Digest接入方式鉴权认证流程 一 摘要认证原理 摘要认证与基础认证的工作原理很相似 xff0c 用户先发出一个没有认证证书的请求 xff0c Web服务器回复一个带有WWW Authenticate头的响应 xff0c 指明访
  • 6.2随笔

    今天打牛客 xff0c 用python写了一题 xff0c 结果发现用空格隔开的两个数不知道怎么输入 代码 xff1a n span class token punctuation span m span class token opera
  • 蓝牙Mesh简介

    蓝牙mesh简介 蓝牙Mesh的基本概念 蓝牙Mesh是2017年7月蓝牙技术联盟 xff08 Bluetooth SIG xff09 正式推出的蓝牙设备组网标准 我们知道蓝牙ble设备可以与其他设备建立GATT连接 xff0c 然后进行
  • 蓝牙Mesh的基本概念

    蓝牙mesh简介 蓝牙Mesh的基本概念 蓝牙Mesh是基于ble广播进行消息传递的一种蓝牙组网通讯网络 xff0c 是一种采用网络洪泛的方式无中心 无路由的对等网络 以实现蓝牙设备与蓝牙设备之间的多对多通讯 xff0c 使蓝牙在物联网智能
  • JLink Commander调试方法

    JLink Commander调试方法 1 背景 目前开发中常用的调试手段主要有串口 IO口输出作为调试方式 目前串口的限制较多 xff0c 有些硬件不太方便接串口或者一些实时的数据 xff0c 当时没有接串口则无法实时获取调试信息 IO调
  • 物联网安全系列 - 非对称加密算法 ECDH

    非对称加密算法 ECDH 背景 之前的章节讲到了对称加密算法AES xff0c 发送方和接收方需要使用相同的密钥进行通讯 xff0c 但是发送方怎么将密钥安全的发送给接收方 xff1f 这是一个问题 密钥分配问题 对称加密算法中 xff0c
  • 【开源】一款PyQT+Pyserial开发的串口调试工具

    开源 PyQT 43 Pyserial开发的串口调试工具 串口调试工具是我们做嵌入式开发常用的工具 xff0c 市面上已经有很多串口调试工具了 xff0c 博主写这款串口调试工具一方面是为了学习Python PyQT Pyserial 相关
  • 【Matter】解密Matter协议(一)--- 什么是Matter协议?

    1 什么是Matter协议 xff1f 目前的智能家居行业使用解决方案众多 xff0c 相互之间隔离严重 xff0c 有WiFi 蓝牙 ZigBee 蜂窝或者有线等等不同通讯协议的设备 不仅不同协议之间的设备不能互通 xff0c 而且连相同
  • 【蓝牙系列】蓝牙5.4到底更新了什么?(1)--- PAwR

    蓝牙系列 蓝牙5 4到底更新了什么 xff08 1 xff09 PAwR 一 背景 蓝牙技术联盟最近发布了蓝牙5 4的核心规范 xff0c 蓝牙5 4规范的主要改进之一就是实现了单个接入点与数千个终端节点进行双向无连接通信 xff0c 这一

随机推荐

  • UP Squared Board,工业级创新开发板,为您的物联网应用注入升级能量

    研扬科技自推出UP Board xff08 世界首创 Intel 平台信用卡大小开发板 xff09 以来 xff0c 便成功于业界打开名号 xff0c 后续 xff0c 研扬持续开发 UP 系列产品 xff0c 至今 xff0c 除了 UP
  • 【蓝牙系列】蓝牙5.4到底更新了什么(2)

    蓝牙系列 蓝牙5 4到底更新了什么 xff08 2 xff09 一 背景 上一篇文章讲了蓝牙5 4的PAwR特征 xff0c 非常适合应用在电子货架标签 xff08 ESL xff09 领域 xff0c 但是实际应用场景中看 xff0c 只
  • 【转载】【Nordic博文分享系列】详解Zephyr设备树(DeviceTree)与驱动模型

    详解Zephyr设备树 xff08 DeviceTree xff09 与驱动模型 转载自nordic半导体微信公众号 1 前言 Nordic最新的开发包NCS xff08 nRF Connect SDK xff09 相对于原来的nRF5 S
  • 感受一下SPL06气压计+APM三阶互补的高度融合

    不得不说 xff0c spl06气压计很强 xff0c 原始数据也比较干净 xff0c 短时间可以保持在30cm内浮动 xff0c 滤波后在10cm内浮动 就是这么夸张 使用APM的三阶互补滤波融合出 高度 xff0c 速度 xff0c 效
  • 6种串口协议的实现

    串口协议开发 以下解析范式都是采用数据队列的形似来存储 xff0c 并且根据设备运行速度差异 xff0c 还需增加数据包队列来存储解析完毕的数据包 1 范式一 固定长度 无校验 0x6B 20字节 0xB6 上面数据中有一个帧头0x6B x
  • html页面实时刷新显示服务器数据

    在上一篇中我说到浏览器和服务器交互数据 xff0c 是实现了服务器发数据给浏览器 xff0c 并在页面上显示 xff0c 但是是通过按钮点击刷新的 xff0c 而且数据是和html页面一起发过来的 xff0c 在这里我是数据放到页面数组里
  • 平衡小车之家客服真差

    我同事送了我一台直流电机平衡车 xff0c 然后同事又买了一台步进电机平衡车 都是在平衡小车之家买的 xff0c 好好看看下面的图片 最近在研究同事的步进平衡小车 xff0c 然后跑去问一下客服步进电机的参数 xff0c 一看我说 xff0
  • C++编译流程

    C 43 43 编译流程 C C 43 43 是编译型高级语言 xff0c 程序要执行 xff0c 必须要有编译器和链接器 编译过程分为四步 xff1a 预处理 编译 汇编 链接 1 预处理 读取源代码并对其中的以 开头的指令和特殊符号进行
  • 卡尔曼滤波 -- 从推导到应用(一)

    前言 卡尔曼滤波器是在估计线性系统状态的过程中 xff0c 以 最小均方误差为目的而推导出的几个递推数学等式 也可以从贝叶斯推断的角度来推导 本文将分为两部分 xff1a 第一部分 xff0c 结合例子 xff0c 从最小均方误差的角度 x
  • 卡尔曼滤波 -- 从推导到应用(二)

    该文是自我总结性文章 xff0c 有纰漏 xff0c 请指出 xff0c 谢谢 白巧克力 这部分主要是通过对第一部分中提到的匀加速小车模型进行位移预测 先来看看状态方程能建立准确的时候 xff0c 状态方程见第一部分分割线以后内容 xff0
  • LQR 的直观推导及简单应用

    本文主要介绍LQR的直观推导 xff0c 说明LQR目标函数J选择的直观含义以及简单介绍矩阵Q R的选取 xff0c 最后总结LQR控制器的设计步奏 xff0c 并将其应用在一个简单的倒立摆例子上 假设有一个线性系统能用状态向量的形式表示成
  • STM32学习路线-长图

    最近好好整理了一下学习STM32的路程 xff0c 做成了一个长图 xff1a STM32学习路线 xff0c 供初学者们参考一下
  • ROS 教程之 vision: 摄像头标定camera calibration

    在上一个ROS教程视觉文章中 xff0c 我们使用usb cam包读入并发布了图像消息 xff0c 但是图像没有被标定 xff0c 因此存在畸变 ROS官方提供了用于单目或者双目标定的camera calibration包 这个包是使用op
  • ROS 基础: 在同一个节点里订阅和发布消息

    在一些应用中 xff0c 可能有的人需要在同一个节点中实现订阅一个消息 xff0c 然后在该消息的回调函数中处理一下这些数据后再发布到另一个topic上 ROS answers中也有人有相同的疑问 xff0c 这里贴出Martin Peri
  • ROS : 修改ROS源代码(overlaying package)

    ROS官方或者其他个人提供了很多package供大家使用 xff0c 但是随着学习的深入 xff0c 很多人可能想去修改这些package的源代码 xff0c ROS提供了一种称之为overlaying的机制 它允许 ROS原有安装的pac
  • graph slam tutorial :从推导到应用3

    为了更好地理解graph based slam的过程 xff0c 本文以二维平面的激光SLAM为例子 xff0c 先简单介绍如何根据传感器信息构建图 xff0c 即图优化的前端 xff08 front end xff09 然后再针对上篇博客
  • graph slam tutorial : 从推导到应用1

    前言 SLAM问题的处理方法主要分为滤波和图优化两类 滤波的方法中常见的是扩展卡尔曼滤波 粒子滤波 信息滤波等 xff0c 熟悉滤波思想的同学应该容易知道这类SLAM问题是递增的 实时的处理数据并矫正机器人位姿 比如基于粒子滤波的SLAM的
  • graph slam tutorial :从推导到应用2

    在上一部分中通过一个例子大致了解了graph based slam的优化过程 在本篇博客中将提升一个层次 xff0c 对图优化的求解过程进行推导 由于博文关注的在图构建好以后 xff0c 如何调整机器人位姿使误差最下 因此 xff0c 本文
  • graph slam tutorial : g2o 的使用

    g2o全称general graph optimization xff0c 是一个用来优化非线性误差函数的c 43 43 框架 如果阅读了前几篇graph slam tutorial的博客 xff0c 再去读 g2o xff1a a gen
  • Monocular slam 的理论基础(1)

    前言 LSD SLAM和ORB SLAM的出现 xff0c 使得单目slam最近成为了研究热点 单目SLAM一般处理流程包括track和map两部分 所谓的track是用来估计相机的位姿 而map部分就是计算pixel的深度 xff0c 如