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=0Eigen::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)

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【Spark精讲】RDD特性之数据本地化

首选运行位置 上图红框为RDD的特性五&#xff1a;每个RDD的每个分区都有一组首选运行位置&#xff0c;用于标识RDD的这个分区数据最好能够在哪台主机上运行。通过RDD的首选运行位置可以让RDD的某个分区的计算任务直接在指定的主机上运行&#xff0c;从而实现了移动计算而不是移…

【matlab进阶学习-6】 读取log数据data.txt文件,并做处理,导出报告/表格/图表

原始文件 原始文件格式txt&#xff0c;每一行对应一个数据&#xff0c;数据之间由逗号分割开 对应意思 时刻&#xff0c;电压&#xff0c;电流&#xff0c;功率&#xff0c;容量&#xff0c;&#xff0c;电流&#xff0c;功率&#xff0c;&#xff0c;RTC时间&#xff0c;状态…

内网服务器部署maven私服简记

前言 很多企业希望创建自己的maven私服&#xff0c;但服务器无法和外网连通&#xff0c;所以这里介绍一套完整的内网部署nexus的解决方案。实现的方式也很简单&#xff0c;将下载好的nexus安装和项目所需的依赖仓库都上传到服务i去上去&#xff0c;通过脚本的方式实现批量导入…

CSS的三大特性(层叠性、继承性、优先级---------很重要)

CSS 有三个非常重要的三个特性&#xff1a;层叠性、继承性、优先级。 层叠性 场景&#xff1a;相同选择器给设置相同的样式&#xff0c;此时一个样式就会覆盖&#xff08;层叠&#xff09;另一个冲突的样式。层叠性主要解决样式冲突 的问题 原则&#xff1a;  样式冲突&am…

autojs-练手-视频号点赞(进阶版)

注释很详细&#xff0c;直接上代码 较初阶版新增内容 1. 简单但好用的ui界面 为方便大家参考&#xff0c;ui界面的模板单独拿出来了 ui界面模板 2. opencv图像识别 3. 需加载情况特殊处理&#xff08;防卡壳&#xff09; 4. 增加自动判断是否已点赞的情况 源码部分 // 启用…

HarmonyOS4.0从零开始的开发教程14Web组件的使用

HarmonyOS&#xff08;十二&#xff09;Web组件的使用 1 概述 相信大家都遇到过这样的场景&#xff0c;有时候我们点击应用的页面&#xff0c;会跳转到一个类似浏览器加载的页面&#xff0c;加载完成后&#xff0c;才显示这个页面的具体内容&#xff0c;这个加载和显示网页的…

智能优化算法应用:基于水循环算法3D无线传感器网络(WSN)覆盖优化 - 附代码

智能优化算法应用&#xff1a;基于水循环算法3D无线传感器网络(WSN)覆盖优化 - 附代码 文章目录 智能优化算法应用&#xff1a;基于水循环算法3D无线传感器网络(WSN)覆盖优化 - 附代码1.无线传感网络节点模型2.覆盖数学模型及分析3.水循环算法4.实验参数设定5.算法结果6.参考文…

无需公网IP联机Minecraft,我的世界服务器本地搭建教程

目录 前言 1.Mcsmanager安装 2.创建Minecraft服务器 3.本地测试联机 4. 内网穿透 4.1 安装cpolar内网穿透 4.2 创建隧道映射内网端口 5.远程联机测试 6. 配置固定远程联机端口地址 6.1 保留一个固定TCP地址 6.2 配置固定TCP地址 7. 使用固定公网地址远程联机 8.总…

Vue 中 v-model 的修饰符

lazy 修饰符&#xff1a;将 v-model 改为失去焦点后更新数据。 number 修饰符&#xff1a;将 v-model 数据转为数字类型。 trim 修饰符&#xff1a;去除 v-model 数据中的首尾空格。 语法格式&#xff1a; // lazy 修饰符 <input v-model.lazy"数据"> // nu…

靠谱的车- 华为OD统一考试(C卷)

靠谱的车- 华为OD统一考试&#xff08;C卷&#xff09; OD统一考试&#xff08;C卷&#xff09; 分值&#xff1a; 100分 题解&#xff1a; Java / Python / C 题目描述 程序员小明打了一辆出租车去上班。出于职业敏感&#xff0c;他注意到这辆出租车的计费表有点问题&#xf…

【JNA与C++基本使用示例】

JNA中java与C使用注意事项和代码示例 JNA关系映射表使用案列注意代码示例C代码java代码 JNA关系映射表 使用案列 注意 JNA只支持C方式的dll使用C的char* 作为返回值时&#xff0c;需要返回的变量为malloc分配的地址C的strlen函数只获得除/0以外的字符串长度 代码示例 C代码…

基于PaddleNLP的深度学习对文本自动添加标点符号(一)

前言 目前以深度学习对文本自动添加标点符号研究很少&#xff0c;已知的开源项目并不多&#xff0c;详细的介绍就更少了&#xff0c;但对文本自动添加标点符号又在古文识别语音识别上有重大应用。 基于此&#xff0c;本文开始讲解基于PaddleNLP的深度学习对文本自动添加标点符号…

鸿蒙开发之状态管理@Prop和@Link

一、用法 在父子组件需要进行数据同步的时候&#xff0c;可以通过Prop和Link装饰器来做到。在父组件中用State装饰&#xff0c;在自组件中用Prop或Link装饰。 结论&#xff1a;Prop用于子组件只监听父组件的数据改变而改变&#xff0c;自己不对数据改变 Link用于子组件与父组…

Proxmox VE 安装 OpenWrt 配置旁路由教程

话不多说&#xff0c;本篇文章将记录如何在 Proxmox VE 环境通过虚拟机安装 OpenWrt 配置旁路由的过程&#xff0c;仅做参考。 PVE 创建虚拟机 名称随意&#xff0c;GuestOS 选择 Linux&#xff0c;不使用任何 iso 镜像。&#xff08;记住你的 VMID&#xff09; 清空将要创建…

机器学习---Adaboost算法

1. Adaboost算法介绍 Adaboost是一种迭代算法&#xff0c;其核心思想是针对同一个训练集训练不同的分类器&#xff08;弱分类器&#xff09;&#xff0c;然 后把这些弱分类器集合起来&#xff0c;构成一个更强的最终分类器&#xff08;强分类器&#xff09;。Adaboost算法本身…

Qt 线程

&#x1f4a1; 进度条显示拷贝进度&#xff08;verson 1&#xff09; 窗口上放置一个按钮和一个进度条部件&#xff0c;点击按钮&#xff0c;进行拷贝操作 —— 打开对话框选择源文件&#xff0c;然后再打开一个对话框 选择 目标文件存放位置和名称。拷贝过程中进度条显示当前…

十三、YARN资源分配调用

1、为什么要先学习YARN组件&#xff1f; 在Hadoop文件系统中&#xff0c;YARN作为Hadoop系统的第三大组件&#xff0c;其中&#xff0c;第二大组件MapReduce组件是基于YARN运行的&#xff0c;即没有YARN无法运行MapReduce程序&#xff0c;所以需要同时学习YARN。 2、YARN &…

Day58力扣打卡

打卡记录 下一个更大元素 IV&#xff08;单调栈 x2&#xff09; 链接 class Solution:def secondGreaterElement(self, nums: List[int]) -> List[int]:ans [-1] * len(nums)s []t []for i, x in enumerate(nums):while t and nums[t[-1]] < x:ans[t.pop()] x # t…

『npm』一条命令快速配置npm淘宝国内镜像

&#x1f4e3;读完这篇文章里你能收获到 一条命令快速切换至淘宝镜像恢复官方镜像 文章目录 一、设置淘宝镜像源二、恢复官方镜像源三、查看当前使用的镜像 一、设置淘宝镜像源 npm config set registry https://registry.npm.taobao.org服务器建议全局设置 sudo npm config…

科技提升安全,基于YOLOv6开发构建商超扶梯场景下行人安全行为姿态检测识别系统

在商超等人流量较为密集的场景下经常会报道出现一些行人在扶梯上摔倒、受伤等问题&#xff0c;随着AI技术的快速发展与不断普及&#xff0c;越来越多的商超、地铁等场景开始加装专用的安全检测预警系统&#xff0c;核心工作原理即使AI模型与摄像头图像视频流的实时计算&#xf…