ORB-SLAM2 --- MapPoint::Replace函数

news2024/9/22 6:23:59

目录

1.函数作用

2.code 

3.函数解析 


1.函数作用

        替换地图点,更新观测关系。

2.code 

void MapPoint::Replace(MapPoint* pMP)
{
    // 同一个地图点则跳过
    if(pMP->mnId==this->mnId)
        return;

    //要替换当前地图点,有两个工作:
    // 1. 将当前地图点的观测数据等其他数据都"叠加"到新的地图点上
    // 2. 将观测到当前地图点的关键帧的信息进行更新


    // 清除当前地图点的信息,这一段和SetBadFlag函数相同
    int nvisible, nfound;
    map<KeyFrame*,size_t> obs;
    {
        unique_lock<mutex> lock1(mMutexFeatures);
        unique_lock<mutex> lock2(mMutexPos);
        obs=mObservations;
        //清除当前地图点的原有观测
        mObservations.clear();
        //当前的地图点被删除了
        mbBad=true;
        //暂存当前地图点的可视次数和被找到的次数
        nvisible = mnVisible;
        nfound = mnFound;
        //指明当前地图点已经被指定的地图点替换了
        mpReplaced = pMP;
    }

    // 所有能观测到原地图点的关键帧都要复制到替换的地图点上
    //- 将观测到当前地图的的关键帧的信息进行更新
    for(map<KeyFrame*,size_t>::iterator mit=obs.begin(), mend=obs.end(); mit!=mend; mit++)
    {
        // Replace measurement in keyframe
        KeyFrame* pKF = mit->first;

        if(!pMP->IsInKeyFrame(pKF))
        {   
            // 该关键帧中没有对"要替换本地图点的地图点"的观测
            pKF->ReplaceMapPointMatch(mit->second, pMP);// 让KeyFrame用pMP替换掉原来的MapPoint
            pMP->AddObservation(pKF,mit->second);// 让MapPoint替换掉对应的KeyFrame
        }
        else
        {
            // 这个关键帧对当前的地图点和"要替换本地图点的地图点"都具有观测
            // 产生冲突,即pKF中有两个特征点a,b(这两个特征点的描述子是近似相同的),这两个特征点对应两个 MapPoint 为this,pMP
            // 然而在fuse的过程中pMP的观测更多,需要替换this,因此保留b与pMP的联系,去掉a与this的联系
            //说白了,既然是让对方的那个地图点来代替当前的地图点,就是说明对方更好,所以删除这个关键帧对当前帧的观测
            pKF->EraseMapPointMatch(mit->second);
        }
    }

    //- 将当前地图点的观测数据等其他数据都"叠加"到新的地图点上
    pMP->IncreaseFound(nfound);
    pMP->IncreaseVisible(nvisible);
    //描述子更新
    pMP->ComputeDistinctiveDescriptors();

    //告知地图,删掉我
    mpMap->EraseMapPoint(this);
}

3.函数解析 

        函数的调用形式为pMPinKF->Replace(pMP)。将pMPinKF地图点替换成pMP。

        这里this变量代表着pMPinKF,是调用这个函数的地图点。若两个地图点的ID一样,则表示调用出错误了,我们退出函数。

        mObservations变量是map<KeyFrame*,size_t>型变量,存储着pMPinKF地图点被哪些关键帧观测到,该地图点/特征点在该关键帧的索引信息。

        由于我们要将pMPinKF地图点替换成pMP,因此我们要把地图点pMPinKF的信息清空并将地图点的信息赋值给地图点pMP

        因此我们要清空pMPinKF地图点的mObservations变量,并用obs变量存储原有的信息方便复制到pMP地图点。将地图点pMPinKFmbBad标记为true表示是一个坏地图点。用nvisible、nfound 暂存当前地图点的可视次数和被找到的次数并用变量mpReplaced指明是由pMP地图点替换掉的。

        遍历能观测到原地图点的pMPinKF所有关键帧:

        如果地图点pMP不在该帧观测中:添加观测

            // 该关键帧中没有对"要替换本地图点的地图点"的观测
            pKF->ReplaceMapPointMatch(mit->second, pMP);// 让KeyFrame用pMP替换掉原来的MapPoint
            pMP->AddObservation(pKF,mit->second);// 让MapPoint替换掉对应的KeyFrame
// 地图点的替换
void KeyFrame::ReplaceMapPointMatch(const size_t &idx, MapPoint* pMP)
{
    mvpMapPoints[idx]=pMP;
}
/**
 * @brief 给地图点添加观测
 *
 * 记录哪些 KeyFrame 的那个特征点能观测到该 地图点
 * 并增加观测的相机数目nObs,单目+1,双目或者rgbd+2
 * 这个函数是建立关键帧共视关系的核心函数,能共同观测到某些地图点的关键帧是共视关键帧
 * @param pKF KeyFrame
 * @param idx MapPoint在KeyFrame中的索引
 */
void MapPoint::AddObservation(KeyFrame* pKF, size_t idx)
{
    unique_lock<mutex> lock(mMutexFeatures);
    // mObservations:观测到该MapPoint的关键帧KF和该MapPoint在KF中的索引
    // 如果已经添加过观测,返回
    if(mObservations.count(pKF)) 
        return;
    // 如果没有添加过观测,记录下能观测到该MapPoint的KF和该MapPoint在KF中的索引
    mObservations[pKF]=idx;

    if(pKF->mvuRight[idx]>=0)
        nObs+=2; // 双目或者rgbd
    else
        nObs++; // 单目
}

        如果地图点pMP在该帧观测中:删除原地图点对观测

/**
 * @brief 由于其他的原因,导致当前关键帧观测到的某个地图点被删除(bad==true)了,将该地图点置为NULL
 * 
 * @param[in] idx   地图点在该关键帧中的id
 */
void KeyFrame::EraseMapPointMatch(const size_t &idx)
{
    unique_lock<mutex> lock(mMutexFeatures);
    // NOTE 使用这种方式表示其中的某个地图点被删除
    mvpMapPoints[idx]=static_cast<MapPoint*>(NULL);
}

        将原地图点的信息添加到新地图点上并更新最佳描述子

ORB-SLAM2 --- MapPoint::ComputeDistinctiveDescriptors 函数解析icon-default.png?t=MBR7https://blog.csdn.net/qq_41694024/article/details/128515977

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

数据报告:[数字健康]如何引发美国医疗深度变革

本文由前嗅数据研究院出品 在美国&#xff0c;全球疫情的不断发展扩大&#xff0c;促进了其医疗行业的变革与创新&#xff0c;以“Digital Health”&#xff08;数字健康&#xff09;为关键词的医疗领域正在发⽣⾰命性的变化。本文着重介绍“Digital Health”的特点及其在各领域…

【博学谷学习记录】超强总结,用心分享|kafka如何保证数据不丢失

文章目录数据在Kafka中的流转阶段一:生产者如何保证数据不丢失ACK机制阶段二:Broker端如何保证数据不丢失磁盘副本阶段三:消费者如何保证数据不丢失消费者提交偏移量数据在Kafka中的流转 阶段一:生产者如何保证数据不丢失 ACK机制 生产者将数据生产到Broker后,Broker需要给一个…

学习python之——python入门

欢迎来到 Python 入门的学习之旅&#xff01; Python 是一种高级编程语言&#xff0c;它是一种解释型语言&#xff0c;有着丰富的库和大量的第三方模块&#xff0c;能够用于许多不同的编程任务。无论你是想要学习 Python 进行 Web 开发&#xff0c;还是想用它来进行数据分析和…

Windows 远程桌面 Ubuntu

参考 Windows远程桌面工具连接Ubuntu系统使用总结_CHH3213的博客-CSDN博客_远程连接ubuntu 开启ssh服务&#xff08;非必须 查看ssh是否已经开启 sudo ps -e | grep ssh 如果最后返回是sshd&#xff0c;证明ssh已经开启&#xff0c;跳到第四步 第二步&#xff0c;如果没有…

excel处理时间数据

目录excel中的日期中同时提取年月&#xff0c;可使用YEAR函数提取年份&#xff0c;MONTH函数提取月份&#xff0c;然后使用合并函数“&”将年月合并即可。方法步骤如下&#xff1a; 1、打开需要操作的EXCEL表格&#xff0c;在任意空白单元格上面的函数编辑框中输入“YEAR&…

自动化 HR 流程,实现人力资源部门无纸化

自动化 HR 流程&#xff0c;实现人力资源部门无纸化 如果公司使用手动流程&#xff0c;人力资源部门则可能是纸张最密集的部门之一。使用像Google Docs或Dropbox这样的免费文件共享应用程序可能会感觉比使用纸张更上一层楼。但是&#xff0c;这些应用程序旨在在某个时间点启用…

python居然还能画出这么精美的魔法少女,惊我一整年

前言 大家早好、午好、晚好吖 ❤ ~ 对于上面漫小姐姐图&#xff0c;大家觉得好不好看呢 这种极简的线条画出超具魅力的小姐姐图 简直不要太击中小心脏 接下来&#xff0c;我们就用python来实现一下&#xff0c;画出一个好看的少女~ 代码展示 导入模块 import turtle as te…

VIVADO异步时钟域约束(groups)

异步时钟域约束 VIVADO异步时钟约束之实例演示 操作方法&#xff1a; 1、先在synthesis 中打开 report clock interaction &#xff0c;可以看到没有约束的异步时钟之间用红色标记&#xff1b; 2、在synthesis中打开edit timing constraints 设置异步时钟&#xff1b; 3、异…

QGroundControl 添加自定义FactGroup

基于QGC4.1.2版本进行添加&#xff0c;首先由于QGC的原来对FactGroup定义均写在Vehicle.h和Vehicle.cc两个文件中&#xff0c;个人感觉都写在Vehicle文件下回导致文件过大&#xff0c;所以将FactGroup定义进行分离&#xff0c;写在各自的.h和.cc文件下&#xff0c;然后在Vehicl…

运动无线耳机哪个品牌比较好、运动效果最好的运动耳机推荐

近几年&#xff0c;运动耳机愈发获得消费者的认可。它拥有着更牢固的佩戴方式&#xff0c;即便是长时间佩戴、也拥有更舒适的体验。因此&#xff0c;运动耳机也受到运动、健身人群的喜爱。但是不少小伙伴跟我反映如何选择一款体验出色的运动耳机&#xff0c;也成为了当前不少运…

计算机sci期刊拒稿两次,重新投稿接受的概率大吗? - 易智编译EaseEditing

重新投稿需要修改的幅度很大&#xff0c;而且就算能接受&#xff0c;时间也会非常久。 要是不着急用可以试试&#xff1a; 根据审稿意见一条条的来修改&#xff1b; 增加新的参考文献&#xff1b; 如果是“修改后重投”&#xff0c;可能需要注意以下问题&#xff1a; 1. 与…

数据可视化,2022A股正式收官,这么特别的一年,你挣钱了吗?

“A股年线止步三连阳&#xff01;深成指全年累计下跌25.85&#xff05;&#xff1b;创业板指全年累计下跌累计29.37&#xff05;&#xff1b;上证50指数累计下跌19.52&#xff05;&#xff1b;科创50指数累计下跌31.35&#xff05;。其中&#xff0c;创业板指、深成指仅跑赢俄罗…

循环神经网络-高级篇RNN Classifier

循环神经网络-高级篇RNN Classifier 本篇实现一个循环神经网络的分类器RNN Classifier 我们使用一个数据集包含Name&#xff0c;Country&#xff0c;其中名字有几千个&#xff0c;来自18个不同的国家&#xff0c;我们的目标是训练一个模型&#xff0c;可以实现输入一个名字&a…

cad绘图:AutoCAD 2023 中文

Autodesk AutoCAD 2023是计算机辅助设计(CAD)软件&#xff0c;是世界领先的2D和3D CAD工具。它将允许您使用其强大而灵活的功能来设计和塑造您周围的世界。在3D中加速文档制作&#xff0c;无缝地分享想法&#xff0c;更直观地探索想法。AutoCAD使用户能够从桌面、Web和移动设备…

http 模块

1、什么是 http 模块 http 模块是 Node.js 官方提供的、用来创建 web 服务器的模块。通过 http 模块提供的http.createServer() 方法&#xff0c;就能方便的把一台普通的电脑&#xff0c;变成一台 Web 服务器&#xff0c;从而对外提供Web 资源服务。 如果要希望使用 http 模块…

Centos8/linux下载、安装、配置、连接MySQL5.7(rpm方式)

目录 问题现象&#xff1a; 问题分析&#xff1a; 解决方法&#xff1a; 下载&#xff1a; 安装&#xff1a; 配置&#xff1a; 连接&#xff1a; 拓展 问题现象&#xff1a; 今天在使用Centos8 安装MySQL5.7的rpm包时&#xff0c;出现如下报错&#xff1a; 仓库 "…

【ROS】—— ROS运行管理 ——元功能包与launch文件(八)

文章目录前言1. 元功能包1.1 应用场景1.2 概念1.3 实现2. ROS节点运行管理launch文件2.1 launch文件标签之launch2.2 launch文件标签之node2.3 launch文件标签之include2.4 launch文件标签之remap2.5 launch文件标签之param2.6 launch文件标签之rosparam2.7 launch文件标签之gr…

2023年伊凡最新整理简单方法之为hbuilderx配置node环境实现可npm install

本文优雅草伊凡投稿一颗优雅草科技&#xff0c;欢迎其他朋友们来投稿&#xff08;一定会详细署名&#xff09;&#xff0c;好直接开始&#xff0c;由于伊凡的电脑实在太卡了因此重装了一下系统所有环境全没了可能要一步步做环境了&#xff0c;后续可能会发关于flutter&#xff…

ModStartBlog v6.5.0 后台多页面升级,支持Laravel9

ModStart 是一个基于 Laravel 模块化极速开发框架。模块市场拥有丰富的功能应用&#xff0c;支持后台一键快速安装&#xff0c;让开发者能快的实现业务功能开发。 系统完全开源&#xff0c;基于 Apache 2.0 开源协议。 功能特性 丰富的模块市场&#xff0c;后台一键快速安装会…

DCDC直流非隔离负高电压输出电源模块12V24V转0-负50v/-150v/-200v/-250v/-300v/-400v/-500v

特点● 效率高达70%以上● 1*2英寸标准封装● 单电压负输出● 价格低● 电压控制,输出电压随控制电压变化线性变化● 工作温度: -40℃~85℃● 阻燃封装&#xff0c;满足UL94-V0 要求● 温度特性好● 可直接焊在PCB 上应用GRB 系列模块电源是一种DC-DC升压变换器。该模块电源的输…