orb-slam2学习总结

目录

视觉SLAM

1、地图初始化

2、ORB_SLAM地图初始化流程

3、ORB特征提取及匹配

1、对极几何

2、对极约束 (epipolar constraint)

3、基础矩阵F、本质矩阵E

5、单目尺度不确定性

6、单应矩阵(Homography Matrix)

6.1 什么是单应矩阵

6.2 H矩阵求解

7.1 基础要点

7.2  从E矩阵中恢复R、t

7.3  从H矩阵中恢复R、t

7.4 R、t值验证

7、三角化             

7.1什么是三角化

7.2 三角化求解

8、关键步骤总结

9、参考资料


视觉SLAM

一、知识点

1、地图初始化

视觉slam中,地图初始化是一个非常重要的步骤,它决定了后续的跟踪、建图等模块的效果。简单来说,初始化的目的是利用前几帧图像,计算出相机位姿,并且构建出第一批3D地图点第一批3D地图点为跟踪、建图等模块提供了一个初始的地图,这样后续的模块就可以利用这些地图点进行跟踪、建图等工作。

双目由于已知两个相机的内外参,可以直接三角化出3D点。三角化是单目的一个步骤,所以双目初始化比较简单。

RGBD可以直接通过深度值还原3D坐标,更加简单。 

配置了IMU之后实际也可以直接获得两个相机之间的姿态,也可以直接三角化出3D点(虽然IMU初始化需要考虑IMU参数的初始化,但是这部分内容不在本文的讨论范围内)。

2、ORB_SLAM地图初始化流程

3、ORB特征提取及匹配

特征点提取是一个比较独立的内容,对于ORB特征提取可以参考这篇文章:https://zeal-up.github.io/2023/05/18/orbslam/orbslam3-ORBextractor/

备注:根据描述子之间的距离来寻找两帧间 距离最近的关键件,达到关键点匹配的效果。

  1. 对极几何及对极约束

1、对极几何

通常,我们会将第一帧图像当作参考帧,也就是世界坐标系。第二帧相机的位姿也就是相对于第一帧相机的位姿。

总结:

利用两相机在空间中成像的(空间几何关系,也叫立体几何)规律,进而求解此时相机的位姿态。因此就需要用到特征提取步骤提取到得匹配点,利用匹配点利用对极约束求解相机位姿。

那么什么是对极约束呢?

2、对极约束 (epipolar constraint)

3、基础矩阵F、本质矩阵E

   Foundamental Matrix、Essential Matrix

  1. 对极约束的几何意义

备注

当需要寻找关键点在另外一张图片上投影点时候,评估相机姿态质量的时候,同样道理。

又或者在极线方向上寻找匹配点,避免全图片检索,提到检索效率。这些都是对极约束的应用。

  1. 本质矩阵和基础矩阵求解
  • 方程求解

  • opencv求解

5、单目尺度不确定性

在看对极几何的图

总结:

尺度信息在等式中无法接着求解,只能利用别的设备增加深度信息才能更好求解尺度。

6、单应矩阵(Homography Matrix)

6.1 什么是单应矩阵

前面讨论基础矩阵的概念以及如何从一些匹配点对关系中求解基础矩阵。我们没有对关键点是否在一个平面上进行任何假设。但是,如果我们假设关键点在一个平面上,那么我们就可以使用单应矩阵(Homography Matrix)来求解相机之间的位姿。当匹配点对的关键点都是在3D空间中一个平面上时,这些点对关系可以通过单应矩阵来描述(相差一个常量系数)

备注:要求匹配点对应点对是3D空间,同一平面上的。

如下图:

6.2 单应矩阵的应用

  • 相机位姿态求解
  • 图像拼接

链接:

超详细!从单应矩阵推导到自动驾驶环视投影应用 | Zeal's Blog

6.2 H矩阵求解

  • 求解推导

  • OpenCV接口

  1. 位姿求解

如何从H、E矩阵恢复R、t?

7.1 基础要点

7.2  从E矩阵中恢复R、t

可使用opencv接口

7.3  从H矩阵中恢复R、t

从H矩阵恢复R、t有多种方法,论文中的方法叫Faugeras SVD-based decomposition,最终可以求解出8种解。另外一种有名的数值解法(通过奇异值分解)叫

SVD-based decomposition

OpenCV的接口使用的是分析解法:https://inria.hal.science/inria-00174036v3/documentOpenCV的接口最终返回4种解

OpenCV的接口使用说明:cv::decomposeHomographyMat

7.4 R、t值验证

从E、H分解出来的矩阵后,需要选择出正确的R、t

无论从E矩阵还是H矩阵中恢复出R、t,都会得到多种解。

我们需要从这些解中选择出正确的解。 最简单的做法是利用分解出的R、t对匹配点进行三角化,并检查该3D点在两个相机下的深度值,3D点必须在两个相机下都是正的才是正确的解。

对于单应矩阵的分解结果,OpenCV提供了一个函数可以帮助我们选择正确的解:cv::filterHomographyDecompByVisibleRefpoints

在ORB_SLAM中,对于每一种解,都会对所有匹配点进行三角化,对三角化出来的点,会进行很多步骤的检查,最后选择拥有最多内点的解作为正确的解

备注:什么是内点

7、三角化             

7.1什么是三角化

当求解出位姿态后,需要利用位姿,联合匹配点关系,求解出三维点坐标。

7.2 三角化求解

用SVD求解上述方程,求解出的3D坐标有4个元素,需要将第四个元素归一化为1。这里把ORB_SLAM的这部分代码也贴出来

/** 
 * @brief 三角化获得三维点
 * @param x_c1 点在关键帧1下的归一化坐标
 * @param x_c2 点在关键帧2下的归一化坐标
 * @param Tc1w 关键帧1投影矩阵  [K*R | K*t]
 * @param Tc2w 关键帧2投影矩阵  [K*R | K*t]
 * @param x3D 三维点坐标,作为结果输出
 */
bool GeometricTools::Triangulate(
    Eigen::Vector3f &x_c1, Eigen::Vector3f &x_c2, Eigen::Matrix<float,3,4> &Tc1w, Eigen::Matrix<float,3,4> &Tc2w,
    Eigen::Vector3f &x3D)
{
    Eigen::Matrix4f A;
    // x = a*P*X, 左右两面乘x的反对称矩阵 a*[x]^ * P * X = 0 ,[x]^*P构成了A矩阵,中间涉及一个尺度a,因为都是归一化平面,但右面是0所以直接可以约掉不影响最后的尺度
    //  0 -1 v    P(0)     -P.row(1) + v*P.row(2)
    //  1 0 -u *  P(1)  =   P.row(0) - u*P.row(2) 
    // -v u  0    P(2)    u*P.row(1) - v*P.row(0)
    // 发现上述矩阵线性相关(第一行乘以-u加上第二行乘以-v等于第三行),所以取前两维,两个点构成了4行的矩阵(X分别投影到相机1和相机2),就是如下的操作,求出的是4维的结果[X,Y,Z,A],所以需要除以最后一维使之为1,就成了[X,Y,Z,1]这种齐次形式
    A.block<1,4>(0,0) = x_c1(0) * Tc1w.block<1,4>(2,0) - Tc1w.block<1,4>(0,0);
    A.block<1,4>(1,0) = x_c1(1) * Tc1w.block<1,4>(2,0) - Tc1w.block<1,4>(1,0);
    A.block<1,4>(2,0) = x_c2(0) * Tc2w.block<1,4>(2,0) - Tc2w.block<1,4>(0,0);
    A.block<1,4>(3,0) = x_c2(1) * Tc2w.block<1,4>(2,0) - Tc2w.block<1,4>(1,0);

    // 解方程 AX=0
    Eigen::JacobiSVD<Eigen::Matrix4f> svd(A, Eigen::ComputeFullV);

    Eigen::Vector4f x3Dh = svd.matrixV().col(3);

    if(x3Dh(3)==0)
        return false;

    // Euclidean coordinates
    x3D = x3Dh.head(3)/x3Dh(3);

    return true;
}

也可以使用opencv接口进行三角化,且可以批量操作:cv::triangulatePoints

8、关键步骤总结

  • 特征点提取和匹配,得到如下效

  • 如何从匹配的特征点中,恢复相机之间的相对位姿

利用E、F矩阵怎么求解位姿态

利用H矩阵怎么求解位姿

利用H矩阵进行图像拼

  • 矩阵中分解R、t
  • 利用R、t进行三角化

9、参考资料

orbslam

ORB-SLAM3保姆级解析:地图初始化(基础矩阵/单应矩阵/三角化的实际应用)

激光slam

详解激光雷达点云处理那些事,点云预处理、感知、定位 - 哔哩哔哩 (bilibili.com)

立体几何

立体视觉入门指南(6):对级约束与Fusiello法极线校正 - 知乎 (zhihu.com)

视觉SLAM中的对极约束、三角测量、PnP、ICP问题

视觉SLAM中的对极约束、三角测量、PnP、ICP问题 - 古月居 (guyuehome.com)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/240650.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

干不完的996,加不完的007,浅谈程序员的内卷化

目录 一. 什么是内卷化 二. 程序员的内卷化 2.1. 码农时代 2.2. 开源时代 2.3. 加班文化 三. 如何不被内卷化 3.1. Stay Hungry, Stay Foolish 3.2. 工程能力 3.2.1. 架构 3.2.2. 规范 3.2.3. 管理 3.2.4. 排错 3.3. 学会思考 四. 结尾 一. 什么是内卷化 最近开始…

【算法与数据结构】37、LeetCode解数独

文章目录 一、题目二、解法三、完整代码 所有的LeetCode题解索引&#xff0c;可以看这篇文章——【算法和数据结构】LeetCode题解。 一、题目 二、解法 思路分析&#xff1a;本题也是一道困难题&#xff0c;难点在于如何构建数独棋盘&#xff0c;如何检查棋盘的合法性&#xff…

Halcon一维码识别

文章目录 参数连接halcon 自带案例1&#xff08;设置校验位识别条码&#xff09;Halcon 自带案例2&#xff08;设置对比度识别条码&#xff09;Halcon 自带案例3&#xff08;存在曲面变形&#xff09;Halcon 自带案例4&#xff08;设置条码扫描线&#xff09;Halcon 自带案例5&…

Linux---Ubuntu操作系统

1. Ubuntu操作系统的介绍 Ubuntu操作系统是属于Linux操作系统中的一种&#xff0c;它是免费、稳定又可以拥有绚丽界面的一个操作系统 2. Ubuntu图形界面的介绍 任务栏 窗口操作按钮 窗口菜单条 任务栏效果图: 窗口操作按钮效果图: 窗口菜单条效果图: 3. 与Windows目录结…

『C++成长记』拷贝构造函数

&#x1f525;博客主页&#xff1a;小王又困了 &#x1f4da;系列专栏&#xff1a;C &#x1f31f;人之为学&#xff0c;不日近则日退 ❤️感谢大家点赞&#x1f44d;收藏⭐评论✍️ 目录 一、拷贝构造函数 &#x1f4d2;1.1拷贝构造函数的概念 &#x1f4d2;1.2拷贝构造…

Java项目-瑞吉外卖Day6

导入用户地址功能&#xff0c;为用户添加地址&#xff1a; 添加AddressBook实体类&#xff0c;创建相关service&#xff0c;mapper&#xff0c;serviceImpl&#xff0c;controller类。 controller类直接使用的资料提供的代码。 实现菜品展示移动端开发&#xff1a; 看到前端发…

添加,更换和删除 vSphere License

目录 1. 删除 License2. 添加 License&#xff08;1&#xff09;输入许可证密钥&#xff08;2&#xff09;编辑许可证名称&#xff08;3&#xff09;确认许可证信息 3. 分配/更换 License&#xff08;1&#xff09;为 vCenter Server 分配 License&#xff08;2&#xff09;为 …

Android : 序列化 Parcelable 简单应用

1.Parcelable 介绍 Parcelable 是 Android 提供的一个序列化接口&#xff0c;用于将数据写入 Parcel&#xff0c;以及从 Parcel 中读取数据。一个类只要实现了这个接口&#xff0c;该类的对象就可以被序列化&#xff0c;主要用于 IPC&#xff08;进程间通信&#xff09;、Bind…

产品经理之如何编写竞品分析(医疗HIS系统管理详细案例模板)

目录 一.项目周期 二.竞品分析的目的 三.竞品分析包含的维度 四.如何选择竞品 五.竞品画布 六.案例模板 一.项目周期 在整个项目的周期&#xff0c;产品经理所做的事情主要在项目前期做市场分析、需求调研等&#xff0c;下面一张图概况了整个项目周期产品经理、开发工程师…

网络安全——Iptables防DDoS攻击实验

一、实验目的要求&#xff1a; 二、实验设备与环境&#xff1a; 三、实验原理&#xff1a; 四、实验步骤&#xff1a; 五、实验现象、结果记录及整理&#xff1a; 六、分析讨论与思考题解答&#xff1a; 一、实验目的要求&#xff1a; 1、掌握常见DDoS攻击SYN Flood的攻击…

gdb本地调试版本移植至ARM-Linux系统

移植ncurses库 本文使用的ncurses版本为ncurses-5.9.tar.gz 下载地址&#xff1a;https://ftp.gnu.org/gnu/ncurses/ncurses-5.9.tar.gz 1. 将ncurses压缩包拷贝至Linux主机或使用wget命令下载并解压 tar-zxvf ncurses-5.9.tar.gz 2. 解压后进入到ncurses-5.9目录…

解决员工安全隐患的终极方案!迅软DSE答疑员工终端安全管控策略揭秘!

企业终端安全管控对于企事业单位来说至关重要。迅软DSE终端安全系统提供了丰富的终端安全桌面管理策略&#xff0c;可以对终端用户的上网行为和终端操作行为进行管理和控制&#xff0c;从而实现桌面终端的标准化管理&#xff0c;解决终端安全管理问题&#xff0c;并提高员工工作…

阿里云SLB的使用总结

一、什么是SLB 实现k8s的服务service的一种推荐方式&#xff0c;也是服务上云后&#xff0c;替代LVS的一个必选产品。 那么它有什么作用呢&#xff1f; 1、负载均衡&#xff0c;是它与生俱来的。可以配置多个服务器组&#xff1a;包括虚拟服务器组、默认服务器组、主备服务器…

小程序使用Nodejs作为服务端,Nodejs与与MYSQL数据库相连

小程序使用Nodejs作为服务端,Nodejs与与MYSQL数据库相连 一、搭建环境二、配置Nodejs三、与小程序交互四、跨域处理/报错处理五、nodejs连接mysql数据库六、微信小程序连接nodejs报错七、小程序成功与服务端相连,且能操作数据库一、搭建环境 新建空文件夹:Win + R进入cmd命令…

C++STL的list模拟实现

文章目录 前言 list实现push_back迭代器(重点)普通迭代器const迭代器 inserterase析构函数构造函数拷贝构造赋值 vector和list的区别 前言 要实现STL的list, 首先我们还得看一下list的源码。 我们看到这么一个东西&#xff0c;我们知道C兼容C&#xff0c;可以用struct来创建一…

Quartus II + Modelsim 脚本仿真

软件版本&#xff1a;Intel Quartus Prime Design Suite: 23.2 方式参考附件Intel 官方文档&#xff1a;Questa*-Intel FPGA Edition Quick-Start: Intel Quartus Prime Pro Edition 第1步&#xff0c;创建一个ram ip&#xff0c;并形成一个例化的top层ip 第2步&#xff0c;自…

独立完成软件的功能的测试(2)

独立完成软件的功能的测试&#xff08;2&#xff09; &#xff08;12.13&#xff09; 1. 对穷举场景设计测试点&#xff08;等价类划分法&#xff09; 等价类划分法的概念&#xff1a; 说明&#xff1a;数据有共同特征&#xff0c;成功失败分类&#xff1a; 有效&#xff1a…

FPGA使用乘法的方式

FPGA使用乘法的方式 方法一:直接使用乘法符“*” 源代码 module multiply(input [7:0] a,input [7:0] b,output wire [15:0] result);(*use_dsp48 = "yes"*) wire [15:0] result;assign result = a*b; endmodule仿真代码 module multiply_tb();reg [7:0] a; re…

大象慧云:从设立分部到迁移总部 与贵阳贵安共筑税务数字化未来

近年来&#xff0c;贵阳贵安着力提升政务服务水平&#xff0c;通过擦亮“贵人服务”品牌&#xff0c;持续优化营商环境。在这样的环境下&#xff0c;再加上“大数据基因”&#xff0c;对于希望在大数据领域大展拳脚的企业来说&#xff0c;贵阳贵安无疑成为了一个极具吸引力的选…

MySQL笔记-第11章_数据处理之增删改

视频链接&#xff1a;【MySQL数据库入门到大牛&#xff0c;mysql安装到优化&#xff0c;百科全书级&#xff0c;全网天花板】 文章目录 第11章_数据处理之增删改1. 插入数据1.1 实际问题1.2 方式1&#xff1a;VALUES的方式添加1.3 方式2&#xff1a;将查询结果插入到表中 2. 更…