【学习记录】ORBSLAM2均匀化策略源码解析

news2024/12/24 21:10:36

在ORBSLAM中,为了保证特征的均匀分布使用了均匀化的策略,最近在尝试扩展一下均匀化的内容,所以仔细看了一下ORBSLAM源码里面这部分的内容,之前看源码的时候没有展开仔细看这一部分的代码,这里补充记录一下,之前的阅读记录可参考链接

在展开看代码之前,首先对ORBSLAM的均匀化策略做一个小总结。均匀化本身是为了让特征在整张图像上分布得更加均匀,也就是保证图中每个位置基本都能有几个特征点,这样做的目的就是为了在位姿估计时能够更加准确。均匀化主要分为两个部分:分割和取点。分割指的是利用四叉树结构,对节点不断进行划分,从而达到满足特征点数目的节点个数。取点则是在划分好的节点中,选取落入节点中的一定数目的特征点,从而实现特征点的提取。

分割节点

均匀化的代码对应位置在ORBextractor.cc里面的DistributeOctTree函数中,该函数传入了待划分的特征点、图像的基本范围、特征点的目标数量以及一个层数,不过层数这个量好像在函数里面没有用到。下面简单看一下代码的实现,进入函数之后,首先会根据图像的宽高比,确定需要多少个初始节点,一般来说是一个,最多也不会超过两个,所以这里我们按照一个初始节点来计算。需要注意的是,由于使用的是树结构的分割方法,所以这里我们用节点这个词,一个节点表示的是图像中的一个范围,或者说一个格子,那么初始节点相当于是整张图像。
在这里插入图片描述
确定好初始节点的数目,就初始化这个初始节点ni,初始化过程中指定了节点的范围并为特征点预留了存储空间,之后就放入了lNodes的列表中,用于后续的分割流程。之后代码将特征点分配给了这个节点内部的vKeys的向量中,并根据初始节点的特征点数目,给初始节点的分割状态进行标记。
在这里插入图片描述
这里补充一下,均匀化的过程中,其实会根据内部特征点的数量,划定三种状态,如果节点内部一个特征点都没有,那就直接删掉,不向lNodes里面添加,如果节点内部只有一个特征点,就会将bNoMore标记为true,表示这个节点不能再进行分割了,最后一种状态就是特征点多于一个,表示这个节点还可以继续分割。

做好这一些准备工作之后,就可以开始分割了,分割的过程简单来说就是一分四,然后检查四个子节点是不是可以继续分割,如果可以,放入lNodes里面,否则就跳过。进入分割的循环后,会利用bFinish作为结束的标准,分割按照轮次进行,这里为了方便理解,一个轮次分割的节点我们就认为是开始分割时lNodes里面拥有的节点,之后每次从lNodes里面拿出一个节点作为要分割的节点。
在这里插入图片描述
对于当前的这个节点,如果内部只有一个特征点,说明不能再分割但也不能直接扔掉,不对它做任何处理直接continue,如果能够进行分割,就调用DivideNode函数,将当前节点分割为四个子节点并将特征点放入其中,如果四个子节点中某个节点有特征点,那么首先将子节点放入lNodes中,之后检查这个节点的状态,确定是否可以进行分割。这里有一个细节,在将子节点放入lNodes时,调用的函数是push_front而非我们常用的push_back,调用这个函数会将节点插入到list的最前面,这样子相当于用一个普通的list实现了类似广搜的操作,这里我们按照代码流程理顺一遍,假设在一轮分割开始之前,lNodes里面有节点ABCD,现在我们取出节点A,这个节点分割出四个子节点abcd,这个时候我们假设这四个子节点都是可以分割的,那么根据代码的执行顺序,节点A通过erase函数去掉,指针移动到B的位置,四个子节点通过push_front插入到lNodes前面,所以对A的分割结束后,lNodes变为abcdBCD,下一次将开始B的分割,这样子在这一轮分割结束后,一共进行了四个节点的分割:ABCD,正好是这一轮分割开始前lNodes里面有的四个节点,同时内部特征点大于等于一的子节点将重新放入lNodes等待下一轮的继续分割。

这一层循环结束的标准是一轮分割结束,在一轮分割结束后,会有一个检验是否结束分割的步骤,如果lNodes里面的节点数目多于要提取的特征点数量,或者一轮分割前后节点数没有变化,则认为达到了分割结束的标准。这里稍微看一下这两个标准,这个if条件里面是两个或条件,根据节点数来判断是因为,我们在前面分割的时候,所有留在lNodes里面的节点,都是内部特征点大于等于1的节点,也就意味着,特征点数目一定是大于等于节点数的,当节点数都多于目标特征点数目的时候,说明没有再继续分割的必要了,直接提取点就够了,所以这个时候选择结束分割,另一个条件则是一轮分割前后节点数没有变化,这里其实对应的就是lNodes中所有节点都是不可再分割的节点,这时候不管重复多少次都是一样的,所以选择结束分割。
在这里插入图片描述
而另一个分支其实是想在停止分割的前一轮进行细微操作,这里可以看到依然是利用目标特征点数目做了一个约束,而约束的内容就是下次分割以后特征点的数目,一个可以分裂的节点分裂后最多产生四个新的子节点,从数目上看增加了三个,所以这里是乘三再做加法,表示下次分割之后最多的数目。如果进入这个分支,相当于在停止分割的前一轮进行下面的一大段操作。
在这里插入图片描述
在这个分支中,其实也是在重复进行分割操作,直到满足结束分割的条件,在这个分支中,需要对这一轮分割新加入的节点进行分割,相当于进行了下一次分割但是确实是在这一轮次中。对新加入的节点利用sort函数进行排序,根据节点内部的特征点数量进行升序排序,这里代码实现上是直接调用的sort,但是并没有指定排序函数,根据sort的默认排序规则,应该是升序,而且排序的是一个元素为pair的vector,所以按道理是根据pair的第一个元素进行排序,如果相同在根据第二个,由此推测是根据内部特征点数量进行的升序排序。
在这里插入图片描述
排序后根据内部特征点的数量,从大到小进行节点的遍历,对每个节点进行分割,操作与前面的分割一样。不同之处在于,如果对一个节点进行分割之后,如果满足了停止分割的条件,就直接结束分割,而不是完成这一轮之后再结束分割。
在这里插入图片描述
所以这里的分割策略就是先按照轮次进行分割,分割到倒数第二次,就换成以子节点为单位进行分割。那么问题在于,如果倒数第二次就更换了分割策略,那是不是就不需要最后一次的策略进行检验了。这里这种写法本意是让分割过程中进入倒数第二次时,更换分割策略从而防止过度分割,但是总感觉哪里有些问题却又说不上来。

提取

提取的过程就相对简单很多了,遍历lNodes中每一个节点,选择出这个节点中特征点响应值最高的点作为这个节点最终筛选出来的特征点,存入向量中返回即为最终结果。
在这里插入图片描述

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

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

相关文章

未来SSD的接口趋势是什么?

针对SSD接口标准,目前业内有两大组织:PCI-SIG:这个就是定义pcie协议标准的那个组织,我们常见的传统接口M.2, U.2, 2.5英寸的接口都归这个组织定义规范。M.2,U.2起源与客户端,也是企业级当前最常用的接口形式…

elasticdump迁移ES数据详解

文章目录elasticdump 简介1.elasticdump导入ES数据到本地json文件2、将本地数据导入es中3、将es导入另一个es4 .其他参数使用--searchBody使用--searchBody 向本机ES导数据使用--typeanalyzer导出分析器elasticdump 简介 elasticdump是一个能够将es的数据快速导入、导出、迁移…

最新最全-中文生物医学命名实体识别最新研究论文、资源、数据集、性能整理分享

本资源旨在跟踪中文生物医学自然语言处理的进展,收集整理相关的论文列表和展示现存方法性能。内容整理自网络,源地址:https://github.com/lingluodlut/Chinese-BioNLP中文电子病历命名实体识别中文电子病历命名实体识别(Chinese C…

《操作系统-真象还原》阅读总结/遗憾离场/加倍努力 出人头地

文章目录关于我又被老天算计奇奇怪怪的 BUG调试 BUG 的心理历程最后两天通宵调试程序的宵夜阅读建议本书所有笔记最后关于我又被老天算计 从 2022-09-14 读这本书,原计划是 2022-12-15 之前完成的,我自信能完成,因为11月下旬我已经开始阅读第…

【Linux】初识进程

文章目录进程控制块的引入初识进程控制块(PCB - Process Control Block)什么是PCBLinux下的PCB初见进程ps指令查看进程kill指令挂掉进程通过系统调用接口得到进程的ID(进程标识符)从根目录下的proc文件查看进程通过fork函数创建子进程进程控制块的引入 首先,听到进…

事故复盘 | 对不同的ID更新操作竟然也引发死锁?

对不同的ID更新操作竟然也引发死锁? 文章目录对不同的ID更新操作竟然也引发死锁?背景分析初步分析 - 怀疑程序并发问题进一步分析 - 怀疑主键缺失行级锁失效再进一步分析 - 是否存在死锁条件解决方案复盘附录示例的死锁日志常用故障排查 SQL参考链接背景…

webassembly学习

webassemblywebassembly学习基本理论webassembly介绍wasm介绍基本信息wasm会替换javascript么ASM.js(wasm的前身)将 WebAssembly 作为编程语言的一种尝试wasm应用场景wasm运行原理周边生态WASI 操作系统接口wasi介绍wasmwasi(服务端&#xff…

平台总线式驱动开发——基本框架

1. 总线、设备和驱动 硬编码式的驱动开发带来的问题: 垃圾代码太多结构不清晰一些统一设备功能难以支持开发效率低下 1.1 初期解决思路:设备与驱动分离 struct device来表示一个具体设备,主要提供具体设备相关的资源(如寄存器地…

ES为什么要移除types类型

文章目录elasticsearch(集群)中可以包含多个索引index(数据库) ,每个索引中可以包含多个类型types(表) ,每个类型下又包含多个文档Document(行) ,每个文档中又包含多个字段Field&…

姿态估计评价指标

PCK 正确估计出关键点的百分比 (Percentage of Correct Keypoints),现在已基本不用。 PCKik∑iδ(did≤Tk)∑i1PCK_i^k\frac{\sum_i\delta(\frac{d_i}{d}\leq T_k)}{\sum_i1} PCKik​∑i​1∑i​δ(ddi​​≤Tk​)​ 检测出的关键点与其对应…

1 机器学习之线性回归

学习笔记自,慕课网 《Python3 入门人工智能》 https://coding.imooc.com/lesson/418.html#mid33109 麻雀虽小,五脏俱全 1.1 回归分析 1.2 线性回归问题求解 1.3 寻找最合适的 a、b,引入损失函数的概念 尽可能使损失函数最小即找到了最合适的…

(重要)实数域上一切范数等价的证明

证明:实数域上一切范数等价编辑切换为居中添加图片注释,不超过 140 字(可选)首先需要明确范数等价的条件,这里的条件等价于夹逼,就是A小于等于B,B小于等于A,那么A肯定等于B。利用这个…

【MySQL】InnoDB存储引擎的行结构

文章目录前言1、MySQL的体系结构2、InnoDB逻辑存储结构3、InnoDB记录行结构3.1、概述3.2、语法操作3.3、Compact行格式3.3.1、示意图3.3.2、记录的额外信息3.3.3、记录的真实数据3.3.4、定长字段补充3.4、行溢出前言 MySQL服务器上负责对表中数据的读取和写入工作的部分是存储…

【博学谷学习记录超强总结,用心分享|产品经理基础总结和感悟14】

TOC 第三章, 内容服务平台优化思考 前文中,我们粗略分析了用户阅读内容的诉求和创作者编制内容的诉求,本章笔者尝试结合用户诉求分析平台的内容分发策略,结合创作者诉求分析创作者后台设计思路,创作者后台分析主要从…

Java实现支付宝支付,内网穿透,支付功能实现-57

一:支付业务 1.1 支付宝业务简介 1)网页跳转到支付宝收银台页面。用户可以使用支付宝App扫一扫屏幕二维码,待手机提示付款后选择支付工具输入密码即可完成支付; 2)如果不使用手机支付,也可以点击上图右侧…

Visual Studio解决方案中添加src文件夹的方法

如标题,这个听起来是一个愚蠢的问题,但如果在Visual Studio想添加一个src文件夹,而命名空间不包含src的话,似乎还真不容易。 如果在Visual Studio里新建一个空白解决方案,然后右键解决方案->添加->新建解决方案…

鲲鹏BigData Pro解决方案中Hive组件的部署

1 介绍 本博文基于《鲲鹏Bigdata pro之Hive集群部署》的实验手册进行,目的是方便Hive学习者重用(从本文复制)相关的指令、配置和代码。同时,会对相关的Bash命令解释,达到增进理解的目的。 2 Hive组件的部署 部署的前…

探索SpringMVC-HandlerAdapter之RequestMappingHandlerAdapter-参数解析

前言 上回,我们大概讲了下HandlerAdapter。今天带大家来认识一下,我们最常用的RequestMappingHandlerAdapter。不过只能给大家先开个头,讲下参数解析。 RequestMappingHandlerAdapter 在介绍HandlerAdapter时,我们就知道Handle…

自己动手写编译器:从NFA到DFA

上一节我们完成了使用NFA来识别字符串的功能。NFA有个问题就是其状态节点太多,使用起来效率不够好。本节我们介绍一种叫“子集构造”的算法,将拥有多个节点的NFA转化为DFA。在上一节我们描述的epsilon闭包操作可以看到,实际上所有由epsilon边…

「ARM32」MMU和页表的映射过程详解

在ARM32中,MMU主要完成虚拟地址到物理地址的映射,并且能够控制内存的访问权限,而页表是实现上述功能的主要手段。页表又分为一级页表、二级页表,在ARM64中甚至还有三级页表。为了便于理解,本章主要讲述一级页表完成段映…