ORB -SLAM2 ---- Tracking::Tracking和GrabImageStereo

embedded/2024/10/22 7:15:30/

文章目录

  • 一、Tracking::Tracking
    • 1. 函数讲解,
    • 2. 函数源码
  • 一、GrabImageStereo()
    • 1. 函数讲解
    • 2. 函数源码
  • 三、 学习方法(路线)
  • 四、总结

一、Tracking::Tracking

1. 函数讲解,

这是Tracking中的构造函数,此函数的主要作用是为在初始化(初始化追踪线程)的时候使用,主要作用是:

  1. 获取相机的内参
  2. 初始化相机的内参矩阵
  3. 初始化畸变系数
  4. 初始化帧率
  5. 输出相机参数(RGB相机还要输出颜色通道顺序)
  6. 读取图像信息
  7. 初始化特征特取器(双目则初始化左右目)
  8. 输出图像信息

2. 函数源码

Tracking::Tracking(System *pSys, ORBVocabulary* pVoc, FrameDrawer *pFrameDrawer, MapDrawer *pMapDrawer, Map *pMap, KeyFrameDatabase* pKFDB, const string &strSettingPath, const int sensor):mState(NO_IMAGES_YET), mSensor(sensor), mbOnlyTracking(false), mbVO(false), mpORBVocabulary(pVoc),mpKeyFrameDB(pKFDB), mpInitializer(static_cast<Initializer*>(NULL)), mpSystem(pSys), mpViewer(NULL),mpFrameDrawer(pFrameDrawer), mpMapDrawer(pMapDrawer), mpMap(pMap), mnLastRelocFrameId(0)
{// Load camera parameters from settings file// 从设置文件中读取相机参数cv::FileStorage fSettings(strSettingPath, cv::FileStorage::READ);float fx = fSettings["Camera.fx"];float fy = fSettings["Camera.fy"];float cx = fSettings["Camera.cx"];float cy = fSettings["Camera.cy"];// 初始化相机内参矩阵 Kcv::Mat K = cv::Mat::eye(3,3,CV_32F); // 三行三列的矩阵 (row行,column列)K.at<float>(0,0) = fx;K.at<float>(1,1) = fy;K.at<float>(0,2) = cx;K.at<float>(1,2) = cy;//K = [ fx  0   cx]//    [ 0   fy  cy]//    [ 0   0   1 ]K.copyTo(mK); //将矩阵K复制到mK中// 初始化畸变系数cv::Mat DistCoef(4,1,CV_32F);DistCoef.at<float>(0) = fSettings["Camera.k1"];DistCoef.at<float>(1) = fSettings["Camera.k2"];DistCoef.at<float>(2) = fSettings["Camera.p1"];DistCoef.at<float>(3) = fSettings["Camera.p2"];const float k3 = fSettings["Camera.k3"];// 有的相机没有参数K3,如果有就重新分配空间,将k3加入DistCoef中if(k3!=0){DistCoef.resize(5);DistCoef.at<float>(4) = k3;}// 将DistCoef中的数据深度拷贝到mDistCoef中DistCoef.copyTo(mDistCoef);// bf是b*f(基线*焦距)mbf = fSettings["Camera.bf"];// 初始化帧率float fps = fSettings["Camera.fps"];if(fps==0)fps=30;// Max/Min Frames to insert keyframes and to check relocalisation// 两个关键帧最大最小帧数限制mMinFrames = 0;mMaxFrames = fps;// 输出相机参数cout << endl << "Camera Parameters: " << endl;cout << "- fx: " << fx << endl;cout << "- fy: " << fy << endl;cout << "- cx: " << cx << endl;cout << "- cy: " << cy << endl;cout << "- k1: " << DistCoef.at<float>(0) << endl;cout << "- k2: " << DistCoef.at<float>(1) << endl;if(DistCoef.rows==5)cout << "- k3: " << DistCoef.at<float>(4) << endl;cout << "- p1: " << DistCoef.at<float>(2) << endl;cout << "- p2: " << DistCoef.at<float>(3) << endl;cout << "- fps: " << fps << endl;// 读取输入图像的颜色通道顺序( 1:RGB 0:BGR )『R:红 G:绿 B:蓝』int nRGB = fSettings["Camera.RGB"];mbRGB = nRGB;// 输出一下使用的颜色通道排序if(mbRGB)cout << "- color order: RGB (ignored if grayscale)" << endl;elsecout << "- color order: BGR (ignored if grayscale)" << endl;// Load ORB parameters// 读取图像信息int nFeatures = fSettings["ORBextractor.nFeatures"];    // 特征点的个数float fScaleFactor = fSettings["ORBextractor.scaleFactor"]; // 金字塔图层之间的比例系数int nLevels = fSettings["ORBextractor.nLevels"];        // 金字塔层数int fIniThFAST = fSettings["ORBextractor.iniThFAST"];   // 角点提取的阈值int fMinThFAST = fSettings["ORBextractor.minThFAST"];   // 降低后的阈值// 创建并初始化(显示初始化)特征提取模块(左眼)mpORBextractorLeft = new ORBextractor(nFeatures,fScaleFactor,nLevels,fIniThFAST,fMinThFAST);if(sensor==System::STEREO)// 如果是双目,还要初始化右眼mpORBextractorRight = new ORBextractor(nFeatures,fScaleFactor,nLevels,fIniThFAST,fMinThFAST);if(sensor==System::MONOCULAR)// 如果是单目,提取双倍提取特征点mpIniORBextractor = new ORBextractor(2*nFeatures,fScaleFactor,nLevels,fIniThFAST,fMinThFAST);// 输出图像信息cout << endl  << "ORB Extractor Parameters: " << endl;cout << "- Number of Features: " << nFeatures << endl;cout << "- Scale Levels: " << nLevels << endl;cout << "- Scale Factor: " << fScaleFactor << endl;cout << "- Initial Fast Threshold: " << fIniThFAST << endl;cout << "- Minimum Fast Threshold: " << fMinThFAST << endl;if(sensor==System::STEREO || sensor==System::RGBD){mThDepth = mbf*(float)fSettings["ThDepth"]/fx;cout << endl << "Depth Threshold (Close/Far Points): " << mThDepth << endl;}if(sensor==System::RGBD){mDepthMapFactor = fSettings["DepthMapFactor"];if(fabs(mDepthMapFactor)<1e-5)mDepthMapFactor=1;elsemDepthMapFactor = 1.0f/mDepthMapFactor;}}

一、GrabImageStereo()

1. 函数讲解

这个函数System.cc中被调用,重要作用有:

  1. 抓取左右目图像
  2. 将抓取的图像转换为灰度图像
  3. 初始化帧,因为这里往往被作为相机的初始帧
  4. 调用Track();跟踪此帧(这个非常非常重要,是这个追踪线程的最主要部分,代码量和难度都很大)
  5. 返回当前帧的世界坐标(当前帧相机的世界坐标)

2. 函数源码

cv::Mat Tracking::GrabImageStereo(const cv::Mat &imRectLeft, const cv::Mat &imRectRight, const double &timestamp)
{// 拷贝左右目图像mImGray = imRectLeft;cv::Mat imGrayRight = imRectRight;// 将RGB或RGBA图像转为灰度图像// 对于这个if,elseif表示不理解,感觉可以不用,或者合并if(mImGray.channels()==3){if(mbRGB){cvtColor(mImGray,mImGray,CV_RGB2GRAY);cvtColor(imGrayRight,imGrayRight,CV_RGB2GRAY);}else{cvtColor(mImGray,mImGray,CV_BGR2GRAY);cvtColor(imGrayRight,imGrayRight,CV_BGR2GRAY);}}else if(mImGray.channels()==4){if(mbRGB){cvtColor(mImGray,mImGray,CV_RGBA2GRAY);cvtColor(imGrayRight,imGrayRight,CV_RGBA2GRAY);}else{cvtColor(mImGray,mImGray,CV_BGRA2GRAY);cvtColor(imGrayRight,imGrayRight,CV_BGRA2GRAY);}}// 显示初始化双目的构造函数mCurrentFrame = Frame(mImGray,imGrayRight,timestamp,mpORBextractorLeft,mpORBextractorRight,mpORBVocabulary,mK,mDistCoef,mbf,mThDepth);// 跟踪(调用Tracking::Track())Track();// 返回当前帧的世界坐标return mCurrentFrame.mTcw.clone();
}

三、 学习方法(路线)

在前面的特征提取ORBextractor.cc和帧Frame.cc的学习中,作者是一次性将整个文件学完,但是在学习MapPoint.cc等文件时,发现他们并不具备完整性,很锁碎,函数之间几乎很少有关联。所以在后续的学习中开始改变学习方法,从三个主要线程入手,碰到一个函数就进入一个函数学习,果然提高了学习效率也不再感到学了又望(因为层次明显,学完会回到上一层)。而且这样做还有一个当时未曾想到的好处,就是学完这个文件(ORB-SLAM2)后翻看所有的.cc文件,看哪些函数没有被标注过(本人看过的代码都会进行标注),就可以查缺补漏。

四、总结

这两个函数在追踪线程中有着极为重要的作用,Tracking::Tracking在初始化追踪线程时用到,GrabImageStereo() 中调用的Track();是追踪线程的主体,后续会详细讲解追踪线程中的其他函数。如果有什么问题或者建议,欢迎大家交流。


http://www.ppmy.cn/embedded/129502.html

相关文章

一起搭WPF架构之livechart的MVVM使用介绍

一起搭WPF架构之livechart使用介绍 前言ModelViewModelView界面设计界面后端 效果总结 前言 简单的架构搭建已经快接近尾声了&#xff0c;考虑设计使用图表的形式将SQLite数据库中的数据展示出来。前期已经介绍了livechart的安装&#xff0c;今天就详细介绍一下livechart的使用…

【Python-AI篇】数据结构和算法

1. 算法概念 1.1 什么是数据结构 存储&#xff0c;组织数据的方式 1.2 什么是算法 实现业务目的的各种方法和思路算法是独立的存在&#xff0c;只是思想&#xff0c;不依附于代码和程序&#xff0c;可以使用不同语言实现&#xff08;java&#xff0c;python&#xff0c;c&a…

人工智能技术的应用前景及其对生活和工作方式的影响

人工智能技术的应用前景及其对生活和工作方式的影响 随着人工智能&#xff08;AI&#xff09;技术的迅猛发展&#xff0c;其在各个领域的应用正日益深入&#xff0c;深刻改变着我们的生活和工作方式。本文将系统地探讨人工智能的历史、现状、未来应用前景&#xff0c;以及其对个…

微信小程序实现canvas电子签名

一、先看效果 小程序canvas电子签名 二、文档 微信小程序canvas 组件文档 微信小程序canvas API文档 H5Canvas文档 三、分析 1、初始话Canvas容器 2、Canvas触摸事件&#xff0c;bindtouchstart&#xff08;手指触摸动作开始&#xff09;、bindtouchmove&#xff08;手指触摸…

【ARM】ARM架构参考手册_Part A CPU(1)

目录​​​​​​​ 1.1 关于ARM架构 1.1.1 ARM寄存器 1.1.2 异常 1.1.3 状态寄存器 1.2 ARM指令集 1.2.1 分支指令 1.2.2 数据处理指令 算术/逻辑指令 比较指令 乘法指令 计算前导零指令 1.2.3 状态寄存器传送指令 1.2.4 加载和存储指令 加载和存储寄存器 加载…

c++就业 创建新的设计模式

virtual自然生成虚函数表&#xff08;一维数组记录了虚函数地址 通过偏移可以调相对应的方法&#xff09; vp 编译的时候地址自然会赋值给相对应的对象 如何体现多态 没有虚函数重写 那么就是早绑定 就比如subject会转换成base类型 p指向base对象 有虚函数就是晚绑定 p指向subj…

LlamaIndex核心概念查询管道(Query Pipelines)简介

LlamaIndex 查询管道简介 概述 LlamaIndex提供了一个声明性查询API&#xff0c;允许您将不同的模块链接在一起&#xff0c;以便在数据上编排从简单到高级的工作流。 这是以QueryPipeline抽象为中心的。装入各种模块&#xff08;从llm到提示符&#xff0c;再到检索器&#xf…

自由学习记录(12)

综合实践 2D的Shape&#xff0c;Tilemap都要导包的&#xff0c;编辑器也要导包&#xff0c;。。和2d沾边的可能3d都要主动导包 应该综合的去运用&#xff0c;不见得Tilemap就很万能&#xff0c;如果要做什么顶方块的有交互反应的物体&#xff0c; 那直接拖Sprite会更方便一些…