ORB-SLAM2学习笔记9之图像帧Frame
先占坑,明天再完善…
文章目录
- 0 引言
- 1 Frame类
- 1.1 成员函数
- 1.2 成员变量
- 2 Frame类的用途
0 引言
ORB-SLAM2学习笔记8详细了解了图像特征点提取和描述子的生成,本文在此基础上,继续学习ORB-SLAM2中的图像帧,也就是Frame类,该类中主要包含设置相机参数、利用双目计算深度及特征点反投影到3D地图点等函数。

1 Frame类
构造函数Frame类主要的代码如下:
双目相机Frame:
// 双目相机Frame构造函数
Frame::Frame(const cv::Mat &imLeft, const cv::Mat &imRight, const double &timeStamp, ORBextractor *extractorLeft, ORBextractor *extractorRight, ORBVocabulary *voc, cv::Mat &K, cv::Mat &distCoef, const float &bf, const float &thDepth): mpORBvocabulary(voc), mpORBextractorLeft(extractorLeft), mpORBextractorRight(extractorRight), mTimeStamp(timeStamp), mK(K.clone()), mDistCoef(distCoef.clone()), mbf(bf), mThDepth(thDepth), mpReferenceKF(static_cast<KeyFrame *>(NULL)) {// step0. 帧ID自增mnId = nNextId++;// step1. 计算金字塔参数mnScaleLevels = mpORBextractorLeft->GetLevels();mfScaleFactor = mpORBextractorLeft->GetScaleFactor();mfLogScaleFactor = log(mfScaleFactor);mvScaleFactors = mpORBextractorLeft->GetScaleFactors();mvInvScaleFactors = mpORBextractorLeft->GetInverseScaleFactors();mvLevelSigma2 = mpORBextractorLeft->GetScaleSigmaSquares();mvInvLevelSigma2 = mpORBextractorLeft->GetInverseScaleSigmaSquares();// step2. 提取双目图像特征点thread threadLeft(&Frame::ExtractORB, this, 0, imLeft);thread threadRight(&Frame::ExtractORB, this, 1, imRight);threadLeft.join();threadRight.join();N = mvKeys.size();if (mvKeys.empty())return;// step3. 畸变矫正,实际上UndistortKeyPoints()不对双目图像进行矫正UndistortKeyPoints();// step4. 双目图像特征点匹配ComputeStereoMatches();// step5. 第一次调用构造函数时计算static变量if (mbInitialComputations) {ComputeImageBounds(imLeft);mfGridElementWidthInv = static_cast<float>(FRAME_GRID_COLS) / static_cast<float>(mnMaxX - mnMinX);mfGridElementHeightInv = static_cast<float>(FRAME_GRID_ROWS) / static_cast<float>(mnMaxY - mnMinY);fx = K.at<float>(0, 0);fy = K.at<float>(1, 1);cx = K.at<float>(0, 2);cy = K.at<float>(1, 2);invfx = 1.0f / fx;invfy = 1.0f / fy;// 计算完成,标志复位mbInitialComputations = false;}mvpMapPoints = vector<MapPoint *>(N, static_cast<MapPoint *>(NULL)); // 初始化本帧的地图点mvbOutlier = vector<bool>(N, false); // 标记当前帧的地图点不是外点mb = mbf / fx; // 计算双目基线长度// step6. 将特征点分配到网格中AssignFeaturesToGrid();
}
RGBD相机Frame:
// RGBD相机Frame构造函数
Frame::Frame(const cv::Mat &imGray, const cv::Mat &imDepth, const double &timeStamp, ORBextractor *extractor, ORBVocabulary *voc, cv::Mat &K, cv::Mat &distCoef, const float &bf, const float &thDepth): mpORBvocabulary(voc), mpORBextractorLeft(extractor), mpORBextractorRight(static_cast<ORBextractor *>(NULL)), mTimeStamp(timeStamp), mK(K.clone()), mDistCoef(distCoef.clone()), mbf(bf), mThDepth(thDepth) {// step0. 帧ID自增mnId = nNextId++;// step1. 计算金字塔参数mnScaleLevels = mpORBextractorLeft->GetLevels();mfScaleFactor = mpORBextractorLeft->GetScaleFactor();mfLogScaleFactor = log(mfScaleFactor);mvScaleFactors = mpORBextractorLeft->GetScaleFactors();mvInvScaleFactors = mpORBextractorLeft->GetInverseScaleFactors();mvLevelSigma2 = mpORBextractorLeft->GetScaleSigmaSquares();mvInvLevelSigma2 = mpORBextractorLeft->GetInverseScaleSigmaSquares();// step2. 提取左目图像特征点ExtractORB(0, imGray);N = mvKeys.size();if (mvKeys.empty())return;// step3. 畸变矫正UndistortKeyPoints();// step4. 根据深度信息构造虚拟右目图像ComputeStereoFromRGBD(imDepth);mvpMapPoints = vector<MapPoint *>(N, static_cast<MapPoint *>(NULL));mvbOutlier = vector<bool>(N, false);// step5. 第一次调用构造函数时计算static变量if (mbInitialComputations) {ComputeImageBounds(imLeft);mfGridElementWidthInv = static_cast<float>(FRAME_GRID_COLS) / static_cast<float>(mnMaxX - mnMinX);mfGridElementHeightInv = static_cast<float>(FRAME_GRID_ROWS) / static_cast<float>(mnMaxY - mnMinY);fx = K.at<float>(0, 0);fy = K.at<float>(1, 1);cx = K.at<float>(0, 2);cy = K.at<float>(1, 2);invfx = 1.0f / fx;invfy = 1.0f / fy;// 计算完成,标志复位mbInitialComputations = false;}mvpMapPoints = vector<MapPoint *>(N, static_cast<MapPoint *>(NULL)); // 初始化本帧的地图点mvbOutlier = vector<bool>(N, false); // 标记当前帧的地图点不是外点mb = mbf / fx; // 计算双目基线长度// step6. 将特征点分配到网格中AssignFeaturesToGrid();
}
1.1 成员函数
| 成员函数 | 类型 | 定义 |
|---|---|---|
ORBextractor* mpORBextractorLeft,ORBextractor* mpORBextractorRight | public | 左右目图像的特征点提取器 |
void ExtractORB(int flag, const cv::Mat &im) | public | 进行ORB特征提取 |
cv::Mat mDescriptors,cv::Mat mDescriptorsRight | public | 左右目图像特征点描述子 |
std::vector<cv::KeyPoint> mvKeys,std::vector<cv::KeyPoint> mvKeysRight | public | 畸变矫正前的左/右目特征点 |
std::vector<cv::KeyPoint> mvKeysUn | public | 畸变矫正后的左目特征点 |
std::vector<float> mvuRight | public | 左目特征点在右目中匹配特征点的横坐标 |
| (左右目匹配特征点的纵坐标相同) | ||
std::vector<float> mvDepth | public | 特征点深度 |
float mThDepth | public | 判断单目特征点和双目特征点的阈值;深度低于该值得特征点被认为是双目特征点;深度低于该值得特征点被认为是单目特征点 |
1.2 成员变量
| 成员变量 | 类型 | 定义 |
|---|---|---|
mbInitialComputations | public | static变量,是否需要为Frame类的相机参数赋值,初始化为false,第一次为相机参数赋值后变为false |
float fx, float fy, float cx, float cy, float invfx, float invfy | public | static变量,相机内参 |
cv::Mat mK | public | 相机内参矩阵 |
float mb | public | 相机基线baseline,相机双目间的距离 |
float mbf | public | 相机基线baseline与焦距的乘积 |
Frame类大多与相机相关的参数,而且整个系统内的所有Frame对象共享同一份相机参数;
2 Frame类的用途
除了少数被选为KeyFrame的帧以外,大部分Frame对象的作用仅在于Tracking线程内追踪当前帧位姿,不会对LocalMapping线程和LoopClosing线程产生任何影响,在mLastFrame和mCurrentFrame更新之后就被系统销毁了。
Reference:
- https://github.com/raulmur/ORB_SLAM2
- https://github.com/electech6/ORB_SLAM2_detailed_comments/tree/master
⭐️👍👍👍👍👍👍👍👍👍👍👍👍👍👍👍👍👍👍👍👍👍👍👍👍👍👍👍👍👍👍👍👍👍👍👍👍👍👍👍👍👍👍👍👍👍👍🌔
相关文章:
ORB-SLAM2学习笔记9之图像帧Frame
先占坑,明天再完善… 文章目录 0 引言1 Frame类1.1 成员函数1.2 成员变量 2 Frame类的用途 0 引言 ORB-SLAM2学习笔记8详细了解了图像特征点提取和描述子的生成,本文在此基础上,继续学习ORB-SLAM2中的图像帧,也就是Frame类&#…...
面试热题(不同的二分搜索树)
给你一个整数 n ,求恰由 n 个节点组成且节点值从 1 到 n 互不相同的 二叉搜索树 有多少种?返回满足题意的二叉搜索树的种数。 经典的面试题,这部分涉及了组合数学中的卡特兰数,如果对其不清楚的同学可以去看我以前的博客卡特兰数 …...
MybatisPlus整合p6spy组件SQL分析
目录 p6spy java为什么需要 如何使用 其他配置 p6spy p6spy是一个开源项目,通常使用它来跟踪数据库操作,查看程序运行过程中执行的sql语句。 p6spy将应用的数据源给劫持了,应用操作数据库其实在调用p6spy的数据源,p6spy劫持到…...
项目实战 — 博客系统③ {功能实现}
目录 一、编写注册功能 🍅 1、使用ajax构造请求(前端) 🍅 2、统一处理 🎄 统一对象处理 🎄 保底统一返回处理 🎄 统一异常处理 🍅 3、处理请求 二、编写登录功能 🍅 …...
卷积神经网络全解:(AlexNet/VGG/ GoogLeNet/LeNet/ResNet/卷积/激活/池化/全连接)、现代卷积神经网络、经典卷积神经网络
CNN,卷积神经网络,Convolution Neural Network 卷积计算公式:N (W-F2p)/s1 这个公式每次都得看看,不能忘 1 经典网络 按照时间顺序 1.1 LeNet LeNet是 Yann LeCun在1998年提出,用于解决手…...
WDM 模型(Windows Driver Model)简述
WDM 模型(Windows Driver Model) 是微软公司为 Windows98 和 Windows2000 的驱动程序设计的一种架构,在 WDM 驱动程序模型中,每个硬件设备 至少有两个驱动程序。其中一个为功能驱动程序,它了解硬件工作的所有细节,负 责初始化 …...
【算法刷题之数组篇(1)】
目录 1.leetcode-59. 螺旋矩阵 II(题2.题3相当于二分变形)2.leetcode-33. 搜索旋转排序数组3.leetcode-81. 搜索旋转排序数组 II(与题目2对比理解)(题4和题5都是排序双指针)4.leetcode-15. 三数之和5.leetcode-18. 四数之和6.leet…...
【数据挖掘】使用 Python 分析公共数据【01/10】
一、说明 本文讨论了如何使用 Python 使用 Pandas 库分析官方 COVID-19 病例数据。您将看到如何从实际数据集中收集见解,发现乍一看可能不那么明显的信息。特别是,本文中提供的示例说明了如何获取有关疾病在不同国家/地区传播速度的信息。 二、准备您的…...
html怎么插入视频?视频如何插入页面
html怎么插入视频?视频如何插入页面 HTML 的功能强大,基本所有的静态效果都可以在此轻松呈现,各种视频网站内有大量的视频内容,本篇文章教你如何在 html 中插入视频 代码如下: <!DOCTYPE html> <html> …...
游戏服务端性能测试
导语:近期经历了一系列的性能测试,涵盖了Web服务器和游戏服务器的领域。在这篇文章中,我将会对游戏服务端所做的测试进行详细整理和记录。需要注意的是,本文着重于记录,而并非深入的编程讨论。在这里,我将与…...
【使用Zookeeper当作注册中心】自己定制负载均衡常见策略
自己定制负载均衡常见策略 一、前言随机(Random)策略的实现轮询(Round Robin)策略的实现哈希(Hash)策略 一、前言 大伙肯定知道,在分布式开发中,目前使用较多的注册中心有以下几个&…...
设计模式十七:迭代器模式(Iterator Pattern)
迭代器模式(Iterator Pattern)是一种行为型设计模式,它提供了一种访问聚合对象(例如列表、集合、数组等)中各个元素的方法,而无需暴露其内部表示。迭代器模式将遍历元素和访问元素的责任分离开来࿰…...
Python制作爱心并打包成手机端可执行文件
前言 本文是想要将python代码打包成在手机上能执行的文件 尝试了几个库, 有这也那样的限制,最终还是选了BeeWare 环境:python3.7.x 开始 找到打包有相关工具os-android-apk-builder,buildozer,cx_Freezeÿ…...
使用docker-compose.yml快速搭建开发、部署环境(nginx、tomcat、mysql、jar包、各种程序)以及多容器通信和统一配置
目录 docker-compose语法(更多说明可查看下面代码)imagehostnamecontainer_namevolumesnetworks yml文件的使用启动停止 开发环境(这里以python为例)部署环境nginxmysqltomcatjar包打包后的可执行程序 常见问题与解决方案多个容器…...
管理类联考——逻辑——真题篇——按知识分类——汇总篇——二、论证逻辑——支持加强——第三节——分类3——类比题干支持
文章目录 第三节 支持加强-分类3-类比题干支持真题(2017-28)-支持加强-正面支持-表达“确实如此”真题(2017-36)-支持加强-正面支持-表达“确实如此”真题(2017-39)-支持加强-正面支持-方法有效或方法可行,但多半不选择方法无恶果真题(2017-50)-支持加强真题(2018-2…...
搜索旋转排序数组
整数数组 nums 按升序排列,数组中的值 互不相同 。 在传递给函数之前,nums 在预先未知的某个下标 k(0 < k < nums.length)上进行了 旋转,使数组变为 [nums[k], nums[k1], …, nums[n-1], nums[0], nums[1], …, …...
Steam搬砖项目:最长久稳定的副业!
项目应该大家都有听说话,但是细节问题,如何操作可能有些不是很清楚,今天在这里简单分享一下。 这个Steam搬砖项目主要赚钱汇率差和价值差,是一个细分领取的小项目。 不用引流,时间也是比较自由的,你可以兼…...
最小化安装移动云大云操作系统--BCLinux-R8-U8-Server-x86_64-230802版
CentOS 结束技术支持,转为RHEL的前置stream版本后,国内开源Linux服务器OS生态转向了开源龙蜥和开源欧拉两大开源社区,对应衍生出了一系列商用Linux服务器系统。BC-Linux V8.8是中国移动基于龙蜥社区Anolis OS 8.8版本深度定制的企业级X86服务…...
神经网络基础-神经网络补充概念-05-导数
概念 导数是微积分中的一个概念,用于描述函数在某一点的变化率。在数学中,函数的导数表示函数值随着自变量的微小变化而产生的变化量,即斜率或变化率。 假设有一个函数 f(x),其中 x 是自变量,y f(x) 是因变量。函数…...
kubernetes — 安装Ingress
1、 Ingress 1、安装-Nginx-Ingress kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.8.1/deploy/static/provider/cloud/deploy.yaml 2、设为默认的Ingress [rootk8s01 ~]# vim default_ingress.yaml apiVersion: networking.…...
51c自动驾驶~合集58
我自己的原文哦~ https://blog.51cto.com/whaosoft/13967107 #CCA-Attention 全局池化局部保留,CCA-Attention为LLM长文本建模带来突破性进展 琶洲实验室、华南理工大学联合推出关键上下文感知注意力机制(CCA-Attention),…...
Golang 面试经典题:map 的 key 可以是什么类型?哪些不可以?
Golang 面试经典题:map 的 key 可以是什么类型?哪些不可以? 在 Golang 的面试中,map 类型的使用是一个常见的考点,其中对 key 类型的合法性 是一道常被提及的基础却很容易被忽视的问题。本文将带你深入理解 Golang 中…...
Redis相关知识总结(缓存雪崩,缓存穿透,缓存击穿,Redis实现分布式锁,如何保持数据库和缓存一致)
文章目录 1.什么是Redis?2.为什么要使用redis作为mysql的缓存?3.什么是缓存雪崩、缓存穿透、缓存击穿?3.1缓存雪崩3.1.1 大量缓存同时过期3.1.2 Redis宕机 3.2 缓存击穿3.3 缓存穿透3.4 总结 4. 数据库和缓存如何保持一致性5. Redis实现分布式…...
dedecms 织梦自定义表单留言增加ajax验证码功能
增加ajax功能模块,用户不点击提交按钮,只要输入框失去焦点,就会提前提示验证码是否正确。 一,模板上增加验证码 <input name"vdcode"id"vdcode" placeholder"请输入验证码" type"text&quo…...
第25节 Node.js 断言测试
Node.js的assert模块主要用于编写程序的单元测试时使用,通过断言可以提早发现和排查出错误。 稳定性: 5 - 锁定 这个模块可用于应用的单元测试,通过 require(assert) 可以使用这个模块。 assert.fail(actual, expected, message, operator) 使用参数…...
C# 类和继承(抽象类)
抽象类 抽象类是指设计为被继承的类。抽象类只能被用作其他类的基类。 不能创建抽象类的实例。抽象类使用abstract修饰符声明。 抽象类可以包含抽象成员或普通的非抽象成员。抽象类的成员可以是抽象成员和普通带 实现的成员的任意组合。抽象类自己可以派生自另一个抽象类。例…...
自然语言处理——Transformer
自然语言处理——Transformer 自注意力机制多头注意力机制Transformer 虽然循环神经网络可以对具有序列特性的数据非常有效,它能挖掘数据中的时序信息以及语义信息,但是它有一个很大的缺陷——很难并行化。 我们可以考虑用CNN来替代RNN,但是…...
零基础在实践中学习网络安全-皮卡丘靶场(第九期-Unsafe Fileupload模块)(yakit方式)
本期内容并不是很难,相信大家会学的很愉快,当然对于有后端基础的朋友来说,本期内容更加容易了解,当然没有基础的也别担心,本期内容会详细解释有关内容 本期用到的软件:yakit(因为经过之前好多期…...
ip子接口配置及删除
配置永久生效的子接口,2个IP 都可以登录你这一台服务器。重启不失效。 永久的 [应用] vi /etc/sysconfig/network-scripts/ifcfg-eth0修改文件内内容 TYPE"Ethernet" BOOTPROTO"none" NAME"eth0" DEVICE"eth0" ONBOOT&q…...
GitFlow 工作模式(详解)
今天再学项目的过程中遇到使用gitflow模式管理代码,因此进行学习并且发布关于gitflow的一些思考 Git与GitFlow模式 我们在写代码的时候通常会进行网上保存,无论是github还是gittee,都是一种基于git去保存代码的形式,这样保存代码…...
