ORB detector 使用 FAST detector 和 BRIEF descriptor 基本思路。在介绍 ORB 之前,首先对 FAST 与 BRIEF 进行说明。

1 FAST

FAST(Featrues from Accelerated Segment Test),其基本思想是比较当前点与周边点差异,当周边有连续不少于一半的点均比中间点亮或者暗,则认为该点为一个特征点。其中,亮或暗的定义为:

1)当  时,周边点比中间点亮;

2)当  时,周边点比中间点暗;

3)当  时,周边点与中间点相似;

使用以上定义,可以迅速找到图像中候选特征点。

由于需要满足不少于一半的连续周边点亮于或暗于中间点,可以首先检测水平与垂直方向上四个点,当少于两个连续点满足条件,则该点一定不是候选特征点。如此可以提升计算效率。

当完成候选特征点扫描后,会发现存在许多临近特征点,可以使用如下评分进行非极大值抑制:

以上即为 FAST 的基本思想,opencv 实现在 cv::FastFeatureDetector 中,参数 threshold 定义了亮或暗,nonmaxSuppression 确定是否排除临近点。

2 BRIEF

BRIEF 对特征点生成描述特征向量。在 SIFT 与 SURF 中均使用了块特征描述方案,使用不同小块的方向梯度直方图构成特征向量。BRIEF 使用点特征描述特征点,基本思想为:

1)在特征点区域内随机生成 N 个点对,这N个点对生成方式有很多种,但一旦生成,对于所有特征点描述均使用相同的点对模式;

2)由于需要对孤立点进行比较,所以首先平滑图像以抑制噪声;

3)构造 N 位向量,第 k 个点对生成第 k 位向量,当点对中前一个点大于后一个点,其值为  1,反之为 0;

opencv 实现在 cv::BriefDescriptorExtractor 中,参数 bytes 确定特征点描述向量长度为 bytes * 8。

结合 FAST 与 BRIEF,可以实现类似 SIFT 与 SURF 的功能,以下给出简单使用代码:

 1 cv::FastFeatureDetector detector(20);
2 std::vector<cv::KeyPoint> keypoints1, keypoints2;
3 detector.detect(img1, keypoints1);
4 detector.detect(img2, keypoints2);
5
6 cv::BriefDescriptorExtractor brief;
7 cv::Mat descriptors1, descriptors2;
8 brief.compute(img1, keypoints1, descriptors1);
9 brief.compute(img2, keypoints2, descriptors2);
10
11 // 不同于SIFT与SURF,这里使用汉明距离
12 cv::BFMatcher matcher(cv::NORM_HAMMING);
13 std::vector<DMatch> matches;
14 matcher.match(descriptors1, descriptors2, matches);

其匹配结果如下:

3 ORB

ORB 主要思想如下:

1)使用 FAST 提取候选特征点;

2)为了克服 FAST 可能产生的边缘响应,使用 Harris corner measure 保留角点响应,剔除边缘响应(边缘响应不利于匹配);

3)按以上方法在不同层级图像金字塔上搜索候选特征点;

4)使用归一化图像描述特征点方向 

5)使用特征点方向生成 BRIEF 特征点描述向量;

6)使用汉明距离计算特征点之间相似度;

opencv 提供  cv::ORB 实现特征点提取与描述,其构造函数参数如下:

nfeatures 表示需要提取的特征点数量;

scaleFactor,nlevels  为图像金字塔参数;

firstLevel 表示从第几层开始搜索特征点,一般为 0;

patchSize 确定特征点尺寸,edgeThreshold 应不小于 patchSize,该参数忽略边界特征点;

scoreType 确定使用 FAST 评分机制或者 Harris corner 评分机制;

WTA_K 控制比较点个数,当为 2 时,即为 FAST 对点对比较方式;

以下给出简单使用代码:

 1 cv::Mat img1 = cv::imread("a.bmp", cv::IMREAD_GRAYSCALE);
2 cv::Mat img2 = cv::imread("b.bmp", cv::IMREAD_GRAYSCALE);
3
4 std::vector<cv::KeyPoint> keypoints1, keypoints2;
5 cv::Mat descriptors1, descriptors2;
6
7 cv::ORB orb(100, 1.5, 4);
8 orb.operator()(img1, cv::noArray(), keypoints1, descriptors1);
9 orb.operator()(img2, cv::noArray(), keypoints2, descriptors2);
10
11 cv::BFMatcher matcher(cv::NORM_HAMMING);
12 std::vector<DMatch> matches;
13 matcher.match(descriptors1, descriptors2, matches);
14
15 cv::Mat img_matches;
16 cv::drawMatches(img1, keypoints1, img2, keypoints2, matches, img_matches);
17 cv::imwrite("c.jpg", img_matches);
18
19 double min_dist = 100;
20
21 for (int i = 0; i < matches.size(); i++)
22 {
23 double dist = matches[i].distance;
24 if (dist < min_dist) min_dist = dist;
25
26 }
27
28 // Draw only "good" matches (i.e. whose distance is less than 2*min_dist,
29 // or a small arbitary value ( 0.02 )
30 std::vector< DMatch > good_matches;
31
32 for (int i = 0; i < matches.size(); i++)
33 {
34 if (matches[i].distance <= max(2 * min_dist, 0.02))
35 {
36 good_matches.push_back(matches[i]);
37 }
38 }
39
40 cv::drawMatches(img1, keypoints1, img2, keypoints2, good_matches, img_matches);
41 cv::imwrite("d.jpg", img_matches)

其匹配结果如下:

参考资料 Learning OpenCV 3   Adrian Kaehler & Gary Bradski

opencv笔记--ORB的更多相关文章

  1. OpenCV笔记大集锦(转载)

    整理了我所了解的有关OpenCV的学习笔记.原理分析.使用例程等相关的博文.排序不分先后,随机整理的.如果有好的资源,也欢迎介绍和分享. 1:OpenCV学习笔记 作者:CSDN数量:55篇博文网址: ...

  2. opencv笔记6:角点检测

    time:2015年10月09日 星期五 23时11分58秒 # opencv笔记6:角点检测 update:从角点检测,学习图像的特征,这是后续图像跟踪.图像匹配的基础. 角点检测是什么鬼?前面一篇 ...

  3. opencv笔记5:频域和空域的一点理解

    time:2015年10月06日 星期二 12时14分51秒 # opencv笔记5:频域和空域的一点理解 空间域和频率域 傅立叶变换是f(t)乘以正弦项的展开,正弦项的频率由u(其实是miu)的值决 ...

  4. opencv笔记4:模板运算和常见滤波操作

    time:2015年10月04日 星期日 00时00分27秒 # opencv笔记4:模板运算和常见滤波操作 这一篇主要是学习模板运算,了解各种模板运算的运算过程和分类,理论方面主要参考<图像工 ...

  5. opencv笔记3:trackbar简单使用

    time:2015年 10月 03日 星期六 13:54:17 CST # opencv笔记3:trackbar简单使用 当需要测试某变量的一系列取值取值会产生什么结果时,适合用trackbar.看起 ...

  6. opencv笔记2:图像ROI

    time:2015年 10月 03日 星期六 12:03:45 CST # opencv笔记2:图像ROI ROI ROI意思是Region Of Interests,感兴趣区域,是一个图中的一个子区 ...

  7. opencv笔记1:opencv的基本模块,以及环境搭建

    opencv笔记1:opencv的基本模块,以及环境搭建 安装系统 使用fedora22-workstation-x86_64 安装opencv sudo dnf install opencv-dev ...

  8. OpenCV基本架构[OpenCV 笔记0]

    最近正在系统学习OpenCV,将不定期发布笔记,主要按照毛星云的<OpenCV3编程入门>的顺序学习,会参考官方教程和文档.学习工具是Xcode+CMake,会对书中一部分内容更正,并加入 ...

  9. 查找并绘制轮廓[OpenCV 笔记XX]

    好久没有更新了,原谅自己放了个假最近又在赶进度,所以...更新的内容是很靠后的第八章,因为最近工作要用就先跳了,后面会更新笔记编号...加油加油! 在二值图像中寻找轮廓 void cv::findCo ...

随机推荐

  1. CentOS7 常用命令汇总

    原文链接:https://blog.csdn.net/weixin_42208959/article/details/107970958 目录常用命令1.进程相关命令1.1 查询进程和结束进程1.2 ...

  2. RabbitMQ 消息中间件 的下载与安装【window10】

    1.前言 弄了好久,才终于把 rabbitmq装好 ,本来是很简单的,但是,安装有个要求就是路径不能有中文字符, 虽然可以安装,但是无法运行,需要修改路径名为非中文字符后重装rabbitmq才可以运行 ...

  3. react中prop-types的使用

    什么是prop-types?prop代表父组件传递过来的值,types代表类型.简单来说就是用来校验父组件传递过来值的类型 import PropTypes from 'prop-types'; To ...

  4. 第10组 Alpha冲刺 总结(组长)

    1.基本情况 组长博客链接:https://www.cnblogs.com/cpandbb/p/14007413.html 答辩总结: ·产品偏离了最开始的方向,地图和刷一刷功能做得没那么好,外卖订单 ...

  5. SQL高级优化(六)之MySQL索引

    一.索引概述 1. 索引的优点 ​ 为什么要创建索引?这是因为,创建索引可以大大提高系统的查询性能.如果不使用索引,查询时从第一行开始查询.如果使用了索引,所以就可以更加快速的找到希望的数据. 第一. ...

  6. golang gin框架中使用protocol buffers和JSON两种协议

    首先,我使用protobuf作为IDL,然后提供HTTP POST + JSON BODY的方式来发送请求. 能不能使用HTTTP POST + PB序列化后的二进制BODY呢? 做了一下尝试,非常简 ...

  7. 1.IO流

    1.组成部分 File.FileInputStream.FileOutStream.FileWriter.FileReader 2.File pathSeparatorChar ; separator ...

  8. golang中结构体标签在json中的应用

    package main import ( "encoding/json" "fmt" "reflect" ) type Movie str ...

  9. IDEA设置Maven

    1,在idea中设置maven,让idea和maven结合使用 idea中内置了maven,一般不使用内置,因为用内置修改maven的设置不方便 使用自己安装的maven,需要覆盖idea中默认的设置 ...

  10. Python定制化天气预报消息推送

    sansui-Weather 代码码云 介绍 定制化天气预报消息推送(练手小脚本) Python脚本实现天气查询应用,提醒她注意保暖! 功能介绍 天气信息获取 当天天气信息提示 第二天天气信息提示 网 ...