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. [ vue ] 自定义组件的 v-model 理解

    需求场景描述: 1. 在父组件 myself.vue 里面定义数据 button_val 2. 在父组件 myself.vue.里面定义按钮,它的功能是吧 button_val  的值 -1 ---- ...

  2. centos7 单用户模式修改root密码

    1. 在虚拟机重启客户机后.会出现下面进入界面.按e键 2.按了e键后,会出现下面的界面.此时按↓键.找到linux16 3.将光标移动到UTF-8后面,添加init=/bin/sh,并按 ctrl  ...

  3. fis学习

    http://fis.baidu.com/docs/beginning/getting-started.html#md5 还是喜欢时间戳?没问题,FIS也可以满足你的需求,点击这里

  4. Ubuntu下使用VS Code创建Spring Boot工程

    目的 我们将在Ubuntu桌面系统下,使用VS Code(Visual Studio Code)编辑器从零开始创建一个Spring Boot工程,并实现一个简单的RESTful风格接口.使用这套流程的 ...

  5. 关于cmake和开源项目发布的那些事(PF)

    本来是打算写一篇年终总结,随便和以往一样提一提自己的开源项目(长不大的plain framework)的一些进度,不过最近这一年对于这个项目实在是维护不多,实在难以用它作为醒目的标题.而最近由于使用了 ...

  6. 44.Prim算法

    public static void main(String[] args) { //测试看看图是否创建ok char[] data = new char[]{'A','B','C','D','E', ...

  7. java-异常-自定义异常异常类的抛出throws

    1 package p1.exception; 2 /* 3 * 对于角标是整数不存在,可以用角标越界表示, 4 * 对于负数为角标的情况,准备用负数角标异常来表示. 5 * 6 * 负数角标这种异常 ...

  8. 如何通俗地理解docker

    Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的 Linux 机器上,也可以实现虚拟化.容器是完全使用沙箱机制,相互之间不会有任何 ...

  9. py笔记第一篇

    #!/usr/bin/python #coding=utf-8 #@rename file #@2019/11/27 import os ls = os.rename('/root/tigergao. ...

  10. 计算机网络再次整理————tcp[二]

    前言 本文不会去介绍tcp的具体协议,因为这个tcp 应该不能说是单纯的连接和传输数据这么简单,里面还有很多机制. 正文 首先介绍一下什么是协议族(protocal Family),举个例子PF_IN ...