ORB-SLAM(六)MapPoint与Map
地图点可以通过关键帧来构造,也可以通过普通帧构造,但是最终,必须是和关键帧对应的,通过普通帧构造的地图点只是临时被Tracking用来追踪用的。
构造函数(地图点3D坐标及其参考帧):
// 参考帧是关键帧,该地图点将于许多帧关键帧对应,建立关键帧之间的共视关系
MapPoint::MapPoint(const cv::Mat &Pos, KeyFrame *pRefKF, Map* pMap)
// 参考帧是普通帧,该地图点只与当前普通帧的特征点对应
MapPoint::MapPoint(const cv::Mat &Pos, Map* pMap, Frame* pFrame, const int &idxF)
地图点和关键帧之间的观测关系是最重要的,参考关键帧是哪一帧,该地图点被哪些关键帧观测到,对应的哪个(idx)特征点?通过两个成员维护:
std::map<KeyFrame*,size_t> mObservations;
// 观测到该地图点的相机数
int nObs;
添加地图点观测:能够观测到同一个地图点的关键帧之间存在共视关系
void MapPoint::AddObservation(KeyFrame* pKF, size_t idx);
删除地图点观测:从当前地图点的mObservation和nObs成员中删掉对应关键帧观测关系,若该关键帧恰好是参考帧,则需要重新指定。当观测相机数小于等于2时,该地图点需要剔除。删掉观测关系,和删掉地图点(以及替换地图点),需要区分开!
void MapPoint::EraseObservation(KeyFrame* pKF);
剔除MapPoint不仅需要删掉地图点中维护的关键帧观测关系,还需要删掉对应关键中对应的地图点,以及Map中该地图点的内存:
void KeyFrame::EraseMapPointMatch(const size_t &idx)
{
unique_lock<mutex> lock(mMutexFeatures);
mvpMapPoints[idx]=static_cast<MapPoint*>(NULL);
} mpMap->EraseMapPoint(this);
下面是一个重要的函数:
void MapPoint::Replace(MapPoint* pMP);
将当前地图点(this),替换成pMp。主要使用在闭环时,调整地图点和关键帧,建立新的关系:
关键帧将联系的this替换成pMap:
pKF->ReplaceMapPointMatch(mit->second, pMP);// KeyFrame中mit->second索引对应的地图点,用pMP替换掉原来的this
pMP->AddObservation(pKF,mit->second);// pMp地图点添加观测关键帧
// 删掉Map中该地图点
mpMap->EraseMapPoint(this);
无论是SetBadFlag()还是Replace(),当前地图点的mbBad标志都被记为true,表明当前地图点是个坏点。
visible和found的区别:该地图点在视野范围内,该地图点有对应特征点的帧数。通常来说,found的地图点一定是visible的,但是visible的地图点很可能not found
float MapPoint::GetFoundRatio()
{
unique_lock<mutex> lock(mMutexFeatures);
return static_cast<float>(mnFound)/mnVisible;
}
GetFoundRatio低表示该地图点在很多关键帧的视野范围内,但是没有匹配上很多特征点。
最后是MapPoint中几个比较重要的函数:
void MapPoint::ComputeDistinctiveDescriptors();
void MapPoint::UpdateNormalAndDepth();
int MapPoint::PredictScale(const float ¤tDist, KeyFrame* pKF);
1. 计算地图点描述子:
从mObservations中获取观察到当前地图点的关键帧及对应描述子,描述子放入vDescriptor描述子向量组成的向量中。在这些描述子中,选择距离(类似hamming距离)其他描述子最近的(中值距离最小,看代码去体会一下是什么意思)作为地图点的描述子mDescriptor。
2. 计算地图点平均观测方向和深度
地图点到所有观测到的关键帧相机中心向量,归一化后相加。
深度范围:地图点到参考帧(只有一帧)相机中心距离,乘上参考帧中描述子获取时金字塔放大尺度,得到最大距离mfMaxDistance;最大距离除以整个金字塔最高层的放大尺度得到最小距离mfMinDistance。通常来说,距离较近的地图点,将在金字塔层数较高的地方提取出,距离较远的地图点,在金字塔层数较低的地方提取出(金字塔层数越低,分辨率越高,才能识别出远点)。因此通过地图点的信息(主要是对应描述子),我们可以获得该地图点对应的金字塔层级:
const int level = pRefKF->mvKeysUn[observations[pRefKF]].octave;
从而预测该地图点在什么距离范围内能够被观测到!
3. int MapPoint::PredictScale(const float ¤tDist, KeyFrame* pKF)
注意金字塔ScaleFactor和距离的关系:当前特征点对应ScaleFactor为1.2的意思是:图片分辨率下降1.2倍后,可以提取出该特征点(分辨率更高时,肯定也可以提取出,这里取金字塔中能够提取出该特征点最高层级作为该特征点的层级)
同时,由当前特征点的距离,可以推测所在层级。
Map则比较简单,主要负责维护其中关键帧和地图点容器,设置参考地图点用于绘图:
std::set<MapPoint*> mspMapPoints;
std::set<KeyFrame*> mspKeyFrames;
ORB-SLAM(六)MapPoint与Map的更多相关文章
- python六剑客:map()、lambda()、filter()、reduce()、推导类表、切片
一:map():映射 map()有两个参数,一个函数,一个序列,序列中每一个元素都会做为参数传给前边的函数,然后生成新的列表, 第二个参数必须用一个序列:元祖,列表,字符串 >>> ...
- MapReduce算法形式六:只有Map独自作战
案例六:Map独自直接输出 之前一直没有用过这个map独自输出的模式,就算是输出一些简单的我也会经过一次reduce输出,但是,发现这个map输出的结果跟我预想的有点不一样,我一直以为shuffle的 ...
- Power BI for Office 365(六)Power Map简介
如果说Power BI中最给力的功能是什么,我觉得是Power Map.Power Map第一次是出现在SQL Server 2014的新特性里被提及,前身就是GeoFlow.在Power Map下可 ...
- 六、es6 map
一.map的特点 JavaScript 的对象(Object),本质上是键值对的集合(Hash 结构),但是传统上只能用字符串当作键.这给它的使用带来了很大的限制. 为了解决这个问题,ES6 提供了 ...
- jQuery 源码解析(六) $.each和$.map的区别
$.each主要是用来遍历数组或对象的,例如: var arr=[11,12,13,14]; $.each(arr,function(element,index){ //遍历arr数组 console ...
- [SLAM] 01. "Simultaneous Localization and Mapping"
本篇带你认识SLAM,形成客观的认识和体系 一.通过行业招聘初步了解SLAM 发信人: leecty (Terry), 信区: ParttimeJobPost标 题: 创业公司招SLAM 算法工程师发 ...
- [SLAM] 01 "Simultaneous Localization and Mapping" basic knowledge
发信人: leecty (Terry), 信区: ParttimeJobPost标 题: 创业公司招SLAM 算法工程师发信站: 水木社区 (Thu Jun 16 19:18:24 2016), 站内 ...
- Map集合、HashMap集合、LinkedHashMap集合、Hashtable集合、Collections工具类和模拟斗地主洗牌和发牌
1.Map集合概述和特点 * A:Map接口概述 * 查看API可以知道: * 将键映射到值的对象 * 一个映射不能包含重复的键 * 每个键最多 ...
- 常用的SLAM解决方案
ORB SLAM 可以去Github上自己搜索现成的SLAM程序包 在此基础上做优化 视觉SLAM的分类方法:按摄像头的多少分为单目和双目,按是否使用概率方法分为概率法和图法 链接 学习SLAM重要的 ...
随机推荐
- 使用Vue-cli脚手架
使用vue-cli脚手架开发vue项目,有以下好处: (1)成熟的Vue项目架构设计. (2)本地测试服务器(热更新). (3)集成打包上线方案. Vue-cli系统要求: Node.js(>= ...
- UVa 10791 - Minimum Sum LCM(唯一分解定理)
链接: https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem& ...
- PHP 生成全局唯一id
直接上代码: function generate_global_uniqid() { $prefix = md5(microtime(true)); // 生成唯一ID发生器 prefix,如果为服务 ...
- SpringMVC(1)
1.简要说明: Spring为展现层提供的基于MVC设计理念的优秀web框架,目前主流的框架 Spring3.0以后全面超越Struts2,成为最优秀的MVC框架 Spring MVC通过一套MVC注 ...
- HTML5——前端预处理技术(Less、Sass、CoffeeScript)
一.Less 1.1.概要 Less是一种动态样式语言,Less 是一门 CSS 预处理语言,它扩展了 CSS 语言,增加了变量.Mixin.函数等特性,使 CSS 更易维护和扩展. Less 将 C ...
- hibernateDAO层基本的增删改查
完整的学习项目放在了我的github上,是一个半成品的在线音乐网站. hibernate版本1.4 下面是userDAO 即对user表进行增删改查 package DAO; import java. ...
- injection for Xcode10使用方法
对于一个使用Xcode的使用者来说,麻烦的地方在于使用代码布置界面时候的调试,5s改一下代码,用10s查看修改效果,如果电脑配置稍低,时间更长,这是病,得治,哈哈.下面就来说一下injection的使 ...
- React通过dva-model-extend实现 dva 动态生成 model
前言 实现通过单个component 单个router通过相应的标识对应产生不同model实现数据包分离,model namespce将会覆盖基础的Model,其中的model[state|subsc ...
- CF1066D Boxes Packing(二分答案)
题意描述: 你有$n$个物品,每个物品大小为$a_i$,$m$个盒子,每个盒子的容积为$k$.$Maksim$先生想把物品装入盒子中.对于每个物品,如果能被放入当前的盒子中,则放入当前盒子,否则换一个 ...
- ztree的用法
哎哟,好久没写什么这个虽然没人看的博客了,其实这段时间情绪非常低谷,就没有写博客了,不过我还是回来了,回到正题,在前端页面编程的时候,我们经常用到树状,用原始的树状呢,功能没有那么强大,所以这个时候 ...