文档章节

ORB图像特征检测

Pulsar-V
 Pulsar-V
发布于 2017/08/03 13:22
字数 1938
阅读 43
收藏 1
点赞 0
评论 0

#ORB算法推导

ORB采用FAST (features from accelerated segment test) 算法来检测特征点。FAST核心思想就是找出那些卓尔不群的点,即拿一个点跟它周围的点比较,如果它和其中大部分的点都不一样就可以认为它是一个特征点。 首先来做几个定义:
U : 参考像素点周围的区域阈值
t : 与参考像素点作对比的阈值点的灰度值当参考点的灰度值之差的绝对值大于t时,我们认为这两个点不相同
Gp : 像素点的灰度值
u : 区域阈值内不同的像素点数量
Un : 区域阈值内的连续像素点数目

FAST计算过程:

  1. 遍历图像矩阵一个参考像素点P。
  2. 考虑该像素点周围的Un个像素。
  3. 现在如果这Un个点中有连续的u个点都和参考点不同,那么它就是一个角点。
  4. 现在我们考虑一下这个检测思路,当我们遍历图像矩阵的时候还需要再一次的去遍历图像参考像素点周边的点,所以这个思路需要进行优化,所以我们 只需要检测参考像素点的矩形区域阈值内的对角像素即可,当对角像素内的像素点存在u (此处u与上面的连续点有所不同) 个不同的像素的时候。可以认为这个点与参考像素点不同。

计算特征描述子 (Feature DescritorS):

计算机是一个二进制机器,它读取的数据流或者是图像,只是一个data流或者是一个像素矩阵,它本身并没有任何特性,即使我们找到了像素的特征点坐
标,我们给它标记出来,可以通过肉眼直观的看到像素特征,但是计算机并不知道这些像素有什么意义,这个时候我们就需要构造一个特征描述子去描述当前像
素点的特征。

定义 O:参考特征点的圆形区域
d : 区域半径
N : 半径内点的个数
P(A,B):提取的点对的向量其中A, B为像素点A与像素点B的向量 具体来讲分为以下几步。

  1. 以关键点P为圆心,以d为半径做圆O。
  2. 在圆O内某一模式选取N个点对。(在OpenCV的FAST算法描述中,默认取512作为点对的个数)
  3. 定义一个函数T (P (A, B)) 使得当函数过程满足条件的时候取0, 时取1。其中为像素点的灰度值

通过上面的函数计算,就可以拿到列如101000101这样的特征描述子 但是实际上来讲,我们提取到的特征描述子仅仅是在同一坐标系中的描述子,当我们旋转这张图片以后呢,就会发现,上面的算法,会导致即是是同一个点,但是因为旋转了 图像而导致匹配失效。

在现实生活中,我们从不同的距离,不同的方向、角度,不同的光照条件下观察一个物体时,物体的大小,形状,明暗都会有所不同。但我们的大脑依然可以判断它是同一件物体。理想的特征描述子应该具备这些性质。即,在大小、方向、明暗不同的图像中,同一特征点应具有足够相似的描述子,称之为描述子的可复现性。

所有获取到的特征描述子应该必须要有:

对光照(亮度)不敏感,具备尺度一致性(大小 ),旋转一致性(角度)

在OpenCV的ORB实现中采用了图像金字塔来改善这方面的性能。ORB主要解决BRIEF描述子不具备旋转不变性的问题。当我们选取点对的时候,是以当前关键点为原点,以水平方向为X轴,以垂直方向为Y轴建立坐标系。当图片发生旋转时,坐标系不变,同样的取点模式取出来的点却不一样,计算得到的描述子也不一样,这样进行的匹配会出问题,因此需要建立一个新的坐标系去解决这个问题,来保证我们的一致性。

在OpenCV中通过构建高斯金字塔,然后在每一层金字塔图像上检测角点,来实现尺度不变性。那么,对于局部不变性,我们还差一个问题没有解决,就是FAST特征点不具有方向,ORB的论文中提出了一种利用灰度质心法来解决这个问题,灰度质心法假设角点的灰度与质心之间存在一个偏移,这个向量可以用于表示一个方向。对于任意一个特征点 来说,我们定义 的邻域像素的矩为:

图像的质心为:

至此,我们可以把特征点与质心的夹角定义为FAST特征点的方向:

给BRIEF加上旋转不变性,把这种方法称为“Steer BREIF”。对于任何一个特征点来说,它的BRIEF描述子是一个长度为 的二值码串,这个二值串是由特征点周围n个点对(2n个点)生成的,现在我们将这2n个点组成一个矩阵S

下面是OpenCV中的ORB实现函数

ORB::ORB(int nfeatures=500, float scaleFactor=1.2f, int nlevels=8, int edgeThreshold=31, int firstLevel=0, int WTA_K=2, int scoreType=ORB::HARRIS_SCORE, int patchSize=31)

nfeatures - 最多提取的特征点的数量
scaleFactor- 金字塔图像之间的尺度参数,类似于SIFT中的
nlevels– 高斯金字塔的层数;

edgeThreshold– 边缘阈值,这个值主要是根据后面的patchSize来定的,靠近边缘edgeThreshold以内的像素是不检测特征点的。

firstLevel - 看过SIFT都知道,我们可以指定第一层的索引值,这里默认为0。

WET_K - 用于产生BIREF描述子的 点对的个数,一般为2个,也可以设置为3个或4个,那么这时候描述子之间的距离计算就不能用汉明距离了,而是应该用一个变种。OpenCV中,如果设置WET_K = 2,则选用点对就只有2个点,匹配的时候距离参数选择NORM_HAMMING,如果WET_K设置为3或4,则BIREF描述子会选择3个或4个点,那么后面匹配的时候应该选择的距离参数为NORM_HAMMING2。

scoreType- 用于对特征点进行排序的算法,你可以选择HARRIS_SCORE,也可以选择FAST_SCORE,但是它也只是比前者快一点点而已。

patchSize– 用于计算BIREF描述子的特征点邻域大小。

#include <opencv2/core/core.hpp> 
#include <opencv2/highgui/highgui.hpp> 
#include <opencv2/imgproc/imgproc.hpp> 
#include <opencv2/features2d/features2d.hpp>

using namespace cv;

int main(int argc, char** argv) 
{ 
    Mat img_1 = imread("test.png"); 
    Mat img_2=imread("test2.png") ;

    // -- Step 1: 初始化ORB匹配点集
    std::vector<KeyPoint> keypoints_1,keypoints_2; 
    ORB orb; 
    orb.detect(img_1, keypoints_1); 
    orb.detect(img_2, keypoints_2);

    // -- Stpe 2: 计算特征描述子
    Mat descriptors_1, descriptors_2; 
    orb.compute(img_1, keypoints_1, descriptors_1); 
    orb.compute(img_2, keypoints_2, descriptors_2);

    //-- Step 3: 匹配相似的特征向量
    BFMatcher matcher(NORM_HAMMING); 
    std::vector<DMatch> mathces; 
    matcher.match(descriptors_1, descriptors_2, mathces); 

    // -- 绘制匹配线
    Mat img_mathes; 
    drawMatches(img_1, keypoints_1, img_2, keypoints_2, mathces, img_mathes); 

    // --显示图像
    imshow("Mathces", img_mathes);
    waitKey(0); 
    return 0; 
}

参考资料:

  1. An Efficient Alternative to SIFT or SURF
  2. 原文paper

© 著作权归作者所有

共有 人打赏支持
Pulsar-V
粉丝 43
博文 74
码字总数 58982
作品 1
成都
后端工程师
视觉SLAM的方案大全

MoNoSLAM 以扩展卡尔曼滤波为后端,追踪前端非常稀疏的特征点,以相机的当前状态和所有路标点为状态量,更新其均值和协方差。 优点:在2007年,随着计算机性能的提升,以及该系统用稀疏的方式...

问题终结者 ⋅ 01/30 ⋅ 0

图像处理之特征提取

知乎上看到一个话题—— 目前火热的 Deep Learning 会灭绝传统的 SIFT / SURF 特征提取方法吗? 由于之前研究过SIFT和HOG这两种传统的特征提取方法,故本篇文章先对SIFT和HOG作一综述,并比较...

牛奶芝麻 ⋅ 2017/11/27 ⋅ 0

opencv MSER(最大极值稳定区域)

最大极值稳定区域,是一种类似分水岭图像的分割与匹配算法。它具有SIFT SURF及 ORB等特征不具备的仿射不变性,近年来广泛应用于图像分割与匹配领域。 详细算法原理介绍可参见链接 http://blo...

moki_oschina ⋅ 2016/11/24 ⋅ 0

LSD SLAM和ORB SLAM的对比

现在开始找实习了,开始回顾研究生做的工作,把之前做的东西都总结一下,梳理梳理知识。 LSD SLAM的介绍: LSD SLAM是slam界大牛 Jakob Engel的著作,也是直接法的代表性工作。和LSD SLAM想对...

osgoodwu ⋅ 04/11 ⋅ 0

分享 | 带来全新交互体验的『支付宝AR』技术大解密

小蚂蚁说: AR是一种新颖的交互方式,与传统交互方式相比,可以让用户更深入地参与互动,给用户带来新体验。 而春节期间,支付宝的「扫福得福」活动也异常火爆,支付宝将AR与游戏、红包相结合...

兔子酱 ⋅ 04/26 ⋅ 0

漫谈 SLAM 技术(上)

欢迎大家前往腾讯云社区,获取更多腾讯海量技术实践干货哦~ 作者:解洪文 导语 随着最近几年机器人、无人机、无人驾驶、VR/AR的火爆,SLAM技术也为大家熟知,被认为是这些领域的关键技术之一...

腾讯云社区 ⋅ 2017/12/04 ⋅ 0

opencv3.0中与CUDA相关的头文件和库解释

目前,opencv中的cuda接口能够实现的算法还比较少,并不是很齐全,使用前需要先确定算法是否存在cuda接口 相对2.x的改动 * 不再使用cv::gpu的命名空间,改用cv::cuda * 头文件中需要单独引用...

sirius_0 ⋅ 04/08 ⋅ 0

ORB SLAM的tracking部分代码解析

    接着LSD SLAM的代码整理,现在把ORB SLAM的代码也梳理一遍。ORB SLAM是基于特征点法的SLAM的一个代表性的工作,并且有个可读性很强的开源代码[1],感兴趣的人可以下载下来跑一跑。 ...

osgoodwu ⋅ 04/24 ⋅ 0

机器学习算法选择——特征提取

第4步:特征工程 或许比选择算法更重要的是正确选择表示数据的特征。从上面的列表中选择合适的算法是相对简单直接的,然而特征工程却更像是一门艺术。 主要问题在于我们试图分类的数据在特征...

桃子红了呐 ⋅ 2017/11/09 ⋅ 0

基于特征检测(SURF,SIFT方法)与特征匹配(Feature Matching)(FLANN方法)

def detectcornerpoints(self, keyframe, good_matches): 结果图: 将书本大小缩小到dstsize大小的1/2,同时还要移动1/4的距离: 书中运行起来的效果如下: import numpy as npfrom matplot...

liangjiubujiu ⋅ 05/23 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

Python爬虫,抓取淘宝商品评论内容

作为一个资深吃货,网购各种零食是很频繁的,但是能否在浩瀚的商品库中找到合适的东西,就只能参考评论了!今天给大家分享用python做个抓取淘宝商品评论的小爬虫! 思路 我们就拿“德州扒鸡”...

python玩家 ⋅ 15分钟前 ⋅ 0

MySQL 内核深度优化

MYSQL数据库适用场景广泛,相较于Oracle、DB2性价比更高,Web网站、日志系统、数据仓库等场景都有MYSQL用武之地,但是也存在对于事务性支持不太好(MySQL 5.5版本开始默认引擎才是InnoDB事务...

java高级架构牛人 ⋅ 38分钟前 ⋅ 0

用户登录信息-钉子效果(基于jquery2.0)

本js效果使用jquery2.0,清晰的分解用户登录信息的(钉子效果),该效果直接用在作者网站(www.phpkhbd.com)上。 里面的难点有:定时器,延时。 大致效果如下: 一开始: 鼠标放上去的时候:...

宁哥实战课堂 ⋅ 39分钟前 ⋅ 0

解决yum安装报错Protected multilib versions

使用yum安装报错Protected multilib versions原因是因为多个库不能共存,不过更新的话也并不行,但是可以在安装命令后面加上如下一段命令: --setopt=protected_multilib=false 案例: 比如需...

北岩 ⋅ 50分钟前 ⋅ 0

为什么要学习Typescript???

简单来说 目前的typescript就是未来的javascript 为什么?? 这要从ECMA-262标准的第4版说起 对了 我们说的ES5 其实是ECMAScript3.1这个替代性建议被扶正了而已... 那么 第4版标准是什么? 看看...

hang1989 ⋅ 55分钟前 ⋅ 0

linux安装ipfs

一、下载ipfs # cd /usr/local/ipfs/ # wget https://dist.ipfs.io/go-ipfs/v0.4.15/go-ipfs_v0.4.15_linux-amd64.tar.gz # tar -zxvf go-ipfs_v0.4.15_linux-amd64.tar.gz 二、安装ipfs # ......

八戒八戒八戒 ⋅ 今天 ⋅ 0

jvm程序执行慢诊断手册

生产环境最多的几种事故之一就是程序执行慢,如果是web服务的话,表现就是响应时间长。本文分享,从业多年形成的排查守则。 诊断步骤 系统资源查看 首先是系统资源查看,而且必须是在第一步。...

xpbob ⋅ 今天 ⋅ 0

YII2 advanced 高级版本项目搭建-添加API应用以及多应用

一、YII安裝 安裝yii可以用composer安裝,也可以在yii中文社区下载归档文件安装 composer安装就不介绍了,因为要安装composer,比较麻烦,当然安装了composer是最好的,以后安装yii的插件要用...

botkenni ⋅ 今天 ⋅ 0

在jdk1.8的环境下模拟永久代内存溢出

相信不少小伙伴在看深入理解Java虚拟机的时候,作者给我们举例一个demo来发生PermGen space 1、通过List不断添加String.intern(); 2、通过设置对应的-XX:PermSize与-XX:MaxPermSize(更快看到...

虾几把写 ⋅ 今天 ⋅ 0

开发OpenDaylight组件的完整流程

在前面介绍学习了OpenDaylight的几个重要模块后,这里再来介绍下完整开发一个模块的过程。 OSGI的bundles提供被其他OSGI组件调用的服务。这个教程中展示的是Data Packet Service去解析数据包...

wangxuwei ⋅ 今天 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部