orb-slam中的orb特征

2023-05-16

1.ORB特征简介
ORB是Oriented FAST and Rotated BRIEF(oFAST and rBRIEF)的简称,ORB的名字已经说明了其来源,其实ORB特征是采用FAST方法来检测提取特征,但FAST特征本身是不具有方向性的,所以在ORB特征中添加对特征方向的计算;另外,ORB采用BRIEF方法计算特征描述子,BRIEF的优点在于速度,但是缺点也很明显:不具备旋转不变性,对噪声敏感,不具备尺度不变性。orb-slam重点解决的是旋转不变性和噪声问题。接下来,首先针对orb特征进行详细说明,并在下一章节中针对orb-slam(version1)中的orb代码部分进行解析测试。

[以下为个人学习理解,如果错误,欢迎指正]
2.orb特征之oFAST

如何确定特征点?
FAST特征以其计算速度快被广泛使用,ORB特征除了使用FAST方法定位特征点位置之外,还针对特征点的方向进行了补充添加。

FAST特征的基本原理是对于当前像素点,取邻域离散圆周上若干采样像素点(如下图的p点表示当前像素位置,以3个像素点为半径,标号1-16的16个点表示圆周上采样的16个像素点)

这里写图片描述

我们认为一个像素如果是“角点”(即特征点),那么这16个采样点中至少有N(N可以等于9,12等,对应于FAST-9,FAST-12等)个连续像素点要么大于当前像素点加上一个阈值,要么小于当前像素点减掉一个阈值,我们设这个阈值为t。但实际上,通常在图像中,“角点”的数量要远小于非“角点”的数量,所以可以采用一种更快速的方法来确定当前像素点是否为“角点”(实际上是快速的排除非特征点的像素),方法是,
1)当前像素点p与标号为1,9的像素点进行比较,如果有 Ipt<Ii<Ip+t,i= 1 or 9 ,则当前像素点肯定不是“角点”,否则的话进行下一步判断;
2)当前像素点p与标号1,5,9,13的像素点进行比较,如果至少有三个像素点满足 Ii<Ipt or Ii>Ip+t,i= 1 or 5 or 9 or 13,则认为当前像素点可能为“角点”,进行下一步判断;
3)当前像素点p与所有标号的采样像素点进行比较,如果至少有N (N可以等于9,12等,对应于FAST-9,FAST-12等)个连续像素点满足 Ii<Ipt or Ii>Ip+t,i=1...16 ,则认为当前像素点为“角点”,即FAST特征点,进行下一步非极大值抑制;
4) 非极大值抑制主要是为了避免图像上得到的“角点”过于密集,主要过程是,每个特征点会计算得到相应的响应得分,然后以当前像素点p为中心,取其邻域(如3x3 的邻域),判断当前像素p的响应值是否为该邻域内最大的,如果是,则保留,否则,则抑制。

上面针对如何选择特征点进行了说明,需要补充的是,orb特征中使用不同尺寸图像构成的图像金字塔,并分别在每一金字塔层图像上提取FAST特征,这样每一个被提取的特征具有“尺度”这一属性。

如何确定特征点方向?
现在我们已经知道如何在当前尺度空间中提取FAST特征,而特征点除了坐标/尺度(层)属性之外,还需要确定特征点的方向。接下来,将阐述orb如何为每一个特征点分配方向。

orb特征确定特征点方向的思路很简单,首先根据“矩”概念确定当前特征点邻域块的重心位置 C ,然后根据当前像素点中心O C 的连线方向确定特征点方向θ
像素块区域的“矩“定义为,

mpq=x,yxpyqI(x,y)

则重心坐标公式为,
C=(m10m00,m01m00)

那么,特征点的方向角度定义为,
θ=atan2(m01,m10)

3.ORB特征之rBRIEF

如何计算特征点描述符?
上面已经介绍了如何提取图像中的FAST特征以及如何计算特征点的方向,接下来将介绍如何计算每一个特征点的描述子。

ORB特征描述子采用BRIEF描述子并进行了改进,BRIEF描述子占用空间小,得益于BRIEF描述子的每一位要么是0要么是1,其基本思想是:在特征点邻域块内,按照一定的规则选择若干对像素点 p,q ,如果有 Ip>Iq ,则当前位的BRIEF描述子的值为1,否则为0。对于比较像素点对的个数,通常可以选择128,256不等。

但实际上,这样会存在一个很严重的问题,就是得到的描述子会对噪声很敏感,如果比较的像素点属于噪声,将对描述子的可靠性造成重要影响。所以,将上述的比较规则进行了调整,

τ(p;x,y):=1:p(x)>p(y);τ(p;x,y):=0:p(x)p(y)

其中, p(x) 表示像素点x的强度值,可以选择高斯滤波值作为当前像素点的强度值,这样比较的两者不会是单独的两个像素点值,而是像素点邻域块的加权平均值,从而有效地降低了噪声的影响。

steered BRIEF
BRIEF描述子本身没有解决旋转不变性的问题,所以在orb特征中对这个问题进行了解决,解决思路也很简单,就是在计算特征点描述子的过程中,将其邻域的若干比较对根据特征点的方向进行相应的旋转变换,即,如果 n 个测试对坐标表示为,

S=(P1,P2,...,Pn),Pi=(xi,yi)

特征点方向角度为 θ ,对应的旋转矩阵为 Rθ ,那么修正后的比较点对坐标 Sθ 为,

Sθ=RθS

将修正后的坐标 Sθ 带入描述子的计算,这样得到的描述子是具有据转不变性的。

rBRIEF
上面阐述中有一个关键问题,那就是应该如何选择比较点对呢?这样考虑,如果比较点对的个数为256,那么最终的BRIEF描述子的位数就是256位,一个好的BRIEF描述子的每一位的变化性(variance)应该是足够大的,或者说每一位的数值分布是比较均匀的,不会过于密集或稀疏;另一个方面,BRIEF描述子的不同位之间应该是不相关的(也就是任意一位的表示应该具有代表性,而不会被其他的若干位线性表示)。

orb特征采用下面这样的算法来选择比较点对的坐标,
首先从数据集中确定300k个关键点。对于31x31的像素块,穷举所有5x5的子窗口像素块,也就是31x31像素块中所有的子窗口可能性有N=(31-5)*(31-5)种.那么从N种子窗口中选择2个子窗口进行比较的可能性就有 C2N ,除去存在重叠的比较子窗口对,最终有M=205590种测试可能(比较子窗口对)。

接下来,
1)对于M种中的每一种测试可能性,在300k个关键点上计算比较结果(每一种可能性对应于BRIEF描述子中的一位);
2)对于每一种测试可能性在关键点上的比较结果,计算300k个数据上的平均值,并按照距离0.5的远近大小由小到大进行排序,构成集合T(距离0.5越近,认为数据分布越平均,可以考虑这样的例子,100个数据中,有50个1,50个0,这样的数据是分布最均匀的,均值为50/100=0.5;而如果100个数据中均为1,则均值为100/100=1,是数据分布最为密集的情况)。这一步是考虑选择尽可能使得每一位BRIEF描述子的数据分布分散的比较对。
3)采用贪心算法
3.1)首先将T中的第一个测试对放入集合R;
3.2)从T中取下一个排序测试对,并与R中的所有测试对计算关联度,如果关联度超过一定的阈值,则放弃当前从T中取到的测试对;反之,则将当前的测试对加入集合R中;
3.3)重复前两步,直至R中有256个测试对。

R中挑选的256个测试对就是满足:
a 每一位描述子的variance尽可能大;
b 不同位描述子之间的关联度尽可能小。

4.总结
总而言之,ORB特征是采用FAST方法定位特征点坐标,采用矩方法计算特征点方向,使用BRIEF计算特征点描述子并根据特征点方向使得描述子具有旋转不变性,另外,通过贪心算法确定测试对。

在下一章节中,将根据orb-slam源代码中关于orb特征部分进行解析。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

orb-slam中的orb特征 的相关文章

  • 微信小程序SLAM AR零基础入门教程

    鬼灭之刃花街篇 开播在即 今天带大家零基础使用Kivicube制作一个炭治郎的SLAM AR云手办 可以通过微信小程序将AR版的炭治郎放置在家中 提前感受鬼灭的氛围 先上个GIF大家看看动态的展示效果 在这里先科普一下本次教程使用到的AR技
  • ROS激光SLAM导航理解

    ROS激光SLAM导航理解 注 最近学习ROS的激光导航知识 需要理清ROS的SLAM 环境感知 costmap 与导航算法 为防止自己忘记 将觉得有价值的内容收集于此 对AGV来说 SLAM是个大大坑 环境感知和局部运动控制也是大坑 学习
  • 【大一立项】如何亲手搭建ROS小车:硬件和软件介绍

    本次博客将详细介绍上篇博客中提到的ROS小车的硬件和软件部分 由于十一实验室不开门 所以部分代码还没有上传到Github 下位机 下位机使用Arduino 因为大一上刚学完用Arduino做循迹小车 其实Arduino作为ROS小车的下位机
  • 使用EKF融合odometry及imu数据

    整理资料发现早前学习robot pose ekf的笔记 大抵是一些原理基础的东西加一些自己的理解 可能有不太正确的地方 当时做工程遇到的情况为机器人在一些如光滑的地面上打滑的情形 期望使用EKF利用imu对odom数据进行校正 就结果来看
  • SLAM评估工具evo的使用

    evo官方指南 参考博客 lt 官方手册 这篇参考博客 完全可以掌握evo的基本操作 gt Then 实践出真知 1 安装evo sudo apt install python pip pip install evo upgrade no
  • 视觉SLAM实践入门——(20)视觉里程计之直接法

    多层直接法的过程 1 读图 随机取点并计算深度 2 创建图像金字塔 相机内参也需要缩放 并计算对应点的像素坐标 3 应用单层直接法 使用G N L M等方法 或者使用g2o ceres库 进行优化 源码中有一些地方会引起段错误 修改方法见下
  • 对最小二乘法的一点理解 - slam学习笔记

    我对最小二乘法的理解 在给定参数个数和函数模型之后 根据测试数据 找出与所有测试数据的偏差的平方和最小的参数 这里面应该有两个问题 1 为什么选取与真实数据平方和最小的拟合函数 2 如何求参数 为什么选取与真实数据平方和最小的拟合函数 极大
  • 【SLAM】libQGLViewer:VS 2019 + Qt 5.14.2 + Win 10 配置

    libQGLViewer 2 7 2 VS 2019 Qt 5 14 2 Win 10 配置 注意 这次配置没有完全成功 编译25个成功 一个失败 失败的是 qglviewerplugin qglviewerplugin 是一个可选控件 不
  • [SLAM四元数基础系列一] 四元数定义 Hamilton vs JPL

    四元数定义 Hamilton vs JPL 简介 四种区分方式 Hamilton vs JPL 引用 不管是卡尔曼滤波或者BA优化形式的SLAM或者VIO系统中 都需要用到单位四元数 Quaternion 来表示旋转 主要是单位四元数表示旋
  • LeGO-LOAM 系列(1): LeGO-LOAM 安装以及概述

    一 github GitHub RobustFieldAutonomyLab LeGO LOAM 二 安装依赖 1 ROS Ubuntu 64 bit 16 04 ROS Kinetic 比较常规 就不赘述了 2 gtsam Georgia
  • 图像匹配算法

    图像匹配算法分为3类 基于灰度的匹配算法 基于特征的匹配算法 基于关系的匹配算法 1 基于灰度的模板匹配算法 模板匹配 Blocking Matching 是根据已知模板图像到另一幅图像中寻找与模板图像相似的子图像 基于灰度的匹配算法也称作
  • Lego-LOAM IMU坐标系变换的详细记录

    Lego LOAM IMU坐标系变换的详细记录 0 基础知识 1 IMU 重力加速度消除 2 相机坐标系 camera 到初始坐标系 camera init 的转换 最近看了Lego LOAM 的IMU部分 没看懂IMU的坐标系变换 看其它
  • SLAM-hector_slam 简介与使用

    hector slam功能包使用高斯牛顿方法 不需要里程计数据 只根据激光信息便可构建地图 所以他的总体框架如下 hector slam功能包 hector slam的核心节点是hector mapping 它订阅 scan 话题以获取SL
  • Ubuntu20.04安装各种库----简洁版

    目录 Eigen3 Sophus Pangolin Ceres g2o 建议先装anaconda再装ros python opencv啥该有的都有了 下面仅仅安装ros没有的库 Eigen3 作用 线性代数开源库 提供了有关线性代数 矩阵和
  • 快看!那个学vSLAM的上吊了! —— (一)综述

    不同于之前发布的文章 我将使用一种全新的方式 iPad Notability Blog的方式打开这个板块的大门 原因有两个 1 Notability更方便手写长公式 也方便手绘坐标系变换等等 2 之前Apple Pencil找不到了新破费买
  • Object SLAM: An Object SLAM Framework for Association, Mapping, and High-Level Tasks 论文解读

    是一篇来自机器人顶刊T RO的文章 发表于2023 5 An Object SLAM Framework for Association Mapping and High Level Tasks 论文 An Object SLAM Fram
  • Eigen几何模块的使用方法

    include
  • SLAM练习题(十一)—— G2O实战

    SLAM 学习笔记 写在前面的话 算是一点小小的感悟吧 估计位姿的方法有线性方法和非线性方法 线性方法就是特征点法中的2D 2D的对极约束 3D 2D的PnP问题 非线性方法有BA优化 它将位姿的估计问题转换成了一个误差关于优化量的最小二乘
  • LIO-SAM运行自己数据包遇到的问题解决--SLAM不学无数术小问题

    LIO SAM 成功适配自己数据集 注意本文测试环境 Ubuntu18 04 ROS melodic版本 笔者用到的硬件以简单参数 激光雷达 速腾聚创16线激光雷达 RS Lidar 16 IMU 超核电子CH110型 9轴惯导 使用频率1
  • 什么是深度学习的无监督学习与有监督学习

    无监督学习 深度学习中的无监督学习方法是一种训练算法 它在没有标注输出的情况下从输入数据中学习模式和特征 这种方法的核心是探索和理解数据的内在结构和分布 而不是通过已知的输出来指导学习过程 无监督学习在深度学习领域有许多不同的形式和应用 以

随机推荐

  • UMD代码格式

    span class token punctuation span span class token keyword function span span class token punctuation span root span cla
  • Tomcat Server.xml配置详解

    在理解Tomcat配置之前 xff0c 需要先熟悉一下Tomcat的架构 xff0c 便于更好的修改配置 一 Tomcat结构 server xff1a 即服务器 xff0c 每个tomcat程序启动后 xff0c 就是一个server s
  • Linux下U盘、SD卡挂载与卸载

    1 手动挂载 卸载 U盘 SD卡 对于ARM Linux来说 xff0c 第一次使用U盘或SD时 xff0c U盘这个文件目录是不能直接进入的 xff0c 我们需要对其进行挂载 xff0c 然后再接下来的使用中就可以直接进行使用了 通过再网
  • Java 阻塞队列--BlockingQueue

    1 什么是阻塞队列 xff1f 阻塞队列 xff08 BlockingQueue xff09 是一个支持两个附加操作的队列 这两个附加的操作是 xff1a 在队列为空时 xff0c 获取元素的线程会等待队列变为非空 当队列满时 xff0c
  • 大厂SQL经典面试题(二)留存问题

    留存率 是用户分析的核心指标之一 xff0c 留存问题也是一个经常考的题目 问题 现场写一道SQL 给定用户表Users 求出每个日期对应的活跃用户数 次日留存用户数 次日留存率 指标定义 某日活跃用户数 某日活跃的去重用户数 N日留存用户
  • 程序猿代码面试指南 PDF

    前言 今年是最难求职年 xff0c 我希望通过这篇文章能帮大家提高求职成功率 这篇文章分为简历篇 面试篇 谈薪酬篇 xff0c 包括了找工作过程中各个环节的技巧和防坑指南 这篇文章就是给大家分享左神这本 程序员代码面试指南 IT名企算法与数
  • 从 Java 代码逆向工程生成 UML 类图和序列图

    前言 本文面向于那些软件架构师 xff0c 设计师和开发人员 xff0c 他们想使用 IBM Rational Software Architect 从 Java 源代码来逆向工程生成 UML 类和序列图 逆向工程经常被用来从已有的源代码中
  • http的三次握手

    在http的三次握手当中 xff0c 首先客户端发起一个我要发送一个数据包的请求 xff0c 发送到服务端 xff0c 这里面呢会有一个标志SYN 61 1 Seq 61 X xff0c syn是一个标识 xff0c 就是我这是一个创建请求
  • SQL优化面试专题

    介绍 xff1a 无论您是创建Web应用程序的开发人员 xff0c 还是参与Web测试的DBA或测试人员 xff0c SQL方面的技巧在数据库编程和数据库验证中都非常重要 因此 xff0c 我们整理了QL性能优化方面的面试问题 SQL性能优
  • Docker容器:将带UI的程序直接转为Web应用,so easy

    摘要 xff1a 使用Docker容器 xff0c 将带UI的程序 xff0c 直接转换为Web应用 很方便 xff0c 跟大家分享一下 本文分享自华为云社区 使用Docker容器 xff0c 将带UI的程序 xff0c 直接转为Web应用
  • 38道多线程核心面试题(附答案)

    前言 今天给大家分享的是比较全面的多线程面试题 xff0c 大家在面试的过程中不免会被问到很多专业性的问题 xff0c 有的时候回答的并不是那么全面和精细 xff0c 这仅仅代表个人观点 1 如何预防死锁 xff1f 1 首先需要将死锁发生
  • Java程序员,最常用的20%技术有哪些?

    1 基本的数据结构和算法真的非常重要 xff1a 不管你做过多少项目或者是熟悉多少框架和工具 xff0c 面试和考察一个人还是大部分停留在基本功上 所以 xff0c 在每天工作开发之余 xff0c 应保证一定的时间段不断去打磨自己的基本功
  • Linux 程序编译过程详解

    大家肯定都知道计算机程序设计语言通常分为机器语言 汇编语言和高级语言三类 高级语言需要通过翻译成机器语言才能执行 xff0c 而翻译的方式分为两种 xff0c 一种是编译型 xff0c 另一种是解释型 xff0c 因此我们基本上将高级语言分
  • 关于485总线 A、B端上拉下拉电阻选择

    问 xff1a about rs485 用电阻上拉 B用电阻下拉 A B间用电阻连接 xff0c 这些电阻参数大致多少 xff1f 我们公司的设计是 TTL输入都用光偶隔离 输出加上拉和下拉 xff0c 中间加TVS和2个电阻串联 xff0
  • JAVA集合框架(一)-ARRAYLIST

    1 ArrayList的特点 存放的元素有序元素不唯一 可以重复 随机访问快插入删除元素慢非线程安全 2 底层实现 底层初始化 xff0c 使用一个Object类型的空对象数组 xff0c 初始长度为0 源码 Object类型对象数组引用
  • Java如何将两个数组合并为一个数组呢?

    数组 xff1a 数组 xff08 Array xff09 是有序的元素序列 1 若将有限个类型相同的变量的集合命名 xff0c 那么这个名称为数组名 组成数组的各个变量称为数组的分量 xff0c 也称为数组的元素 xff0c 有时也称为下
  • pca9548及vsc9548的设备树简单挂载

    简述 pca9548及vsc9548是iic拓展器件 xff0c 主要是防止iic器件地址冲突 通过写其0x0寄存器可切换0 7路iic 设备树挂载 这里用到了vsc9548 xff0c 且在第7路上挂在了eeprom器件 i2c 64 f
  • 类的作用域

    类的作用域简称类域 xff0c 它是指在类的定义中由一对花括号所括起来的部分 每一个类都具有该类的类域 xff0c 该类的成员局部于该类所属的类域中 在类的定义中可知 xff0c 类域中可以定义变量 xff0c 也可以定义函数 从这一点上看
  • 常见问题(持续更新)

    近期整理的初级开发遇到的问题 xff0c 希望对大家有用 1 Unsatisfied dependency expressed through field 39 baseMapper 39 于是在pom xml中搜索mybatis关键字 x
  • orb-slam中的orb特征

    1 ORB特征简介 ORB是Oriented FAST and Rotated BRIEF xff08 oFAST and rBRIEF xff09 的简称 xff0c ORB的名字已经说明了其来源 xff0c 其实ORB特征是采用FAST