ORB_SLAM3:单目+IMU初始化流程梳理

这篇具有很好参考价值的文章主要介绍了ORB_SLAM3:单目+IMU初始化流程梳理。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

单目+IMU模式下,前面的一些配置完成后,处理第一帧图像时:

1、每帧图像都会调用该函数:

clahe->apply(im,im);

目的:使灰度直方图分布较为均匀,从而使整体对比度更强,便于后面特征点的提取等工作;

2、第一帧图像(ni=0)时无IMU数据(vImuMeas容器为空),进入下面的这个函数:

SLAM.TrackMonocular(im, tframe, vImuMeas);

该函数先是对一些状态进行判断,做出相应的处理。当有IMU数据时,将IMU数据存储到队列mlQueueImuData中,其主要任务是计算当前帧相机的位姿,通过调用下面这个函数来完成;

Sophus::SE3f Tcw = mpTracker->GrabImageMonocular(imToFeed, timestamp, filename);

3、先是将彩色图像转为单通道灰度图像,然后按照是否有IMU和跟踪状态(mState)来构造Frame类,此时跟踪状态mState==NO_IMAGES_YET。当前帧构造Frame类时需要提取5*1500个特征点,初始化成功后只需要提取1500个特征点;

4、Frame构造函数中先是完成帧的ID赋值:

mnId = nNextId++;    // 先赋值再自增1

然后将金字塔的相关参数赋值给成员变量,接下来是对图像进行特征点提取,这时应用的是仿函数,运行的函数为:

int ORBextractor::operator()( InputArray _image, InputArray _mask, vector<KeyPoint>& _keypoints,
                                OutputArray _descriptors, std::vector<int> &vLappingArea)

上面仿函数一些注意的点是:

1)使用四叉树的方式计算每层图像的特征点并进行均匀分配,均匀的特征点可以提高位姿计算精度;2)在计算特征点的描述子之前先对图像进行高斯模糊,主要是为了避免图像噪声的影响;

3)最后需要将金字塔中非0层的特征点坐标恢复到原图像(第0层)的坐标系下,至于界限的意思我没有看懂,后面也不清楚有什么用。

5、提取完特征点后先用OpenCV的矫正函数对特征点去畸变,然后计算去畸变后图像边界(此过程一般是在第一帧或者是相机标定参数发生变化之后进行),最后将特征点分配到图像网格中(每个固定大小的网格记录其里面特征点的索引),目的是加快后期的特征点匹配。

当第一帧图像进Tracking::Track()时:

1、此时mpLastKeyFrame=NULL、mbCreatedMap=false,将跟踪状态mState更新为NOT_INITIALIZED;

2、进行单目初始化,此时mbReadyToInitializate=false,创建初始化关键帧要求当前帧的特征点数多于100个;

3、当前帧满足创建初始化关键帧条件后,更新mInitialFrame、mLastFrame和用于记录"当前帧"所有特征点的mvbPrevMatched,将容器mvIniMatches的所有值都设置为-1,该容器的长度为当前帧特征点的个数;

4、mpImuPreintegratedFromLastKF的Bias设置为0,*mpImuCalib是在读取IMU的yaml文件时设置的。初始化当前帧预积分mCurrentFrame.mpImuPreintegrated = mpImuPreintegratedFromLastKF,最后将mbReadyToInitializate设为true,意为已经创建初始化参考帧,当前帧的变换矩阵Tcw为单位矩阵。

当第二帧图像进Tracking::Track()时:

1、此时有IMU数据,mState=NOT_INITIALIZED、mpLastKeyFrame=NULL,当有异常的时间戳时,需要进行处理;

2、对IMU数据进行预积分,对每帧IMU数据有两种预积分,一种是相对于上一帧,另一种是相对于上一个关键帧;

注:在Frame构造函数中将当前帧的mpPrevFrame=*mLastFrame,陀螺仪输出角速度(rad/s),加速度计输出加速度(m/s2)。

void Tracking::PreintegrateIMU()  // 要求当前帧的上一帧(mpPrevFrame)不为NULL且mlQueueImuData里有数据

该函数主要进行的工作是:

1)进入while(true)中,将符合下面这2个条件的IMU数据存入mvImuFromLastFrame容器中;

条件:a.当前IMU时间戳 ≥ 上一帧时间戳 - mImuPer(0.001s)

b.当前IMU时间戳 < 当前帧时间戳 - mImuPer(0.001s)

结束while(true)的条件:当前IMU时间戳不满足上面的2个条件或mlQueueImuData容器为空;

2)构造IMU预积分处理器(pImuPreintegratedFromLastFrame),偏置使用上一帧的偏置,每帧的mImuCalib都相同(其是在读取IMU的yaml文件时设置的);

3)第一帧IMU数据和最后一帧IMU数据需要单独处理,中间的IMU数据直接处理,主要就是计算前后2帧IMU的平均加速度(acc)、平均角速度(angVel)和两帧之间的时间差(tstep0);

4)mpImuPreintegratedFromLastKF是在Tracking::ParseIMUParamFile(cv::FileStorage &fSettings)中设置的,其中偏置都设置为0;

5)最开始时(即当前帧的上一帧)的dR为单位矩阵,dP、dV均为0。主要计算当前帧相对于上一帧和上一关键帧之间的dP、dV和dR,计算JPa、JPg、JVa、JVg和JRg,最后计算出该时间段的协方差矩阵C;

mpImuPreintegratedFromLastKF->IntegrateNewMeasurement(acc, angVel, tstep);
pImuPreintegratedFromLastFrame->IntegrateNewMeasurement(acc, angVel, tstep);

6)更新当前帧的mpImuPreintegratedFrame(基于上一帧的IMU预积分处理器指针)、mpImuPreintegrated(基于上一关键帧的IMU预积分处理器指针)和mpLastKeyFrame(上一个关键帧指针),最后将当前帧的mbImuPreintegrated设为true,意为当前帧完成了预积分。

当第二帧图像进Tracking::MonocularInitialization()时:

1、此时单目初始化器(mInitialFrame)已创建,mbReadyToInitializate=true,要求当前帧特征点超过100个或mSensor == System::IMU_MONOCULAR且当前帧上一帧的时间戳比单目初始化参考帧的时间戳大于1秒;

2、满足上面的条件后对当前帧与初始化参考帧进行特征点匹配,mvIniMatches容器的索引为初始化参考帧的特征点序号,若初始化参考帧中的该特征点与当前帧有匹配,则该容器对应的值为当前帧特征点序号,否则为-1;

3、先是对两帧中的特征点进行校正,然后通过RANSAC(循环200次)双线程计算基础矩阵F和单应矩阵H,分别记录得分最高的SH和SF对应的H和F矩阵,最后通过条件来判断是通过基础矩阵F还是单应矩阵H进行重建;

4、重建的意思是通过F或H恢复R、t以及满足相应条件恢复出的三维点的个数,最后输出满足相关条件最好的Tcw、重建的地图点和初始化参考帧中哪些特征点成功重建了地图点(存入容器vbTriangulated中);

5、将初始化参考帧作为世界坐标系,因此第一帧变换矩阵为单位矩阵,最后设置当前帧位姿(Tcw)。

Tracking::CreateInitialMapMonocular()函数:

1、将初始化参考帧和当前帧都设置为关键帧,将初始化参考帧的mpImuPreintegrated(基于上一关键帧的IMU预处理器指针)设置为NULL;

2、将初始化参考关帧和当前关键帧的描述子转为BoW,主要是完成mBowVec和mFeatVec容器的赋值,其中mBowVec容器的数据类型为map,第一个数据为单词id,第二个值为权重(weight),如果图像中多个特征点对应同一个单词,则weight会叠加。mFeatVec容器的数据类型为map,第一个数据为节点id(L=2时),第二个数据类型为vector容器,其里面的内容为该节点id包含的描述子索引,该容器的目的是为后面特征点匹配进行加速;注:只有关键帧才会把其的描述子转为Bow

3、用初始化得到的3D点来生成地图点MapPoints,其中mvIniP3D容器中的数据为世界坐标系下点的坐标 :

1)用3D点(世界坐标系下)来构造地图点;

2)为该地图点添加属性:

a.更新观测到该MapPoint的关键帧,容器mObservations中第一个元素为关键帧指针,第二个元素为该地图点对应此关键帧中的特征点索引,同时更新该地图点的观测数目(nObs),双目和RGB相机:nObs=nObs+2,单目相机:nObs=nObs+1;

b.从众多关键帧中能观测到该MapPoint的特征点中挑选最有代表性的描述子,地图点最好的描述子与其它能观测到该地图点的特征点的描述子应该具有最小的距离中值;注:由于一个MapPoint会被许多相机观测到,因此在插入关键帧后,需要判断是否更新当前MapPoint最有代表性的描述子。

c.更新该MapPoint平均观测方向以及观测距离的范围。

3)更新关键帧间的连接关系,每个边有一个权重,边的权重是该关键帧与当前关键帧公共3D点的个数;

4)全局BA优化,优化当前关键帧的位姿和MapPoint;

单目初始化之后,得到的初始地图中的所有点都是局部地图点。

5)mState = OK,此时单目初始化全部完成。文章来源地址https://www.toymoban.com/news/detail-688089.html

到了这里,关于ORB_SLAM3:单目+IMU初始化流程梳理的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【ORB_SLAM】Ubuntu20.04 配置ORB_SLAM3

    本文主要记录基于Ubuntu20.04环境下,对普通的ORB_SLAM3和稠密版本的ORB_SLAM3进行环境的配置。 这里采用鱼香ros的一键安装,感谢小鱼的一键安装。 Pangolin:链接: https://pan.baidu.com/s/1FXYLsEK1W3xmX0m_Vqylag 提取码: jgz2 (基于小六的注释后的ORB_SLAM3代码) https://github.com/electech6/ORB_SLAM3_d

    2024年02月15日
    浏览(56)
  • SIM初始化流程

    ATR(Answer To Reset):复位应答信号,有SIM卡传输给终端,包括SIM卡自身的一些信息,比如支持的传输速率,传输模式等。   SIM卡的ATR代表\\\"Answer to Reset\\\",即复位响应。当SIM卡被插入设备中时,设备会向SIM卡发送一个复位命令,以获取SIM卡的响应。 SIM卡会回复一个ATR,其中包含有

    2024年02月04日
    浏览(49)
  • OpenCV迭代去畸变undistortPoints 与vins的迭代不同 第二章vins前端 第三章imu预积分 第四章vio初始化

    OpenCV去畸变undistortPoints原理解析 不动点迭代法—单变量非线性方程近似根matlab求解 淦VINS-MONO源码 03–openCV与VINS中去畸变方法的不同 这里用的方法和openCV不同,假设现在求A点的去畸变坐标,那么我们将A的坐标直接代入畸变模型中,求得再次畸变的坐标,并求得这个坐标和

    2024年02月09日
    浏览(61)
  • Android 11属性系统初始化流程

    在init进程启动的第二阶段,调用PropertyInit 对属性系统进行初始化 PropertyInit函数在systemcoreinitproperty_service.cpp 中实现 注释1处在dev下创建__properties__文件夹。注释2处会收集读取各个分区下的property_contexts文件,将读取到的信息系列化之后,写到/dev/ properties /property_info文件中。

    2024年04月09日
    浏览(64)
  • ORB_SLAM2运行KITTI数据集

            在前文我们已经安装运行了ORB_SLAM2,下载和编译(包括报错)在文章: ORB_SLAM2下载编译及运行EuRoC数据集_浅梦语11的博客-CSDN博客_euroc数据集下载         并且我们使用运行了EuRoC数据集。今天利用框架运行KITTI数据集。         注意 :如果没有运行成功EuRoC数据

    2024年02月08日
    浏览(38)
  • ORB_SLAM3 LocalMapping中CreateNewMapPoints

    CreateNewMapPoints 在 新插入的关键帧 的 邻近的关键帧 中,通过 词袋模型 与新插入关键帧中 没有匹配的 ORB特征进行匹配,并抛弃其中 不满足对极约束 的匹配点对,接着通过 三角化 生成地图点 GetBestCovisibilityKeyFrames :找出与当前关键帧 共视程度最高前nn帧 vpNeighKFs 如果是 I

    2024年02月01日
    浏览(58)
  • 【ORB_SLAM2算法中逐函数讲解】

    在ORB-SLAM2算法中, TrackReferenceKeyFrame() 函数主要用于根据参考关键帧(Reference KeyFrame)来进行相机位姿估计。这个函数在跟踪过程中起到关键作用,它使用当前帧与参考关键帧之间的匹配点进行位姿估计,从而实现视觉里程计的功能。以下是这个函数中的主要操作: 计算当前

    2023年04月25日
    浏览(41)
  • UE4 源码解析----引擎初始化流程

       在研究UE4的源码过程中着实不理解的地方有很多,今天给大家分享一下UE4引擎的初始化流程。 C++的函数入口都是Main() 函数入口,UE4也是一样,EngineSourceRuntimeLaunchPrivate Windows函数入口  引擎入口函数为:GuardedMain UE4所有相关的代码都在游戏循环函数中,在Launch.cpp中,写

    2024年02月06日
    浏览(86)
  • 【Git】初始化仓库配置与本地仓库提交流程

    目录 一、仓库配置邮箱与用户名 二、本地仓库提交流程 【Git】Linux服务器Centos环境下安装Git与创建本地仓库_centos git仓库搭建_1373i的博客-CSDN博客 https://blog.csdn.net/qq_61903414/article/details/131260033?spm=1001.2014.3001.5501 在之前的文章里我们学习了如何在centos系统上安装git以及使用gi

    2024年02月15日
    浏览(51)
  • 【PostgreSQL】Ubuntu 下使用 Prisma 的初始化流程

    步骤如下: 创建 Ubuntu 用户 创建 PostgreSQL 用户 使用 postgres 用户登录,然后创建新用户: 设置用户密码 使用 postgres 或 projectname 用户登录,设置用户密码: 完成上面准备工作就ok了,不需要手工创建数据库,因为下面将由 Prisma 来创建数据库。 Prisma 初始化 schema.prisma 创建好

    2024年01月18日
    浏览(67)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包