4.1ORB-SLAM3之处理缓存队列中的关键帧

0.简介

该函数主要包括以下几个部分:

  • 计算该关键帧特征点的Bow信息
  • 更新当前关键帧新增地图点的属性
  • 更新共视图中关键帧间的连接关系
  • 将该关键帧插入到地图中

1.计算该关键帧特征点的Bow信息ComputeBoW()

vector<cv::Mat> vCurrentDesc = Converter::toDescriptorVector(mDescriptors);
mpORBvocabulary->transform(vCurrentDesc, mBowVec, mFeatVec, 4);

将当前关键帧的所有描述子vCurrentDesc转换为词袋向量,主要用于加速特征匹配(跟踪参考关键帧)和计算两帧之间的相似性(重定位和回环检测)。前面已经讲过,在ORB特征检测后得到的描述子是一个N行的cv::Mat,N表示特征点的数量。为了方便将描述子进行词袋向量转换会对描述子进行一些转换,即将每个特征点对应的描述子拿出来放到vector容器中,得到一个cv::Mat类型的N维vector,其每个元素都表示一个特征点的描述子。

计算描述子函数的输出有两个:
mBowVec记录了由描述子转换得到的词袋向量信息以及每个单词的权重,这个主要用于计算两帧之间的图像相似性。

mFeatVec记录了每个特征点的索引以及该特征点对应单词在词袋树上的节点id,根据这一信息可以在寻找特征匹配时只对统一节点上的特征点寻找匹配关系,以实现加速匹配。

2.更新当前关键帧新增地图点的属性

参考链接:《ORB-SLAM2代码详解03: 地图点MapPoint》

  1. 为当前地图点添加观测
  2. 更新平均观测方向和观测距离范围
  3. 更新地图点的最佳描述子
if(!pMP->IsInKeyFrame(mpCurrentKeyFrame)){pMP->AddObservation(mpCurrentKeyFrame, i);pMP->UpdateNormalAndDepth();pMP->ComputeDistinctiveDescriptors();
}

2.1为当前地图点添加观测AddObservation

表示该地图点被当前关键帧观测到了,函数AddObservation()EraseObservation()同时维护两个成员变量mObservationsnObs以更新地图点的观测情况。

std::map<KeyFrame*,size_t> mObservations是一个map类型的容器,键KeyFrame*表示观测到该Mappoint的关键帧,值size_t表示该MapPoint在KF中的索引。通过函数GetIndexInKeyFrame()IsInKeyFrame()可以对mObservations进行简单查询。

nObs为int类型变量,记录了当前地图点被多少个关键帧相机观测到了(单目关键帧每次观测算1个相机,双目/RGBD帧每次观测算2个相机).

2.2更新平均观测方向和观测距离范围UpdateNormalAndDepth

函数UpdateNormalAndDepth()更新当前地图点的平均观测方向和距离.

1.观测方向:
其中平均观测方向是根据mObservations中所有观测到本地图点的关键帧取平均得到的,通过地图点与关键帧对应相机光心的连线可以得到该地图点的观测方向mWorldPos - pKF->GetCameraCenter(),然后计算该地图点在所有关键帧中的观测方向,并取平均值。

// UpdateNormalAndDepth()
for(map<KeyFrame*,tuple<int,int>>::iterator mit=observations.begin(), mend=observations.end(); mit!=mend; mit++)
{KeyFrame* pKF = mit->first;tuple<int,int> indexes = mit -> second;int leftIndex = get<0>(indexes), rightIndex = get<1>(indexes);if(leftIndex != -1){Eigen::Vector3f Owi = pKF->GetCameraCenter();// 获得光心相机坐标Eigen::Vector3f normali = Pos - Owi;// 计算到光心的向量也即观测方向normal = normal + normali / normali.norm();// 对每个方向向量进行归一化然后相加,最终得到综合方向向量n++;}if(rightIndex != -1){// 针对双单目组合模式Eigen::Vector3f Owi = pKF->GetRightCameraCenter();Eigen::Vector3f normali = Pos - Owi;normal = normal + normali / normali.norm();n++;}
}

(2)观测距离:
平均观测距离是根据参考关键帧得到的,观测距离指的是该3D点到参考关键帧光心的距离。

Eigen::Vector3f PC = Pos - pRefKF->GetCameraCenter();
const float dist = PC.norm();...{unique_lock<mutex> lock3(mMutexPos);mfMaxDistance = dist*levelScaleFactor;// 计算距离上限mfMinDistance = mfMaxDistance/pRefKF->mvScaleFactors[nLevels-1];// 计算距离下限mNormalVector = normal/n;// 计算平均观测距离
}

除了更新观测距离外还会更新该3D点观测距离的上下限:mfMinDistancemfMaxDistance,用于判断某个特征点在反投影后是否真正在视野范围内,其计算方式金字塔图像的尺度有关。

如下图,mfMaxDistance表示若地图点匹配在某特征提取器图像金字塔第7层上的某特征点,观测距离值;mfMinDistance表示若地图点匹配在某特征提取器图像金字塔第0层上的某特征点,观测距离值;
在这里插入图片描述

反过来,也可以根据平均观测距离和该特征点的观测距离上限推测特征点所在的金字塔图像的level.
在这里插入图片描述

计算公式如下:
在这里插入图片描述

2.3更新地图点的最佳描述子ComputeDistinctiveDescriptors

对于某个3D地图点会在多个时刻下被相机观测到,因此同一3D地图点会被多个关键帧观测到,也即该3D点是多个特征点的反投影点,该3D点的描述子也由与其对应特征点的描述子决定。假设该3D点存在N个对应的特征点,计算方式如下:

  • 统计该3D点所有对应特征点的描述子
  • 计算这些描述子两两之间的距离,则可以得到一个关于描述子距离NxN的矩阵
  • 每个描述子对应N个与其他描述子的距离,对于每个描述子取出其与其他描述子距离的中位数
  • 对N个中位数进行排序,选择中位数最小时对应的描述子作为3D点的描述子

3.3 更新共视图中关键帧间的连接关系

void KeyFrame::UpdateConnections(bool upParent)

在没有执行这个函数前,关键帧只和MapPoints之间有连接关系(将观测信息进行关联),这个函数可以更新关键帧之间的连接关系。

  1. 首先获得该关键帧的所有MapPoint点,统计有多少关键帧与当前关键帧存在共视关系(是否观测到了同一个3D点),统计结果放在KFcounter(可以通过地图点的observations属性获得)。
  2. 只要共视点数量大于阈值th=15,就为关键帧与当前帧互相添加连接关系,边的权重为共视点的数量。
  3. 如果遍历完所有的共视关键帧,没有连接到关键帧(权重超过阈值),则对权重最大的关键帧建立连接关系

前面三步都是为了寻找满足要求的关键帧,找到有资格和当前KF建立连接关系的共视关键帧,添加关键帧的核心函数如下:

void KeyFrame::AddConnection(KeyFrame *pKF, const int &weight)
{{unique_lock<mutex> lock(mMutexConnections);if(!mConnectedKeyFrameWeights.count(pKF))// 如果没建立共视关系则直接建立连接关系,本质上是一个map类型的变量mConnectedKeyFrameWeights[pKF]=weight;else if(mConnectedKeyFrameWeights[pKF]!=weight)// 如果已经建立共视关系了更新权重(共视点的数量)mConnectedKeyFrameWeights[pKF]=weight;elsereturn;}// 按照权重对当前关键帧的共视关键帧进行排序UpdateBestCovisibles();
}
  1. 更新生成树的连接,初始化该关键帧的父关键帧为共视程度最高的那个关键帧,将当前关键帧作为其子关键帧

4.将该关键帧插入到地图中

本质上就是将该关键帧KF插入到当前活跃子地图对应成员变量的容器中

void Map::AddKeyFrame(KeyFrame *pKF){...mspKeyFrames.insert(pKF);...
}

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

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

相关文章

【MySQL数据库】MMM高可用架构

目录 一 、MMM简介1.1MMM&#xff08;Master-Master replication manager for MvSQL&#xff0c;MySQL主主复制管理器&#xff09;1.2关于 MMM 高可用架构的说明如下 二、搭建mysql MMM架构2.1实验环境2.2搭建多主多从2.3安装配置 MySQL-MMM 一 、MMM简介 1.1MMM&#xff08;M…

四、Docker镜像详情

学习参考&#xff1a;尚硅谷Docker实战教程、Docker官网、其他优秀博客(参考过的在文章最后列出) 目录 前言一、Docker镜像1.1 概念1.2 UnionFS&#xff08;联合文件系统&#xff09;1.3 Docker镜像加载原理1.4 重点理解 二、docker commit 命令2.1 是什么&#xff1f;2.2 命令…

pytorch快速入门中文——01

PyTorch 深度学习&#xff1a;60分钟快速入门 原文&#xff1a;https://pytorch.org/tutorials/beginner/deep_learning_60min_blitz.html 作者&#xff1a; Soumith Chintala https://www.youtube.com/embed/u7x8RXwLKcA 什么是 PyTorch&#xff1f; PyTorch 是基于以下两个…

无限极 × 盖雅工场|劳动力管理系统项目正式启动,为多工厂管理保驾护航

6月12日&#xff0c;无限极盖雅工场劳动力管理系统启动大会在广东江门举行。无限极IT供应链系统负责人毛松和、智能制造总监胡波、新会生产中心负责人胡流云、营口生产中心负责人源博恩和人才资源共享服务负责人林岳&#xff0c;以及盖雅工场华南总经理潘磊等出席了启动大会。 …

uniapp打包白屏问题

【bug】&#xff1a;浏览器运行正常&#xff0c;模拟器、真机运行只有tab栏显示&#xff0c;或者完全白屏。打包也是白屏。 【控制台报错信息】&#xff1a; 注意&#xff1a;app不支持dom操作 【解决办法】&#xff1a;在main.js里修改 render函数是vue通过js渲染dom结构的…

html5学习精选5篇案例

html5学习心得1 一&#xff1a;了解HTML5前端开发技术 HTML 指的是超文本标记语言 (Hyper Text Markup Language)&#xff0c;标记语言是一套标记标签 (markup tag)&#xff0c;HTML 使用标记标签来描述网页。HTML5区别于HTML的标准&#xff0c;基于全新的规则手册&#xff0…

【云原生】二进制k8s集群(下)部署高可用master节点

本次部署说明 在上一篇文章中&#xff0c;就已经完成了二进制k8s集群部署的搭建&#xff0c;但是单机master并不适用于企业的实际运用&#xff08;因为单机master中&#xff0c;仅仅只有一台master作为节点服务器的调度指挥&#xff0c;一旦宕机。就意味着整个集群的瘫痪&#…

shell脚本ssh远程执行命令给变量赋值的问题

需求及目标 从A机器通过SSH方式到B机器&#xff0c;并执行相关的命令。命令中包含变量及变量的赋值。 代码如下&#xff0c;意思是&#xff0c;ssh到192.111.111.27这台机器&#xff0c;cd到 / 根目录下&#xff0c;并执行ls命令&#xff0c;如果ls出来的结果不为空&#xff…

Excel 2019访问SQL Server数据库的实现过程

源之&#xff1a;https://vip.kingdee.com/article/288066926977041920?productLineId11 在日常ERP系统实施过程中&#xff0c;往往会遇到客户的一些个性化需求&#xff0c;比如有些客户习惯用Excel电子表格来查看ERP系统中的数据&#xff0c;业余拓展学习了一下&#xff0c;借…

浅析EasyCVR视频技术与AR实景智能管理平台在智慧厂区中的应用

一、背景分析 新型智慧厂区是运用人工智能、大数据、物联网和设备监控技术加强厂区安保和信息管理。通过先进技术&#xff0c;保障厂区生产运营安全&#xff0c;同时减少生产线上的人工干预、及时正确地采集各类生产数据&#xff0c;以及合理的生产计划编排与生产进度&#xff…

matlab将数据写入到excel中

第一种&#xff1a; 将数据转化为cell块&#xff0c;从A1单元格写起 % xlswrite(info_10*2.xls ,sheet1,B2:B4) clear; clc; a[1 2 3 4 5 6 ];%三组数据 b[11 22 33 44 55 66]; c[12 23 34 45 56 61]; data [a b c];%把数据保存到data中&#xff0c;其中a的表示转置 [m p]si…

Segment-Anything的一些相关论文总结

1、 Segment Anything Model (SAM) Enhanced Pseudo Labels for Weakly Supervised Semantic Segmentation Tianle Chen, Zheda Mai, Ruiwen Li, Wei-lun Chao https://arxiv.org/abs/2305.05803 图像级监督的弱监督语义分割(WSSS)由于其标注成本较像素级标注低而受到越来越…