SLAM初始化

2023-05-16

本节的学习要点:

  1. 初始化的目的(单目/双目)
  2. 初始化的两种方法
  3. 初始化过程

初始化的目的

​ 单目SLAM初始化的目的是 ==构建初始的三维点云地图(空间点)并为之后的计算提供初始值==。

​ 由于仅从单帧的图像不能得到深度信息,因此需要从图像序列中选取两帧以上的图像以估计相机机姿态并重建出初始的三维点云。

常见的方法

方法一

​ 追踪一个已知物体。单帧图像的每一个点都对应于空间的一条射线。通过不同角度不同位置扫描同一个物体,期望能够将三维点的不确定性缩小到可接受的范围。

方法二

​ 基于假设空间存在一个平面物体,选取两帧不同位置的图像,通过计算单应矩阵来估计位姿。这类方法在视差较小或者平面上的点靠近某个主点时效果不好。

方法三

​ 根据两帧之间的特征点匹配计算基础矩阵,进一步估计位姿。这种方法要求存在不共面的特征点。

单目初始化

方法流程

  1. 匹配初始帧;
  2. 位姿计算;
  3. 三角测量和地图创建;
  4. BA优化。

基本步骤

1. 匹配初始帧

​ 该阶段工作是,根据连续两帧图片中能够匹配的特征点数量来判断其是否可以作为初始帧,即只有连续两帧中能够匹配的特征点的数量大于某个值时才认为该帧(前一帧)为初始帧;
​ 在ORM-SLAM2中认为连续帧匹配点的数量大于100时可以将前一帧作为初始帧并记录两帧的匹配关系;
​ 以下是在ORB-SLAM2中相关部分的代码,功能为对两帧图片进行ORB特征点提取并进行匹配,当匹配的点的数量大于100时认为前一帧可以作为初始帧;可以通过修改代码中的参数来调整判断是否能够作为初始帧的条件。

int nmatches = matcher.SearchForInitialization(mInitialFrame,mCurrentFrame,mvbPrevMatched,mvIniMatches,100);

2. 位姿计算

​ 得到超过100对匹配点后,ORB-SLAM2同时计算适用于平面场景的单应矩阵H和适用于普通场景的基础矩阵F;
方法是:首先由抽样点计算出单次抽样的H(四对点)和F矩阵(八点法),通过若干次RANSAC抽样计算出最优的H和F矩阵;然后选择最合适的结果作为相机的初始位姿。

2.1. 八点法

相机位姿估计问题是为了求解本质矩阵E或者基础矩阵F,然后求解旋转R和平移t。
对于E矩阵认为是一个3*3的矩阵,因为任意常数乘以E不变,所以E矩阵的自由度是8。实际上E矩阵的自由度是5(反对称),但是对于SLAM运算中八点法和五点法区别不大且会增加麻烦所以我们只考虑E矩阵的尺度等价性用八点法来计算),从上式可以看出一对点可以确定一个关于E矩阵的方程,8个自由度就需要8对点来求解E矩阵,这就是八点法。

2.2 计算位姿

在同时计算单应矩阵和基础矩阵后对两个模型进行打分选择得分高的那个模型用来位姿计算,打分是用求得的E矩阵和F矩阵将前一帧上的特征点投影到下一帧并将下一帧的特征点投影到前一帧来计算重投影误差的和,代码如下:

cv::Mat Hn = ComputeH21(vPn1i,vPn2i); //计算单应矩阵        
currentScore = CheckHomography(H21i, H12i, vbCurrentInliers, mSigma); //进行评分
cv::Mat Fn = ComputeF21(vPn1i,vPn2i);//计算基础矩阵         
currentScore = CheckFundamental(F21i, vbCurrentInliers, mSigma);// 进行评分
float RH = SH/(SH+SF);//计算评分比,如果RH>0.4,选择单应矩阵来恢复相机位姿,否则选择基础矩阵来恢复相机位姿。

在计算完E矩阵和F矩阵并确定模型后,如果是本质矩阵E,进行SVD分解会得到4组可能的R,t,对这些解进行检查求出唯一真正的解;如果是单应矩阵进行分解(数值法、解析法)得到4组解,利用先验信息进行排除得到唯一解。

3. 三角测量和地图创建

已知位姿后通过三角测量可以计算出特征点对应的深度从而生成点云;并以第一帧为世界坐标系创建地图并进行数据关联。

三角测量是指通过在两处观察同一个点的夹角从而确定该点的距离。数学上可以从上式进行求解,设$x_1$,$x_2$是两个特征点的归一化坐标,那么存在
$$
s_1x_1=s_2Rx_2+t
$$
现在已知$R$,$t$要求解$s_1$,$s_2$,先求解$s_2$,对上式左乘$x_1$^:

image-20200323214017168

数据关联
  1. 地图点与关键帧关联

一个地图点可被多个关键帧观测到,将观测到这个地图点的关键帧与这个地图点进行关联,同时记录关键帧上哪一个特征点与这个地图点有关联。对于单目初始化来说,地图点需要关联第一步创建的两个关键帧;地图点与关键帧上的特征点关联后,计算最合适的描述子来描述该地图点,用于之后跟踪的匹配。

  1. 关键帧与地图点关联

一个关键帧上的特征点由多个地图点投影而成,将关键帧与地图点关联。

  1. 关键帧与关键帧关联

关键帧之间会共视一个地图点,如果共视的地图点个数越多,说明这两个关键帧之间的联系越紧密。对于某个关键帧,统计其与其他关键帧共视的特征点个数,如果大于某个阈值,那么将这两个关键帧进行关联。

  1. 将关键帧和地图点加入到地图中

4. BA优化。

初始化的最后一步将对只有两个关键帧的地图进行BA优化来优化位姿和路标点,以优化后的结果来重新生成点云地图。
同局部BA优化来最小化重投影误差不同,全局BA优化是在求解观测误差的最小二乘。由于观测误差的最小二乘是非线性的,利用了雅克比矩阵和H矩阵的稀疏性进行边缘化来简化运算,其中也使用了图优化理论。
实际上求解观测误差的最小二乘的过程是较复杂的,在这里就不多赘述了。
值得一提的是,由于单目没有尺度,因此在地图尺寸初始化时选择生成点深度的中位数作为单位尺寸1当作基准来进行地图的尺寸初始化。

双目初始化

由于双目和RGB-D相机不需要通过两个相邻帧来恢复地图点深度,所以初始化过程极其相似。

只要得到两个满足条件的关键帧即可开始初始化。

双目/RGB-D相机已知若干个特征点的深度(通过双目匹配、结构光或者飞行时间等深度计算方法),可以求解二维点对应的世界坐标系下的空间点,即已知若干个3D空间点及其投影的位置;此时使用PnP来估计相机运动;PnP问题的求解方法有很多种,包括P3P, DLT,EPnP,UPnP, BA等,其中ORM-SLAM2使用的PnP方法是EPnP,具体计算方不作赘述。

RGB-D初始化

  1. 初始化的目的是建立三维的空间点和地图并为之后的计算提供初始值;
  2. 同双目/RGB-D SLAM不同,单目SLAM无法从一帧图片中计算出深度,因此初始化需要两帧连续满足条件的图片来进行初始化;
  3. 单目SLAM初始化计算位姿是一个对极约束问题,而双目/RGB-D SLAM的初始化计算位姿是一个PnP问题;
  4. 在初始化成功后单目SLAM和双目SLAM一样是通过PnP来求解相机位姿的;
  5. 单目SLAM尺度不确定性的原因是因为在通过SVD分解E矩阵求解R,t时计算的t是没有单位的;
  6. 单目SLAM初始化的过程中对t进行了归一化来固定尺度,即以求解的初始帧的t为单位1,而后的轨迹和平移都将以这个t为单位;
  7. 单目SLAM的初始化一定要有一定程度的平移,纯旋转是无法完成初始化的。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

SLAM初始化 的相关文章

  • ubuntu1804系统安装Realsense SDK驱动和ROS Wrapper

    文章目录 1 软件安装1 1 安装realsense SDK1 2 安装Ros Wrapper 2 打开双目的开关3关闭结构光方法1 xff1a 通过可视窗口关闭方法2 xff1a 通过修改launch文件关闭 4查看相机参数 说明 xff
  • 在使用evo进行orb-slam2轨迹评估时提示时间戳没有对齐的问题

    最近使用一个orb slam2修改版跑euroc数据集 在使用evo评估绝对轨迹误差时出现下面的报错 found no matching timestamps between CameraTrajectory txt and gt MH01
  • ORB-SLAM2论文翻译

    文章转载至泡泡机器人 转载链接 链接 摘要 ORB SLAM2是基于单目 xff0c 双目和RGB D相机的一套完整的SLAM方案 它能够实现地图重用 xff0c 回环检测和重新定位的功能 无论是在室内的小型手持设备 xff0c 还是到工厂
  • ROS使用命令行查看图像消息的宽和高

    备忘 xff1a ROS在终端使用命令行查看图像消息的宽和高 span class token comment 查看图像的宽 span rostopic span class token builtin class name echo sp
  • C++读取指定目录下的所有文件

    简介 xff1a 代码备忘 xff0c 使用C 43 43 读取指定目录下的所有文件名 xff0c 并存入vector向量 需要的头文件 span class token macro property span class token di
  • ubuntu1804进行vins-fusion算法环境搭建遇到的问题汇总

    简介 xff1a 在ubuntu1804系统搭建vins fusion环境并基于euroc数据集进行测试 xff0c 对遇到的编译报错和解决办法进行汇总 1 vins fusion算法环境搭建 报错1 Chessboard cc 20 38
  • ubuntu1804搭建svo2.0环境并跑euroc数据集

    0说明 整个SVO2 0环境搭建过程按照官网的说明进行 链接 xff1a https github com uzh rpg rpg svo pro open 开发环境是ubuntu18 04 43 ROS Melodic 1工具安装 Ins
  • 使用ceres库时报错:undefined reference to `ceres::Problem::Problem()‘

    编译cmake项目链接ceres库时名称没有写对导致报错 myCeres cpp span class token punctuation span text startup 43 0x247 span class token punctu
  • qt.qpa.plugin: Could not load the Qt platform plugin “xcb“

    运行环境 ubuntu 20 04 5 使用python3 9 由于使用qt5的同时使用了opencv导致如下报错 应该是由于调用环境不兼容导致的 需要加入如下代码问题解决 import os os environ pop 34 QT QP
  • 【Ubuntu】触摸屏旋转配置

    1 主要参考这篇文章编写配置脚本 Ubuntu18 04双屏显示触屏设置 xff0c 解决触摸点和响应位置不一致的问题 iShare 123的博客 CSDN博客 ubuntu触摸屏设置 Ubuntu18 04双屏 https blog cs
  • 红外视频——行人识别

    最近在做关于红外视频的项目 xff0c 主要是对区域入侵检测 xff0c 主要是能够对行人进行识别 xff0c 又到了瓶颈期 xff0c 所以看看论文找些灵感 xff0c 下面也主要是对看到的论文的思想及实现步骤进行总结 1 Thermal
  • Ardupilot任务调度的理解

    Ardupilot通过定时器定时调度一系列任务实现任务调度 由于Ardupilot固件有基于arduino的APM发展而来 xff0c 因此程序与arduino的形式类似 xff0c 包含一个setup xff08 xff09 函数与一个l
  • 最详细的Gmapping代码详解!详细到每一行!

    无处不在的小土 gmapping的ROS封装 gaoyichao com
  • 【OpenCV3】棋盘格角点检测与绘制——cv::findChessboardCorners()与cv::drawChessboardCorners()详解

    棋盘格法是摄像机标定中常用的一种方法 xff0c 在使用该方法时需要对棋盘格的角点进行检测 opencv中封装了一个专门用于棋盘格角点检测的函数即cv findChessboardCorners xff0c 同时 xff0c 也提供了一个专
  • 网络编程和并发编程面试题

    网络编程和并发编程面试题 1 简述 OSI 七层协议 一 应用层 与其它计算机进行通讯的一个应用 xff0c 它是对应应用程序的通信服务的 例如 xff0c 一个没有通信功能的字处理程序就不能执行通信的代码 xff0c 从事字处理工作的程序
  • 树莓派利用串口进行通信

    树莓派串口通信 我用的是树莓派3b 43 型号 xff0c 网上各种各样的修改方式来使得树莓派的串口可以工作 xff0c 过于混乱 xff0c 还有的教程甚至会被树莓派系统搞崩溃 xff0c 尤其是树莓派实验室那里的中文教程 xff0c 是
  • Android系统学习(六)------裁剪Android系统

    你好 xff01 这里是风筝的博客 xff0c 欢迎和我一起交流 经过前面几篇博客的编译步骤 xff0c 成功的编出了Android系统 xff0c 但是发现编出来的system img有点大了 xff0c 有差不多1 7G xff0c 怎
  • 用postman批量执行post请求数据

    今天接到一个任务 xff0c 需要在同一个url中执行83次不同的post请求 xff0c 而且需要连续执行3次 xff0c 如果一个一个点击 xff0c 岂不是不符合 xff0c 摸鱼大王的风格 xff0c 思考片刻之后 xff0c 决定
  • 使用python批量发送post请求

    usr bin env python import requests url 61 34 http 192 168 26 xxx 34 header 61 39 Connection 39 39 close 39 39 Accept 39
  • 关于A 全球大气光 atmosphere light 算法总结

    由于大气散色所用引起的光源的特性 随着距离的增大而增强 A其实为无穷远处的一个大气光源 xff0c 比如天空 xff0c 这应该不是指天空中的云而是近地天空 由于各种去雾算法不同对A的依赖可能也不相同 我看到有几种方法对在去雾算法中应用 x

随机推荐

  • 解决树莓派开机黑屏不显示桌面问题

    一 设备状态 xff1a 以前桌面使用正常 xff0c 通过ssh进行安装pyqt5后导致桌面开机黑屏 二 所使用设备为 xff1a 树莓派4B 43 2021 05 07 raspios buster armhf img 三 定位问题 x
  • 树莓派Linux固定多USB设备号相同厂家设备和不同设备(包括一个USB设备两个设备名称号的情况)

    目录 一 问题说明 二 解决思路 三 开干 一 问题说明 在使用USB摄像头时 xff0c 由于使用了两个摄像头 xff0c 故此在上电启动后 xff0c 设备号会发生变化 xff0c 比如设备1之前时video0 xff0c 有的时候上电
  • FreeRTOS学习笔记-流缓冲区(FreeRTOS中文官网)

    https www freertos org zh cn cmn s RTOS stream buffer API html RTOS 流缓冲区 API RTOS 流缓冲区 API 函数 xff1a xStreamBufferCreate
  • FreeRTOS学习笔记-消息缓冲区(FreeRTOS中文官网)

    RTOS消息缓冲区 API RTOS 消息缓冲区 API 函数 xff1a xMessageBufferCreate xMessageBufferCreateStatic xMessageBufferSend xMessageBufferS
  • ubuntu系统X86环境下配置TX2的ARM环境的交叉编译链

    总步骤 安装qtcreator的IDE安装aarch64 linux gnu g 43 43 交叉编译链下载Qt库的源码 xff0c 配置编译选项 xff0c 编译生成针对TX2的ARM环境的qmake工具配置qtcreator xff0c
  • ROS中Eigen库的引用

    在CmakeList txt中添加两个地方 find package Eigen REQUIRED include directories Eigen INCLUDE DIR 如果找不到Eigen xff0c 我们将第一句改成 find p
  • ROS tf使用

    1 静态tf发布 lt node pkg 61 34 tf 34 type 61 34 static transform publisher 34 name 61 34 link1 link2 broadcaster 34 args 61
  • SLAM算法配置——使用Realsense D435i结合ROS跑通ORB-SLAM2的RGB-D节点

    ORB SLAM2源地址 配置环境依赖 Pangolin xff0c OpenCV xff0c Eigen3 xff0c DBoW2 and g2o xff08 源代码里有 xff0c 不用自己装 xff09 xff0c ROS xff08
  • 代码编写及阅读规范

    阅读常识 1 C语言中在函数名或关键字前加下划线 一般情况是标识该函数或关键字是自己内部使用的 xff0c 与提供给外部的接口函数或关键字加以区分 规范 综述 C 43 43 是一门十分复杂并且威力强大的语言 xff0c 使用这门语言的时候
  • 流媒体开发之路

    其实很早之前 xff0c 就想写属于自己的博客 xff0c 大二就有了CSDN账号 xff0c 很讽刺的是 xff0c 工作几年了 xff0c 账号里面的内容竟然和小鲜肉脸一样干净 干净的让人尴尬 回顾自己的这几年的开发之路 xff0c 接
  • matlab图像处理实例详解---note

    1 直方图均衡及直方图规定化 可以优化图像的亮度及gamma效果 2 图像的标准差 当图像越清晰的时候 xff0c 图像的标准差就越大 是否可以用来做af的判定标准 作为fv的值 另外是否可以用图像的相关系数作为caf的一个trigger
  • promise限制并发请求数量

    所谓并发请求 xff0c 就是指在一个时间点多个请求同时执行 当并发的请求超过一定数量时 xff0c 会造成网络堵塞 xff0c 服务器压力大崩溃或者其他高并发问题 xff0c 此时需要限制并发请求的数量 假如等待请求接口1000个 xff
  • 一个跨平台的 C++ 内存泄漏检测器(转载)

    一个跨平台的 C 43 43 内存泄漏检测器 吴咏炜 adah 64 netstd com 2004 年 3 月 内存泄漏对于C C 43 43 程序员来说也可以算作是个永恒的话题了吧 在Windows下 xff0c MFC的一个很有用的功
  • printf和wprintf、printf输出结束标识符、c++按值返回临时对象是否是const的实验

    ifndef TEST H define TEST H include lt iostream gt include lt string gt using namespace std int x 61 5 struct s public s
  • 自己搭深度学习环境踩坑血泪史

    自己搭深度学习环境踩坑的血泪史 从一个沮丧的事情开始问题1 强行更新了一次win10后 双系统里的ubuntu的启动项就没了 xff0c 直接进入win10系统问题2 sudo apt get update 总是超时问题3 conda in
  • 电脑串口延迟/缓冲设置方法

    使用串口做精确信号发送的时候会经常出现不能时间不精确的问题 xff0c 使用两个u口转串口串连之后一个接收一个发送的情况下 收到的时间延迟数据如下 xff1a 注意 xff1a 这里的因为有一个接收缓冲区和一个发送缓冲区 xff0c 所以这
  • apt-get install 连同诸多依赖包一并安装的指令

    apt get install 连同诸多依赖包一并安装 如题 xff0c apt get安装某个包的时候 xff0c 经常会碰到很多依赖包 xff0c 需要一一安装了才行 xff0c 非常麻烦 当然 xff0c 可以使用以下指令一步到位 a
  • git 分支操作记录

    查看分支 xff1a 查看本地分支 xff1a git branch 查看远程分支 xff1a git branch r 查看全部分支 xff08 本地和远程 xff09 git branch a 新建分支 xff1a 创建新分支 xff1
  • C++ 简析容器Vector

    向量 xff08 Vector xff09 是一个封装了动态大小数组的顺序容器 xff08 Sequence Container xff09 跟任意其它类型容器一样 xff0c 它能够存放各种类型的对象 可以简单的认为 xff0c 向量是一
  • SLAM初始化

    本节的学习要点 xff1a 初始化的目的 单目 双目 初始化的两种方法初始化过程 初始化的目的 单目SLAM初始化的目的是 61 61 构建初始的三维点云地图 xff08 空间点 xff09 并为之后的计算提供初始值 61 61 由于仅从单