opencv 进阶16-基于FAST特征和BRIEF描述符的ORB(图像匹配)

news2024/11/25 22:31:49

在计算机视觉领域,从图像中提取和匹配特征的能力对于对象识别、图像拼接和相机定位等任务至关重要。实现这一目标的一种流行方法是
ORB(Oriented FAST and Rotated Brief)特征检测器和描述符。ORB 由 Ethan Rublee
等人开发,结合了两种现有技术的优势——FAST(加速分段测试特征)和Brief(二进制鲁棒独立基本特征)——为特征提取和匹配提供了强大而高效的解决方案。

在本文中,我们将深入研究 ORB 的内部工作原理,探讨它如何充当特征检测器和描述符、其关键组件以及与其他特征提取方法相比的优势。

  1. FAST特征检测器

加速分割测试的特征(Feature from Accelerated Segment
Test,FAST)算法是通过分析16个像素的圆形邻域来实现的。FAST算法把邻域内每个像素标记为比特定阈值更亮或更暗,该阈值是相对于圆心定义的。如果邻域包含若干标记为更亮或更暗的一系列连续像素,那么这个邻域就被视为角点。

FAST是一种角点检测算法,可以有效识别图像中的角点或关键点。通过利用简单的强度阈值方案和最小化计算,它的设计速度比传统的角点检测器更快。FAST 检查候选像素周围的一圈像素,如果有足够数量的连续像素比候选像素更亮或更暗,则将其分类为角点。

  1. BRIEF

另外,二值鲁棒独立基本特征(Binary Robust Independent Elementary
Feature,BRIEF)并非特征检测算法,而是一个描述符。我们来更深入地研究一下描述符的概念,然后再来研究BRIEF。

在前面用SIFT和SURF分析图像时,整个过程的核心是调用
detectAndCompute函数。此函数执行两个不同的步骤——检测和计算,它们返回2个不同的结果(耦合到一个元组中)。

检测结果是一组关键点,计算结果是这些关键点的一组描述符。这意味着OpenCV的cv2.SIFT和cv2.SURF类都实现了检测和描述算法。请记住,原始的SIFT和SURF不是特征检测算法。

OpenCV的cv2.SIFT实现了DoG特征检测和SIFT描述,而OpenCV的cv2.SURF实现了快速Hessian特征检测和SURF描述。
关键点描述符是图像的一种表示,充当特征匹配的通道,因为你
可以比较两幅图像的关键点描述符并发现它们的共性。BRIEF是目前最快的描述符之一。BRIEF背后的理论相当复杂,但是可以这样说,BRIEF采用一系列优化,使其成为特征匹配的一个非常好的选择。

蛮力匹配

蛮力匹配器是一个描述符匹配器,它比较两组关键点描述符并生成匹配列表。之所以称为蛮力匹配,是因为在该算法中几乎不涉及优化。对于第一个集合中的每个关键点描述符,匹配器将之与第二个集合中的每个关键点描述符进行比较。每次比较产生一个距离值,并基于最小距离选择最佳匹配。

概括地说,在计算中,“蛮力”一词是指将所有可能组合(例如,破解已知长度密码的所有可能的字符组合)的穷举按优先级排序的方法。相反,优先考虑速度的算法可能会跳过一些可能性,并试图走一条捷径来找到看似最合理的解决方案。

OpenCV提供了一个cv2.BFMatcher类,支持几种蛮力特征匹配的方法。

  1. ORB算法原理
    ORB算法将FAST特征点的检测方法和BRIEF特征描述子结合起来,并在它们的基础上做了改进与优化。

首先,它利用FAST特征点检测的方法来检测特征点,然后利用Harris角点的度量方法,从FAST特征点中挑选出Harris角点响应值最大的N个特征点。其中Harris角点的响应函数定义为:

R=detM−k(trace(M))2

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

但是ORB并没有解决尺度不一致的问题,在OpenCV的ORB实现中采用了图像金字塔来改善这方面的性能,我们通过构建高斯金字塔,然后在每一层金字塔图像上检测角点,来实现尺度不变性。ORB主要解决了BRIEF描述子不具备旋转不变性的问题,ORB论文种提出了一种利用灰度质心法来解决这个问题,灰度质心法假设角点的灰度与质心之间存在一个偏移,这个向量可以用于表示一个方向。对于任意一个特征点p来说,我们定义p的邻域像素的矩为:

在这里插入图片描述

其中I(x,y)为点(x,y)处的灰度值,q 为质心,i,j=0,1。那么我们可以得到图像的质心为:

在这里插入图片描述

那么特征点与质心的夹角定义为FAST特征点的方向:

在这里插入图片描述
为了提高算法的旋转不变性,需要确保 x 和 y 在半径为r 的圆形区域内,即x,y∈[−r,r],r 等于邻域半径。

特征点的描述

ORB选择了BRIEF作为特征描述方法,但是我们知道BRIEF不具备旋转不变性,所以我们要给BRIEF加上旋转不变性,把这种方法称为"Steer BRIEF"。 对于任何一个特征点来说,它的BRIEF描述子是一个长度为n的二值码串,这个二值码串是由特征点邻域n个点对生成的,我们现在讲这2n个点(xi,yi),i=1,2,…,2n组成一个矩阵S:

在这里插入图片描述
Calonder建议为每个块的旋转和投影集合分别计算BRIEF描述子,但代价昂贵。ORB中采用了一个更有效的方法:使用邻域方向θ和对应的转矩阵Rθ,构建S 的一个校正版本Sθ:

在这里插入图片描述
其中:

在这里插入图片描述
而θ 即我们为特征点求得的主方向。

即我们把坐标轴旋转]theta,计算以主方向为坐标系的匹配点对,如下图:

在这里插入图片描述
实际上,我们可以把角度离散化,即把360度分为12份,每一份是30度,然后我们对这个12个角度分别求得一个Sθ,这样我们就创建了一个查找表,对于每一个θ,我们只需要查表即可快速得到它的点的集合Sθ。

解决描述子的区分性

BRIEF令人惊喜的特性之一是:对于n维的二值串的每个特征位,所有特征点在该位上的值都满足一个均值接近于0.5,而方差很大的高斯分布。方差越大,说明区分性越强,那么不同特征点的描述子就表现出来越大差异性,对匹配来说不容易误配。但是当我们把BRIEF沿着特征点的方向调整为Steered BRIEF时,均值就漂移到一个更加分散式的模式。可以理解为有方向性的角点关键点对二值串则展现了一个更加均衡的表现。而且论文中提到经过PCA对各个特征向量进行分析,得知Steered BRIEF的方差很小,判别性小,各个成分之间相关性较大。

为了减少Steered BRIEF方差的亏损,并减少二进制码串之间的相关性,ORB使用了一种学习的方法来选择一个较小的点对集合。方法如下:

首先建立一个大约300k关键点的测试集,这些关键点来自于PASCAL2006集中的图像。

对于这300k个关键点中的每一个特征点,考虑它的31×31的邻域,我们将在这个邻域内找一些点对,不同于BRIEF中要先对这个Patch内的点做平滑,再用以Patch中心为原点的高斯分布选择点对的方法。

ORB为了去除某些噪声点的干扰,选择了一个5×5大小的区域的平均灰度来代替原来一个单点的灰度,这里5×5区域内图像平均灰度的计算可以用积分图的方法。我们知道31×31的Patch里共有N=(31−5+1)×(31−5+1)个这种窗口,那么我们要N个子窗口中选择2个子窗口的话,共有C2N种方法。所以对于300k中每一个特征点,我们都可以从它的31×31大小的邻域中提取一个很长的二进制串,长度为M=C2N,表示为:

在这里插入图片描述
那么当300k个关键点全部进行上面的特征提取之后,我们就得到了一个300k×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描述子的特征点邻域大小。

示例:使用ORB描述符进行Brute-Force匹配:

示例代码:


import cv2

def orb_test():
    # 加载图片  灰色
    img1 = cv2.imread('images\\quexiao\\2.png')
    gray1 = cv2.cvtColor(img1, cv2.COLOR_BGR2GRAY)
    img2 = cv2.imread('images\\quexiao\\2-1.png')

    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、匹配
    '''
    # 使用汉明距离,创建BF匹配器,并进行匹配() 新版本不支持
   # matcher = cv2.BFMatcher_create(cv2.HAMMING_NORM_TYPE, crossCheck=True)
    matcher = cv2.BFMatcher_create(cv2.NORM_HAMMING, 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()

在这里插入图片描述

实验原图:
2.png
请添加图片描述

2-1.png
请添加图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/912628.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

工作7年的测试员,明白了如何正确的“卷“

背景 近两年,出台和落地的反垄断法,明确指出要防止资本无序扩张。 这也就导致现在的各大互联网公司,不能再去染指其他已有的传统行业,只能专注自己目前存量的这些业务。或者通过技术创新,开辟出新的行业。 但创新这种…

vmware 虚拟机开机自启动脚本

1、建立一个txt文件 D:\VMware\VMware Workstation\vmrun.exe -T ws start "I:\Documents\Virtual Machines\centos\centos.vmx" nogui 注意:如果路径中有中文需要先转换txt文件编码格式ANSI 2、设置bat开机自启动 winr shell:startup 复制文本文件到…

【uniapp】微信小程序 , 海报轮播图弹窗,点击海报保存到本地,长按海报图片分享,收藏或保存

uivew 2.0 uniapp 海报画板 DCloud 插件市场 第一步&#xff0c;下载插件并导入HbuilderX 第二步&#xff0c;文件内 引入 海报组件 <template><painter ref"haibaorefs"></painter> <template> <script>import painter from /comp…

Docker关于下载,镜像配置,容器启动,停止,查看等基础操作

系列文章目录 文章目录 系列文章目录前言一、安装Docker并配置镜像加速器二、下载系统镜像&#xff08;Ubuntu、 centos&#xff09;三、基于下载的镜像创建两个容器 &#xff08;容器名一个为自己名字全拼&#xff0c;一个为首名字字母&#xff09;四、容器的启动、 停止及重启…

汽车检测报告小程序开发制作方案

传统的车辆检测流程通常繁琐且耗时&#xff0c;用户对更快速、便捷的检测方式有了更高的期望。基于这一需求&#xff0c;开发一款汽车检测报告小程序将成为现实生活中的实用工具。 产品定位为一款提供汽车检测报告查询的小程序&#xff0c;主要服务于需要进行汽车检测的车主、…

【Leetcode】移动零

移动零 题目描述算法描述编程代码 链接: 移动零 题目描述 算法描述 编程代码 class Solution { public:void moveZeroes(vector<int>& nums) {//题目要求不可以复制数组&#xff0c;开辟额外空间int dest -1,curr 0;for(;curr < nums.size();curr){if(nums[cu…

正中优配:股票增发对散户有补偿吗?

股票增发指的是公司发行新的股票&#xff0c;从而添加公司的股本。这通常是为了筹集资金&#xff0c;以用于公司的扩张或其他出资。可是&#xff0c;这种操刁难散户出资者的影响往往被疏忽或被低估。本文将从多个角度剖析股票增发对散户出资者的影响&#xff0c;包含股票价格、…

荣耀重返印度市场,代工订单闻泰承接 | 百能云芯

荣耀宣布将重新进军印度市场&#xff0c;最新的消息显示&#xff0c;荣耀已与闻泰科技达成协议&#xff0c;委托其承接印度手机市场的制造订单。此举旨在通过在闻泰科技的印度工厂进行组装&#xff0c;降低关税&#xff0c;从而提升荣耀产品在印度市场的竞争力。 作为备受瞩目的…

分库分表之拆分键设计 | 京东物流技术团队

众所周知&#xff0c;在现实世界中&#xff0c;每一个资源都有其提供能力的最大上限&#xff0c;当单一资源达到最大上限后就得让多个资源同时提供其能力来满足使用方的需求。同理&#xff0c;在计算机世界中&#xff0c;单一数据库资源不能满足使用需求时&#xff0c;我们也会…

Andorid广播

以下内容摘自郭霖《第一行代码》第三版 文章目录 一、广播机制简介1.1 广播的类型1.1.1 标准广播1.1.2 有序广播 二、接收系统广播2.1 动态注册监听时间变化2.2 静态注册实现开机启动 三、发送自定义广播3.1 发送标准广播3.2 发送有序广播 一、广播机制简介 1.1 广播的类型 A…

EPS倾斜摄影模型测图

1、打开EPS软件&#xff0c;新建工程。 2、加载倾斜摄影模型。在三维测图--倾斜摄影--加载本地倾斜模型中&#xff0c;加载模型到工作空间。 3、加载后的结果如下&#xff1a; 4、开始绘制房屋。选择编码--进入加线模式--开始绘图。 开始绘图图形&#xff0c; 5、绘图按键使用 …

面试题大揭秘!Java中== 与equals的区别?

大家好&#xff0c;我是你们的小米&#xff01;今天我们要来聊一个在Java面试中经常被问到的问题&#xff1a; 与 equals 的区别。这可是一个重要而且常常令人头疼的问题哦&#xff01;废话不多说&#xff0c;咱们马上开启今天的探索之旅吧&#xff01; 背景知识 在开始深入探…

什么是雨量气象站?

过多的强降水会造成重大自然灾害&#xff0c;给我们的生活带来很大影响&#xff0c;实时监测降雨信息&#xff0c;能够及时发布气象预警&#xff0c;防范可能因强降水引起的山洪、泥石流等自然灾害&#xff0c;保护人民群众生命财产安全&#xff0c;提高防灾减灾能力。 雨量气…

【三维重建】【深度学习】NeuS代码Pytorch实现--测试阶段代码解析(下)

【三维重建】【深度学习】NeuS代码Pytorch实现–测试阶段代码解析(下) 论文提出了一种新颖的神经表面重建方法&#xff0c;称为NeuS&#xff0c;用于从2D图像输入以高保真度重建对象和场景。在NeuS中建议将曲面表示为有符号距离函数(SDF)的零级集&#xff0c;并开发一种新的体绘…

springboot+vue实现的智慧学校云平台源码

智慧校园源码 智慧班牌云平台源码 系统架构&#xff1a;Javavue2springbootMySQL elmentuiQuartzjpajwt 智慧校园电子班牌云平台是出于校园考勤管理以及班级校园信息展示为目的的管理系统&#xff0c;电子班牌系统主要用于中小学教育的综合管理平台&#xff0c;融合了多媒体技…

SPSS中级统计--卡方独立性检验之n×c表资料

nc资料表检验 nc资料表分类&#xff1a; ①双向无序的RC表资料 ②单向有序的RC表资料 ③双向有序的RC表资料 1、双向无序RC表资料 多个样本率的比较&#xff08;c2&#xff09; 例1&#xff1a;比较不同污染地区的动物畸形率是否有差异&#xff1f; H0&#xff1a;不同污染…

Android中使用JT808协议进行车载终端通信的实现和优化

JT808是一种在中国广泛应用的车载终端通信协议&#xff0c;用于车辆与监控中心之间的数据通信。下面是关于Android平台上使用JT808协议进行通信的一般步骤和注意事项&#xff1a; 协议了解&#xff1a;首先&#xff0c;您需要详细了解JT808协议的规范和定义。该协议包含了通信消…

iServer通过服务实例动态化管理MongoDB万级瓦片集应用实践

作者&#xff1a;Carlo 文章目录 数据特点项目难点优化方案先了解“服务实例动态化管理”功能特性“服务实例动态化管理”应用场景优化1&#xff1a;开启服务实例动态化管理优化2&#xff1a;同时设置一个特定服务关闭动态管理持续存活优化3&#xff1a;将服务配置信息存储到Po…

React(8)

千锋学习视频https://www.bilibili.com/video/BV1dP4y1c7qd?p72&spm_id_frompageDriver&vd_sourcef07a5c4baae42e64ab4bebdd9f3cd1b3 1.React 路由 1.1 什么是路由&#xff1f; 路由是根据不同的 url 地址展示不同的内容或页面。 一个针对React而设计的路由解决方案…

python从入门到精通——完整教程

阅读全文点击《python从入门到精通——完整教程》 一、编程入门与进阶提高 Python编程入门 1、Python环境搭建&#xff08; 下载、安装与版本选择&#xff09;。 2、如何选择Python编辑器&#xff1f;&#xff08;IDLE、Notepad、PyCharm、Jupyter…&#xff09; 3、Pytho…