opencv笔记--ORB
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的更多相关文章
- OpenCV笔记大集锦(转载)
整理了我所了解的有关OpenCV的学习笔记.原理分析.使用例程等相关的博文.排序不分先后,随机整理的.如果有好的资源,也欢迎介绍和分享. 1:OpenCV学习笔记 作者:CSDN数量:55篇博文网址: ...
- opencv笔记6:角点检测
time:2015年10月09日 星期五 23时11分58秒 # opencv笔记6:角点检测 update:从角点检测,学习图像的特征,这是后续图像跟踪.图像匹配的基础. 角点检测是什么鬼?前面一篇 ...
- opencv笔记5:频域和空域的一点理解
time:2015年10月06日 星期二 12时14分51秒 # opencv笔记5:频域和空域的一点理解 空间域和频率域 傅立叶变换是f(t)乘以正弦项的展开,正弦项的频率由u(其实是miu)的值决 ...
- opencv笔记4:模板运算和常见滤波操作
time:2015年10月04日 星期日 00时00分27秒 # opencv笔记4:模板运算和常见滤波操作 这一篇主要是学习模板运算,了解各种模板运算的运算过程和分类,理论方面主要参考<图像工 ...
- opencv笔记3:trackbar简单使用
time:2015年 10月 03日 星期六 13:54:17 CST # opencv笔记3:trackbar简单使用 当需要测试某变量的一系列取值取值会产生什么结果时,适合用trackbar.看起 ...
- opencv笔记2:图像ROI
time:2015年 10月 03日 星期六 12:03:45 CST # opencv笔记2:图像ROI ROI ROI意思是Region Of Interests,感兴趣区域,是一个图中的一个子区 ...
- opencv笔记1:opencv的基本模块,以及环境搭建
opencv笔记1:opencv的基本模块,以及环境搭建 安装系统 使用fedora22-workstation-x86_64 安装opencv sudo dnf install opencv-dev ...
- OpenCV基本架构[OpenCV 笔记0]
最近正在系统学习OpenCV,将不定期发布笔记,主要按照毛星云的<OpenCV3编程入门>的顺序学习,会参考官方教程和文档.学习工具是Xcode+CMake,会对书中一部分内容更正,并加入 ...
- 查找并绘制轮廓[OpenCV 笔记XX]
好久没有更新了,原谅自己放了个假最近又在赶进度,所以...更新的内容是很靠后的第八章,因为最近工作要用就先跳了,后面会更新笔记编号...加油加油! 在二值图像中寻找轮廓 void cv::findCo ...
随机推荐
- 深入谈谈 Java IOC 和 DI
1.前言 不得不说, IOC和DI 在写代码时经常用到.还有个就是在面试时 ,面试官老喜欢问 IOC 和DI是什么的问题,都快被问吐了, 可是,仍然会让许多人说的支支吾吾. 为什么? 第一,因为这个知 ...
- 智能集成接口:I3 ISA-95 的应用
介绍 多年来,使用基于制造运营管理 (MOM) 的应用程序的制造 IT 顾问试图说服制造商这些类型的应用的高价值.实时 MOM 解决方案是唯一一组能够精确优化工厂日常运营的 IT 应用程序,可为其可用 ...
- JUC之线程池基础
线程池 定义和方法 线程池的工作时控制运行的线程数量,处理过程中将任务放入队列,然后在线程创建后启动这些任务,如果线程数量超过了最大数量,超出数量的线程排队等候,等待其他线程执行完成,再从队列中取出任 ...
- rocketmq实现延迟队列(精确到秒级)
最近项目里需要在延时队列,但是开源版本rocketmq不支持任意时间延时,造成有些任务无法执行 参考了网上的不少文章,但是都么有实现,所以再开源的基础上改造了个支持任意时间延时的队列. 源码地址: h ...
- 【pwn】DASCTF Sept 九月赛
[pwn]DASCTF Sept 月赛 1.hehepwn 先查看保护,栈可执行,想到shellcode 这题需要注意shellcode的写法 拖入ida中分析 一直以为iso scanf不能栈溢出, ...
- jQuery ajax get与post后台交互中的奥秘
这两天在做关注功能模块(类似于Instagram).多处页面都需要通过一个"关注"按钮进行关注或者取消该好友的操作.一个页面对应的放一个按钮,进行操作.效率低维护性差.因此想通过j ...
- 使用Hot Chocolate和.NET 6构建GraphQL应用(1)——GraphQL及示例项目介绍
系列导航 使用Hot Chocolate和.NET 6构建GraphQL应用文章索引 前言 这篇文章是这个系列的第一篇,我们会简单地讨论一下GraphQL,然后介绍一下这个系列将会使用的示例项目. 关 ...
- C# Reflection反射机制
一.反射 什么是反射 .Net的应用程序由几个部分:'程序集(Assembly)'.'模块(Module)'.'类型(class)'组成: 反射提供一种编程的方式,让程序员可以在程序运行期获得这几个组 ...
- [源码分析] Facebook如何训练超大模型 --- (3)
[源码分析] Facebook如何训练超大模型 --- (3) 目录 [源码分析] Facebook如何训练超大模型 --- (3) 0x00 摘要 0x01 ZeRO-Offload 1.1 设计原 ...
- 建造者模式(Bulider模式)
模式的定义与特点 建造者(Builder)模式的定义:指将一个复杂对象的构造与它的表示分离,使同样的构建过程可以创建不同的表示,这样的设计模式被称为建造者模式.它是将一个复杂的对象分解为多个简单的对象 ...