第十六节、基于ORB的特征检测和特征匹配
之前我们已经介绍了SIFT算法,以及SURF算法,但是由于计算速度较慢的原因。人们提出了使用ORB来替代SIFT和SURF。与前两者相比,ORB有更快的速度。ORB在2011年才首次发布。在前面小节中,我们已经提到了ORB算法。ORB算法将基于FAST关键点的技术和基于BRIEF描述符的技术相结合,关于FAST和BRIEF相关内容可以参考博客第十四节、FAST角点检测(附源码)和第十六节、特征描述符BRIEF(附源码)。
一 ORB算法原理
ORB算法将FAST特征点的检测方法和BRIEF特征描述子结合起来,并在它们的基础上做了改进与优化。
首先,它利用FAST特征点检测的方法来检测特征点,然后利用Harris角点的度量方法,从FAST特征点中挑选出Harris角点响应值最大的N个特征点。其中Harris角点的响应函数定义为:
$$R=detM-k(trace(M))^2$$
关于$M$的含义和响应函数可以参考第十一节、Harris角点检测原理(附源码)这篇博客。
1、旋转不变性
在现在生活中,我们从不同的距离,不同的方向、角度、不同的光照条件下观察一个物体时,物体的大小、形状,明暗都会有所不同。但是我们仍然可以判断它是一个物体。理想的特征描述子应该具备这些性质,即在大小、方向、明暗不同的图像中,同一特征点应具有足够相似的描述子,称之为描述子的可复现性。
但是ORB并没有解决尺度不一致的问题,在OpenCV的ORB实现中采用了图像金字塔来改善这方面的性能,我们通过构建高斯金字塔,然后在每一层金字塔图像上检测角点,来实现尺度不变性。ORB主要解决了BRIEF描述子不具备旋转不变性的问题,ORB论文种提出了一种利用灰度质心法来解决这个问题,灰度质心法假设角点的灰度与质心之间存在一个偏移,这个向量可以用于表示一个方向。对于任意一个特征点$p$来说,我们定义$p$的邻域像素的矩为:
$$m_{ij}=\sum\limits_{x=-r}^{r}\sum\limits_{y=-r}^{r}x^iy^jI(x,y)$$
其中$I(x,y)$为点$(x,y)$处的灰度值,$q$为质心,$i,j=0,1$。那么我们可以得到图像的质心为:
$$C=(\frac{m_{10}}{m_{00}},\frac{m_{01}}{m_{00}})$$
那么特征点与质心的夹角定义为FAST特征点的方向:
$$\theta=arctan(m_{01},m_{10})$$
为了提高算法的旋转不变性,需要确保$x$和$y$在半径为$r$的圆形区域内,即$x,y\in[-r,r]$,$r$等于邻域半径。
2、特征点的描述
ORB选择了BRIEF作为特征描述方法,但是我们知道BRIEF不具备旋转不变性,所以我们要给BRIEF加上旋转不变性,把这种方法称为"Steer BRIEF"。对于任何一个特征点来说,它的BRIEF描述子是一个长度为$n$的二值码串,这个二值码串是由特征点邻域$n$个点对生成的,我们现在讲这$2n$个点$(x_i,y_i),i=1,2,.....,2n$组成一个矩阵$S$:
$$S=\begin{bmatrix} x_1 & x_2 & ... &x_{2n} \\ y_1 & y_2 & ... & y_{2n} \end{bmatrix}$$
Calonder建议为每个块的旋转和投影集合分别计算BRIEF描述子,但代价昂贵。ORB中采用了一个更有效的方法:使用邻域方向$\theta$和对应的旋转矩阵$R_{\theta}$,构建$S$的一个校正版本$S_{\theta}$:
$$S_{\theta}=R_{\theta}S$$
其中:
$$R_{\theta}=\begin{bmatrix} cos\theta & sin\theta \\ -sin\theta & cos\theta \end{bmatrix}$$
而$\theta$即我们为特征点求得的主方向。
即我们把坐标轴旋转$]theta$,计算以主方向为坐标系的匹配点对,如下图:
实际上,我们可以把角度离散化,即把360度分为12份,每一份是30度,然后我们对这个12个角度分别求得一个$S_{\theta}$,这样我们就创建了一个查找表,对于每一个$\theta$,我们只需要查表即可快速得到它的点的集合$S_{\theta}$。
3、解决描述子的区分性
BRIEF令人惊喜的特性之一是:对于$n$维的二值串的每个特征位,所有特征点在该位上的值都满足一个均值接近于0.5,而方差很大的高斯分布。方差越大,说明区分性越强,那么不同特征点的描述子就表现出来越大差异性,对匹配来说不容易误配。但是当我们把BRIEF沿着特征点的方向调整为Steered BRIEF时,均值就漂移到一个更加分散式的模式。可以理解为有方向性的角点关键点对二值串则展现了一个更加均衡的表现。而且论文中提到经过PCA对各个特征向量进行分析,得知Steered BRIEF的方差很小,判别性小,各个成分之间相关性较大。
为了减少Steered BRIEF方差的亏损,并减少二进制码串之间的相关性,ORB使用了一种学习的方法来选择一个较小的点对集合。方法如下:
首先建立一个大约300k关键点的测试集,这些关键点来自于PASCAL2006集中的图像。
对于这300k个关键点中的每一个特征点,考虑它的$31\times{31}$的邻域,我们将在这个邻域内找一些点对,不同于BRIEF中要先对这个Patch内的点做平滑,再用以Patch中心为原点的高斯分布选择点对的方法。ORB为了去除某些噪声点的干扰,选择了一个$5\times{5}$大小的区域的平均灰度来代替原来一个单点的灰度,这里$5\times{5}$区域内图像平均灰度的计算可以用积分图的方法。我们知道$31\times{31}$的Patch里共有$N=(31-5+1)\times{(31-5+1)}$个这种窗口,那么我们要$N$个子窗口中选择2个子窗口的话,共有$C_N^2$种方法。所以对于300k中每一个特征点,我们都可以从它的$31\times{31}$大小的邻域中提取一个很长的二进制串,长度为$M=C_N^2$,表示为:
$$binArray = \begin{bmatrix} p_1 & p_2 & ... &p_M \end{bmatrix},p_i\in\{0,1\} $$
那么当300k个关键点全部进行上面的特征提取之后,我们就得到了一个$300k\times{M}$的矩阵,矩阵中的每个元素值为0或者1.
对该矩阵的每个列向量,也就是每个点对在300k个特征点上的测试结果,计算其均值。把所有的列向量按均值进行重新排序。排好后,组成了一个向量$T$,$T$的每一个元素都是一个列向量。
进行贪婪搜索,从$T$中把排在第一的那个列放到$R$中,$T$中就没有这个点对的测试结果了,然后把$T$中的排在下一个的列与$R$中的所有元素比较,计算它们的相关性,如果相关超过了某一事先设定好的阈值,就扔了它,否则就把它方到$R$里面。重复上面的步骤,直到$R$中有256个列向量位置。如果把$T$全部找完也没有找到256个,那么我们可以把相关的阈值调高一些,再尝试一遍。
这样,我们就得到了256个点对。上面这个过程我们称它为rBRIEF。
二 OpenCV实现
ORB中有很多参数可以设置,在OpenCV中它可以通过ORB来创建一个ORB检测器。
cv2.ORB_create([,nfeatues[,scaleFactor[,nlevels[,edgeThreshold[,firstLevel[,WTA_K[,[scoreType,[patchSize,fastThreshold]]]]]]]]])
参数说明:
- nfeatures :最多提取的特征点的数量;
- scaleFactor : 金字塔图像之间的尺度参数,类似于SIFT中的$k$;
- 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描述子的特征点邻域大小。
# -*- coding: utf-8 -*-
"""
Created on Mon Sep 10 22:37:36 2018 @author: zy
""" '''
ORB特征匹配
'''
import numpy as np
import cv2 def orb_test():
#加载图片 灰色
img1 = cv2.imread('./image/orb1.jpg')
gray1 = cv2.cvtColor(img1,cv2.COLOR_BGR2GRAY)
img2 = cv2.imread('./image/orb2.jpg')
img2 = cv2.resize(img2,dsize=(450,300))
gray2 = cv2.cvtColor(img2,cv2.COLOR_BGR2GRAY)
image1 = gray1.copy()
image2 = gray2.copy() '''
1.使用ORB算法检测特征点、描述符
'''
orb = cv2.ORB_create(128)
keypoints1,descriptors1 = orb.detectAndCompute(image1,None)
keypoints2,descriptors2 = orb.detectAndCompute(image2,None)
#在图像上绘制关键点
image1 = cv2.drawKeypoints(image=image1,keypoints = keypoints1,outImage=image1,color=(255,0,255),flags=cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS)
image2 = cv2.drawKeypoints(image=image2,keypoints = keypoints2,outImage=image2,color=(255,0,255),flags=cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS)
#显示图像
cv2.imshow('orb_keypoints1',image1)
cv2.imshow('orb_keypoints2',image2)
cv2.waitKey(20) '''
2、匹配
'''
matcher = cv2.BFMatcher_create(cv2.HAMMING_NORM_TYPE,crossCheck=True)
matchePoints = matcher.match(descriptors1,descriptors2)
print(type(matchePoints),len(matchePoints),matchePoints[0])
#按照距离从小到大排序,选取最优匹配的
sorted(matchePoints,key=lambda x:x.distance)
#绘制最优匹配点
outImg = None
outImg = cv2.drawMatches(img1,keypoints1,img2,keypoints2,matchePoints[:10],outImg,matchColor=(0,255,0),flags=cv2.DRAW_MATCHES_FLAGS_DEFAULT)
cv2.imshow('matche',outImg)
cv2.waitKey(0)
cv2.destroyAllWindows() cv2.waitKey(0)
cv2.destroyAllWindows() if __name__ == '__main__':
orb_test()
参考文章:
[1]Oriented FAST and Rotated BRIEF(部分转载自该文)
第十六节、基于ORB的特征检测和特征匹配的更多相关文章
- 第一百二十六节,JavaScript,XPath操作xml节点
第一百二十六节,JavaScript,XPath操作xml节点 学习要点: 1.IE中的XPath 2.W3C中的XPath 3.XPath跨浏览器兼容 XPath是一种节点查找手段,对比之前使用标准 ...
- 第四百一十六节,Tensorflow简介与安装
第四百一十六节,Tensorflow简介与安装 TensorFlow是什么 Tensorflow是一个Google开发的第二代机器学习系统,克服了第一代系统DistBelief仅能开发神经网络算法.难 ...
- ASP.NET MVC深入浅出系列(持续更新) ORM系列之Entity FrameWork详解(持续更新) 第十六节:语法总结(3)(C#6.0和C#7.0新语法) 第三节:深度剖析各类数据结构(Array、List、Queue、Stack)及线程安全问题和yeild关键字 各种通讯连接方式 设计模式篇 第十二节: 总结Quartz.Net几种部署模式(IIS、Exe、服务部署【借
ASP.NET MVC深入浅出系列(持续更新) 一. ASP.NET体系 从事.Net开发以来,最先接触的Web开发框架是Asp.Net WebForm,该框架高度封装,为了隐藏Http的无状态模 ...
- 风炫安全web安全学习第三十六节课-15种上传漏洞讲解(一)
风炫安全web安全学习第三十六节课 15种上传漏洞讲解(一) 文件上传漏洞 0x01 漏洞描述和原理 文件上传漏洞可以说是日常渗透测试用得最多的一个漏洞,因为用它获得服务器权限最快最直接.但是想真正把 ...
- 第三百八十六节,Django+Xadmin打造上线标准的在线教育平台—HTML母版继承
第三百八十六节,Django+Xadmin打造上线标准的在线教育平台—HTML母版继承 母板-子板-母板继承 母板继承就是访问的页面继承一个母板,将访问页面的内容引入到母板里指定的地方,组合成一个新页 ...
- 第三百七十六节,Django+Xadmin打造上线标准的在线教育平台—创建用户操作app,在models.py文件生成5张表,用户咨询表、课程评论表、用户收藏表、用户消息表、用户学习表
第三百七十六节,Django+Xadmin打造上线标准的在线教育平台—创建用户操作app,在models.py文件生成5张表,用户咨询表.课程评论表.用户收藏表.用户消息表.用户学习表 创建名称为ap ...
- 第三百六十六节,Python分布式爬虫打造搜索引擎Scrapy精讲—elasticsearch(搜索引擎)的bool组合查询
第三百六十六节,Python分布式爬虫打造搜索引擎Scrapy精讲—elasticsearch(搜索引擎)的bool组合查询 bool查询说明 filter:[],字段的过滤,不参与打分must:[] ...
- 第三百五十六节,Python分布式爬虫打造搜索引擎Scrapy精讲—scrapy分布式爬虫要点
第三百五十六节,Python分布式爬虫打造搜索引擎Scrapy精讲—scrapy分布式爬虫要点 1.分布式爬虫原理 2.分布式爬虫优点 3.分布式爬虫需要解决的问题
- 第三百四十六节,Python分布式爬虫打造搜索引擎Scrapy精讲—Requests请求和Response响应介绍
第三百四十六节,Python分布式爬虫打造搜索引擎Scrapy精讲—Requests请求和Response响应介绍 Requests请求 Requests请求就是我们在爬虫文件写的Requests() ...
随机推荐
- python学习笔记(11)--测验3: Python基础语法(下) (第7周)
斐波那契数列计算 B 描述 斐波那契数列如下: F(0) = 0, F(1) = 1 F(n) = F(n-1) + F(n-2) 编写一个计算斐波那契数列的函数,采用递归方式,输出不超过n的所有斐波 ...
- spring 注解 之 AOP基于@Aspect的AOP配置
Spring AOP面向切面编程,可以用来配置事务.做日志.权限验证.在用户请求时做一些处理等等.用@Aspect做一个切面,就可以直接实现. 1.首先定义一个切面类,加上@Component @A ...
- PLSQL 错误问题:Datebase character set (AL32UTF-8) and Client character set (ZHS16GBK) are different.
(解决不了,网上用的是Orecal,我用的只是客户端.) 网上找到解决方法 打开注册表(ctr+R,输入regedit),根据报错提示找到注册表位置,但本机是win10 64位系统,根据以上路径找不到 ...
- idea中Lombok的使用
使用了lombok的注解(@Setter,@Getter,@ToString,@@RequiredArgsConstructor,@EqualsAndHashCode或@Data)之后,就不需要编写或 ...
- Java多线程之通过标识关闭线程
package org.study2.javabase.ThreadsDemo.status; /** * @Auther:GongXingRui * @Date:2018/9/19 * @Descr ...
- Java使用RabbitMQ之订阅分发(Topic)
使用RabbitMQ进行消息发布和订阅,生产者将消息发送给转发器(exchange),转发器根据路由键匹配已绑定的消息队列并转发消息,主题模式支持路由键的通配. 生产者代码: package org. ...
- C#使用WebClient下载文件到本地目录
C#使用WebClient下载文件到本地目录. 1.配置本地目录路径 <appSettings> <!--文件下载目录--> <add key="Downloa ...
- 设置和安装 BizTalk Server 2016 的必备组件
设置服务器,然后安装和配置软件必备组件. 加入本地管理员组 若要安装并配置 BizTalk Server,在本地计算机上使用管理员帐户登录到服务器. 向本地管理员组添加任何管理 BizTa ...
- hibernate多对多映射文件的配置
user.hbm.xml <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE hibernate ...
- springMVC (优秀篇)
本文依然是复制的 Spring3 MVC结构简单,应了那句话简单就是美,而且他强大不失灵活,性能也很优秀. 官方的下载网址是:http://www.springsource.org/download ...