CL关于ORB_SLAM的那些事(Sim3Solver)

sim3在orbslam2与gis中的应用 im3简单来说,就是使用3对匹配点来进行相似变换(similarity transformation)的求解,进而解出两个坐标系之间的旋转矩阵、平移向量和尺度。ORB-SLAM2中使用的sim3求解方法来自 Horn 1987, Closed-form solution of absolute orientation using unit quaternions 这篇论文。 阅读详情

Sim3Solver部分的学习总结

刚刚看完关于PnP方面的代码,那就趁热打铁继续阅读关于Sim3Solver部分的代码吧,开始吧!

.h部分的阅读

该头文件里包含了关键帧的头文件维护的变量(protected)有:
两个关键帧指针存放1帧坐标系下的3D点坐标的容器
存放2帧坐标系下的3D点坐标的容器存放1帧内的MapPoints的容器
存放2帧内的MapPoints的容器存放两帧匹配上的MapPoint的容器
存放索引值的容器
存放1帧的Sigma平方数的容器
存放2帧的Sigma平方数的容器
存放1最大误差的容器
存放2最大误差的容器
int整型的N和mN1
Mat类型1到2的旋转矩阵、平移矩阵和尺度因子
Mat类型1到2的变换矩阵和2到1的变换矩阵
存放内点标志位的bool容器
定义int整型的内点数量
定义int整型的迭代次数
定义存放是否是最好内点的标志位的容器
定义int整型的最好内点的数量
定义Mat最好的2到1的变换矩阵
定义Mat最好的旋转矩阵
定义Mat最好的平移矩阵
定义最好的尺度因子
定义是否固定尺度因子的标志位
定义存放随机选择的所有索引的容器
定义存放1帧内的投影坐标的容器
定义存放2帧内的投影坐标的容器
定义Ransac的概率
定义Ransac的最小内点数
定义Ransac的最大迭代次数
定义内外点判断的阈值
定义Sigma的平方数
定义帧1的内参矩阵
定义帧2的内存矩阵

该头文件里中的function有:
构造函数
设置Ransac的参数函数,这边默认的概率为0.99,最小的内点数为6,最大的迭代次数为300
寻找的函数
迭代的函数
获取估计的旋转矩阵的函数
获取估计的平移矩阵的函数
获取估计的尺度因子的函数
#############下面的函数是protected###############
计算中心店坐标函数
计算Sim3的函数
校核内点的函数
投影函数
从相机到图像的函数

function by function

先看一下.cpp文件中除了包含了自己的头文件之后,还有其他哪些头文件:

  1. KeyFrame
  2. ORBmatcher
  3. 词袋DBoW2

构造函数
Sim3Solver()
函数的参数列表:关键帧1、关键帧2、存放匹配的MapPoint的容器、是否固定尺度因子的标志位
用列表初始化的方式,初始化迭代的次数为0,最好的内点数量为0,固定初度因子的标志位为传入的参数
将传入的1和2的关键帧赋值给维护变量
获取1关键帧的能匹配上的MapPoint,将这些MapPoint存入容器内
获取当前两帧关键帧之间匹配上的MapPoint的数量
用这个数量来初始化1和2关键帧中存放MapPoint的容器的大小
将匹配上的MapPoint容器赋值给维护变量
继续用上面的数量初始化1索引容器的大小、1和2的关键帧中存放3D点的容器的大小
分别获取两关键帧的Pose信息(旋转矩阵和平移向量)
继续用上面的数量初始化存放所有索引的容器的大小
定义初始化索引为0
循环遍历匹配上的MapPoint,判断其是否有MapPoint,获取两帧中对于这个MapPoint的指针,如果该点在两帧中都是good情况下,获取其对应的像素坐标的索引,在索引都大于0的情况下,获取两帧中该点对应的像素坐标,并获取该点对应的sigma的平方值,定义最大误差为9.21倍的sigma平方存入最大误差内,存入对应MapPoint和索引值,获取该点在世界坐标系下的坐标,利用之前的Pose信息转换到两个相机坐标系下,存入相机坐标系下的3D坐标容器内,存入定义的索引值,索引值++
获取两帧的内参
相机1和2分别调用FromCameraToImage()函数,传入相机坐标系下的3D点坐标、存放2D像素坐标的容器和内参
调用SetRansacParameters()函数,设置Ransac的参数

设置Ransac的参数
SetRansacParameters()
函数的参数列表:概率值、最小的内点数量和最大迭代次数
将传入的参数,分别赋值给Ransac的概率、Ransac最小的内点数量和Ransac最大的迭代次数
获取匹配上的点对的数量
用这个数量来初始化内点容器的大小
定义一个值epsilon:Ransac最小内点数量/所有的点数
定义迭代的数量变量
如果Ransac最小内点数等于所有的点数,迭代次数为1;
如果不是,迭代次数等于((1-Ransac的概率)的对数/(1-epsilon的三次方)的对数)的ceil
Ransac的最大迭代次数为:上面计算的迭代次数和传入的最大迭代次数的较小者,选出的较小者与1比的较大者为Ransac的最大迭代次数。
mn的迭代次数赋值为0。

迭代函数
iterate()
函数的参数列表:迭代的次数、不再进行迭代的标志位、存放内点标志位的容器和内点的数量
初始化传入的不再进行迭代的标志为false
初始化存放内点标志位的容器的大小为匹配上的点数,初值都为false
初始化传入的内点数为0
如果匹配上的点数小于Ransac的最小内点数,将不再进行迭代的标志置true,返回空Mat
定义存放可获取索引的容器
定义Mat的三维点矩阵
定义当前迭代的次数为0
while循环(满足mn迭代次数小Ransac的最大迭代次数,且当前迭代次数小于迭代次数),当前迭代次数++,mn迭代次数++,将存放所有索引值的容器赋值给存放可获得索引值的容器,循环三次,随机选取3个MapPoint,将其对应在相机坐标系内的3D坐标分别存放在上面定义的三维点矩阵内,每一个对应一列,挑选过的索引将会被删除,避免抽到同一个点。调用ComputeSim3()函数计算Sim3矩阵,传入3组对应的点。调用CheckInliers()函数,进行内点数的检测。如果内点数不小于最好的内点数,将此时的mvb的内点数赋值给最好的mvb内点数,将此时的mn的内点数赋值给最好的mn内点数,赋值最好的变换矩阵、旋转矩阵和平移矩阵,最重要的是尺度因子也赋值给最好的尺度因子。如果mn内点数大于Ransac最小内点数,将mn内点数赋值给n内点数,循环标记内点的标记位,返回最好的两帧之间的变换矩阵。
如果循环结束后,还是没找到最好的变换矩阵,如果mn迭代的次数不小于Ransac最大的迭代次数,不再迭代的标志位置true,返回空的Mat。

寻找函数
find()
函数的参数列表:12的内点情况的容器和迭代的次数
定义bool的flag标志位
调用刚刚介绍的iterate()函数,返回计算得到的变换矩阵

计算形心坐标
ComputeCentroid()
函数的参数列表:Mat的三维点的矩阵、去形心的三维坐标和形心的坐标
调用opencv中的reduce()函数,按列累加,输出给形心坐标
将形心坐标除上列数(点的数量),得到真正的形心坐标
循环得到去形心的三维坐标

计算Sim3函数
ComputeSim3()
函数的参数列表:两帧内的3D坐标
定义点与点之前的相对坐标
定义形心的坐标
调用刚刚说的ComputeCentroid(),计算得到相对的坐标和形心坐标
构建M矩阵,帧2内的相对坐标乘上帧1内的坐标的转置
定义N矩阵,对称矩阵,如下图所示
在这里插入图片描述
定义Mat的特征值和特征向量
调用opencv中的eigen()函数求解N矩阵的特征值和特征向量
将特征向量的矩阵第一行第二列到第4列取出赋值给1行3列的vec变量
下面的操作就是怎么把现有的四元数转换成旋转矩阵,现将四元数转换成欧拉角,然后利用罗德里格斯公式计算得到旋转矩阵。
具体的公式如下图:
在这里插入图片描述
计算得到旋转矩阵之后,将2帧中取形心的点集乘上这个旋转矩阵。
如果没有固定尺寸,计算尺度因子,用Mat的dot函数,计算点集1和点集2之间的值
在这里插入图片描述
如果是固定尺寸,那么尺度因子为1。
将平移向量创建为1行3列
平移向量直接等于1帧的形心坐标-尺度因子×旋转矩阵×2帧的形心坐标
创建变换矩阵的大小和类型
将计算好的尺度、旋转和平移矩阵填充到变换矩阵中。
另外还要构建一个逆变换矩阵。

校核内点的函数
CheckInliers()
定义存放Mat的类型的容器P1和P2
调用Project()函数进行3D坐标的投影
初始化内点的数量为0
循环投影的点,计算在帧1和帧2中的像素误差,取误差的平方和,如果两边的误差少于最大的误差,该点就是内点,内点的数量++,如果不满足,那就不是内点。

获取估计的旋转矩阵
GetEstimatedRotation()
直接返回最好的旋转矩阵

获取估计的平移矩阵
GetEstimatedTranslation()
直接返回最好的平移矩阵

获取估计的尺度
GetEstimatedScale()
直接返回最好的尺度

投影函数
Project()
函数的参数列表:3D坐标容器、2D坐标容器、变换矩阵和内参矩阵
取出变换矩阵中的旋转和平移矩阵
取出内参矩阵的元素
将2D坐标容器清空
重新设置该容器的大小
循环遍历3D点,利用投影公式计算2D坐标并将其存入容器内。

从相机到图像
FromCameraToImage()
函数的参数列表:3D点坐标容器、2D点坐标容器和内参矩阵
取出内参矩阵中的元素(焦距和光心坐标)
将2D坐标容器清空
重新设置该容器的大小
循环遍历3D点,利用投影公式计算2D坐标并将其存入容器内。

时间:2019年09月15日
作者:hhuchen
机构:河海大学机电工程学院

【逐函数详细讲解ORB_SLAM2算法和C++代码|Sim3Solver|1-23】 该类接受两个关键帧和它们之间的一组匹配的地图点作为输入,然后使用RANSAC方法迭代地优化Sim(3)变换。估计的变换包括旋转、平移和尺度信息。使用两个关键帧、一组匹配的地图点和一个可选的布尔参数来初始化Sim3Solver对象,以固定比例。定义了一个命名空间,封装了与ORB-SLAM2相关的类和函数,以避免命名冲突。分别来自OpenCV和C++标准库,用于存储矩阵、动态数组和大小信息。,存储对象的状态,包括关键帧、地图点和算法中使用的其他变量。声明了具有相应输入和输出参数的成员函数,如。 阅读详情

相关推荐

【逐函数详细讲解ORB_SLAM2算法和C++代码|PnPsolver|1-22】

类在ORB-SLAM2系统中负责计算相机位姿,它使用EPnP算法从2D-3D点对之间的关系中进行估计。同时,使用RANSAC方法提高鲁棒性,剔除异常值。它实现了一种名为EPnP(Efficient Perspective-n-Point)的算法,该算法能够从2D-3D点对之间的关系中估计相机的位姿。类中还定义了许多私有方法,主要用于实现EPnP算法的内部计算和RANSAC迭代过程。

小秋 AI SLAM 入门实战教程 529

ORBSLAM3整体框架

对ORBSLAM3原理及代码进行详细解读

weixin_45850350的博客 5300

深入解析UVM寄存器模型:reg2bus与bus2reg的隐式调用机制

本文深入解析了UVM寄存器模型中reg2bus与bus2reg函数的隐式调用机制。通过追踪一次寄存器访问的完整旅程,揭示了这两个关键函数是如何在uvm_reg_map和uvm_reg_predictor中被框架自动调用的,从而在抽象的寄存器操作与具体总线事务之间完成转换,并实现镜像值的自动更新。掌握此机制是高效调试和灵活应用UVM寄存器模型的基础。

weixin_29211309的博客 441

ORB-SLAM3 从理论到代码实现(五):sim3 优化

摘要:本文分析了ORB-SLAM3中Optimizer::OptimizeSim3()函数的实现,该函数用于优化两个关键帧之间的Sim3变换。首先初始化g2o优化器,添加Sim3顶点和地图点顶点;然后通过双向投影构建边约束,利用L-M算法进行优化;最后剔除误差较大的边并再次优化,得到精确的Sim3变换。该函数被闭环检测线程调用,通过双向重投影误差优化候选关键帧到当前帧的Sim3变换,为后续闭环校正提供准确的位姿约束。

人无远虑,必有近忧 1600

微信小程序-如何根据缩放屏幕大小自适应icon图标更改marker

微信小程序如何根据用户的缩放屏幕来改变marker图标icon的大小,实现icon自适应屏幕缩放的效果

Bartender_VA11的博客 3980

多层感知机 Multilayer Perceptron | MLP

本文主要简单介绍了多层感知机的基本概念,优缺点,应用场景,建模时的注意事项,评价指标,实现方法,python示例和模型的参数等。

JasonH2021的博客 3万+

ORB_SLAM2中的Sim3变换

对于双目、RGB-D相机,可获得深度,因此不存在尺度问题,因此Sim3中的尺度s=1。 (1)通过词袋加速算法实现当前帧、闭环帧的特征点的匹配,建立闭环帧的路标点和当前帧的特征点间的联系。 (2)使用RANSAC法,随机采取3对点(根据特征点的索引,获得当前帧中的路标点(局部建图时获得)及对应的闭环帧中的路标点(步骤(1)中获得)),计算两帧间的Sim3变换。一共迭代5次,如果有一次,获得的内点数大于20,就认为成功。 (3)根据Sim3变换,将闭环帧的路标点投影至当前帧中进行匹配。随后优化Sim3矩阵。

lovely_yoshino的博客 4504

告别CPU空转!用STC8的SPI+DMA高效驱动上百颗WS2812B灯珠

本文详细解析了如何利用STC8单片机的SPI+DMA外设高效驱动WS2812B全彩灯珠,解决传统软件延时驱动方式在长灯带应用中的性能瓶颈。通过硬件方案设计、数据格式转换和DMA传输配置,实现高达400Hz的刷新率和低于5%的CPU占用率,适用于大规模灯光项目。

weixin_30847939的博客 397

软件工程应用与实践第七篇

ORB-SLAM3 Sim3Solver.cc相关代码分析与理解 2021SC@SDUSC 文章目录ORB-SLAM3 Sim3Solver.cc相关代码分析与理解前言一、MapPoints初始化的相关内容二、代码分析 前言 这一篇主要是Sim3Solver剩余一些函数的分析 一、MapPoints初始化的相关内容 1.初始化阶段的创建 在Track()函数中调用了各类初始化函数,如双目初始化函数StereoInitialization()、单目初始化函数MonocularInitializatio

m0_46689170的博客 263

某讯天御滑块验证码逆向实战:从参数解析到环境对抗

本文详细解析了某讯天御滑块验证码的逆向工程实战技巧,从关键参数解析到浏览器环境模拟对抗。重点介绍了collect、eks等参数的逆向思路,以及如何通过puppeteer等工具补全环境检测,帮助开发者有效突破验证码防护。文章还提供了常见错误解决方案和性能优化建议,是验证码逆向领域的实用指南。

weixin_29325007的博客 440

RV1126B RV1126B-P 瑞芯微 高性能视觉处理器SoC 芯片

它集成了大量算法加速器,如 HDR、3A、LSC、3DNR、2DNR、锐化、去雾、鱼眼校正、伽马校正、特征点检测等。此外,还配备了一款最多8兆像素的 AI-ISP,作为对传统ISP 的补充,以提供卓越的空间去噪性能和增强的图像增强效果。除了先前的高性能多媒体区块外,RV1126B还包含丰富的音频、内存和其他外围接口,如I2C、SPI、PWM等。借助这-特性,来自相机的视频可以以高分辨率进行编码,并存储在本地内存中,同时还能将另-段较低分辨率的视频传输到云存储。

szhorsway的博客 1862

CL关于ORB_SLAM的那些事(PnPsolver)

PnPsolver部分的学习总结 之前看的代码基本都是整个部分的功能,今天开始看一些求解器的cpp,主要就是两个吧,PnPsolver还有Sim3Solver。 ,开始吧! .h部分的浏览 包含的头文件有,opencv、MapPoint.h、Frame.h PnPsolver类维护的变量(都是私有的): double uc, vc, fu, fv:内参? double * pws, * us, *...

EyeToTheWorld的博客 1264

【开源~磁悬浮】零代码,纯硬件闭环:从霍尔到H桥的磁悬浮稳定术

本文详细介绍了如何不依赖任何代码,仅通过模拟和数字电路的组合,实现一个完整的磁悬浮闭环控制系统。从霍尔传感器检测位置,到运放电路进行信号调理与模拟PID控制,再到H桥驱动电磁铁执行纠偏,全程使用基础电子元器件搭建。文章深入剖析了系统原理、电路设计、调试技巧与实践经验,展现了纯硬件实现自动控制的独特魅力与挑战。

perl8的博客 622

ORB-SLAM2代码阅读笔记(十):sim3求解

Table of Contents 1.sim3的简单概述 2.sim3算法介绍 1)3对匹配的3D点建立坐标系 2)旋转矩阵计算 3)平移向量计算 4)尺度计算 3.代码解析 1)sim3求解器构造函数Sim3Solver 2)sim3迭代求解Sim3Solver::iterate 本篇笔记对 ORB-SLAM2代码阅读笔记(八):LoopClosing线程 中提到的s...

1万+

【基础-多选】HarmonyOS鸿蒙应用开发

1、HarmonyOS提供了基础的应用加固安全能力,包括混淆、加密和代码签名能力。正确2、可以通过ohpm uninstall 指令下载指定的三方库。错误3、支持模块化开发是指一个应用通常会包含多种功能,将不同的功能特性按模块来划分和管理是一种良好的设计方式。在开发过程中,我们可以将每个功能模块作为一个独立的Module进行开发,Module中可以包含源代码、资源文件、第三方库、配置文件等,每一个Module可以独立编译,实现特定的功能。这种模块化、松耦合的应用管理方式有助于应用的开发、维护与扩展。正确。

江拥羡橙的博客 1万+

IMSL CNL 7.0.0 (x86-64)Crack

IMSL CNL 7.0.0 (x86-64)Crack intel的算法库破解文件,这是C++版本的破解文件

ORB-SLAM3理解

ORB-SLAM3理解 长期更新

泠山的博客 8246

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

ORB-SLAM2中SIM3求解中RANSAC的应用

在Sim3Solver.cc文件中的第153行SetRansacParameters()函数 /** * @brief 设置进行RANSAC时的参数 * * @param[in] probability 当前这些匹配点的置信度,也就是一次采样恰好都是内点的概率 * @param[in] minInliers 完成RANSAC所需要的最少内点个数 * @param[in] maxIterations 设定的最大迭代次数 */ void S

YMWM_的博客 904

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

ORB-SLAM2 从理论到代码实现(十):LoopClosing 程序详解

本文详细介绍了ORB-SLAM2系统中的LoopClosing闭环检测类。该类通过检测闭环候选帧、计算Sim3变换、优化位姿图等步骤实现闭环修正。核心功能包括:1)检测闭环候选帧并验证连续性;2)通过RANSAC和优化计算关键帧间的Sim3变换;3)使用图优化和全局BA进行闭环校正。文中详细分析了DetectLoop、ComputeSim3和CorrectLoop等关键方法的实现流程,包括特征匹配、位姿优化、地图点融合等关键技术。该系统能有效处理单目、双目和RGB-D相机的闭环检测,提高SLAM系统的全局一

人无远虑,必有近忧 897

相似变换Sim3推导(C++实现)

  C++实现: #include <iostream> #include <opencv2/opencv.hpp> using namespace cv; using namespace std; Mat ComputeSim3(Mat &P1, Mat &P2); // Sim3仿真 void main() { Mat p1_c1 = (...

A_L_A_N 2193

(01)ORB-SLAM2源码无死角解析-(58) 闭环线程→计算Sim3: 源码Sim3Solver::iterate()讲解

讲解关于slam一系列文章汇总链接:史上最全slam从零开始,针对于本栏目讲解的(01)ORB-SLAM2源码无死角解析链接如下(本文内容来自计算机视觉life ORB-SLAM2 课程课件): (01)ORB-SLAM2源码无死角解析-(00)目录_最新无死角讲解:https://blog.youkuaiyun.com/weixin_43013761/article/details/123092196 文末正下方中心提供了本人联系方式,点击本人照片即可显示WX→官方认证{\color{blue}{文末正下方中心}

江南才尽江南山,年少无知年少狂! 862

orb-slam系列 LoopClosing线程 ComputeSim3(十一)

ComputeSim3 /******************************** * 计算每一个回环候选关键帧与当前关键帧之间的相似矩阵 * 1. 首先通过BOW向量将回环候选关键帧和当前关键帧进行匹配,得到匹配地图点,通过匹配地图点初始化相似矩阵求解器 * 2. 遍历所有的回环候选关键帧和当前关键帧计算sim矩阵,并优化sim矩阵,根据优化sim矩阵确定匹配内点数量,从...

qq_18834185的博客 671

ORBSLAM2学习笔记11(Sim3Solver)

Sim3Solver.h /** * This file is part of ORB-SLAM2. * * Copyright (C) 2014-2016 Raúl Mur-Artal <raulmur at unizar dot es> (University of Zaragoza) * For more information see <https://github.com/raulmur/ORB_SLAM2> * * ORB-SLAM2 is free software:

Bobsweetie的专栏 778

ORBSLAM2理论与实战(24) 代码解读Sim3solver类

Sim3solver类 Sim3solver.h #ifndef SIM3SOLVER_H #define SIM3SOLVER_H #include <opencv2/opencv.hpp> #include <vector> #include "KeyFrame.h" namespace ORB_SLAM2 { class Sim3Solver { ...

算法攻城狮 1289

ORB-SLAM中LoopClosing线程的sim3计算

参考论文:http://people.csail.mit.edu/bkph/papers/Absolute_Orientation.pdf 参考ORB-SLAM源码详解 sim3计算:R t s   ORB-SLAM 源码中的文件Sim3Slover.cc void Sim3Solver::ComputeCentroid(cv::Mat &amp;P, cv::Mat ...

qq_37611824的博客 1627

sim3优化的理解

sim3变换就是相似变换:p2=sRp1+t s是一个缩放系数。可以这么理解,p1在旋转后,又被放大了s倍。但是之前的平移量t没有发生变化,随意乘以s和不乘s的效果是t的作用变小了s倍。也就有了下面的关系: p2/s=Rp1+t/s 对比两个表达,s的引入就是让结果整体小了s倍。 其实s的作用就是把一个物体放大或者缩小。 如果我们有个两个变换相加:A+B=C 如果A是带scale变化的...

ziliwangmoe的博客 4642
上一篇: CL关于SLAM优化的推导和理解
下一篇: CL关于ORB_SLAM的那些事(LocalMapping)
EyeToTheWorld
博客等级 码龄10年 25粉丝 26原创
评论 2
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值