【OpenCV 例程 300篇】246. 特征检测之ORB算法

news2024/11/28 22:47:05

『youcans 的 OpenCV 例程300篇 - 总目录』


【youcans 的 OpenCV 例程 300篇】246. 特征检测之ORB算法


特征检测与匹配是计算机视觉的基本任务,包括检测、描述和匹配三个相互关联的步骤。广泛应用于目标检测、图像检索、视频跟踪和三维重建等诸多领域。


6.9.1 ORB 算法简介

ORB(Oriented FAST and rotated BRIEF) 是 OpenCV 实验室开发的一种特征检测与特征描述算法,将 FAST 特征检测与 BRIEF 特征描述结合并进行了改进,具有尺度不变性和旋转不变性,对噪声有较强的抗干扰能力。

ORB算法在图像金字塔中使用FAST算法检测关键点,通过一阶矩计算关键点的方向,使用方向校正的BRIEF生成特征描述符。

FAST(Features From Accelerated Segment Test)是一种关键点检测算法,用于特征提取但不涉及特征描述。FAST 算法通过与圆周像素的比较结果判别特征点,计算速度快、可重复性高,非常适合实时视频的处理。

BRIEF (Binary Robust Independent Elementary Features)是一种二进制特征描述符,直接生成二进制字符串作为关键点的特征描述符,加快了建立特征描述符的速度,降低了特征描述符的内存占用,极大地提高了特征匹配的效率,是一种快速高效的特征描述方法,对光照、模糊和透视变换具有较强的鲁棒性。

基本的FAST和BRIEF算法并不具有尺度不变性和旋转不变性,ORB算法的主要贡献是:
(1)对 FAST 算法提取的特征点,使用一阶矩计算特征点方向,实现旋转不变性;
(2)高效计算带方向的 BRIEF 特征点描述符;
(3)降低 BRIEF 特征描述符点对的相关性,在最近邻匹配中具有更好的性能。

参考文献:Ethan Rublee, Vincent Rabaud, Kurt Konolige, and Gary Bradski. Orb: an efficient alternative to sift or surf. In Computer Vision (ICCV), 2011 IEEE International Conference on, pages 2564–2571. IEEE, 2011.

ORB论文中没有解决尺度不变性,但在OpenCV算法中通过图像金字塔实现了尺度不变性。


ORB的主要步骤如下:

(1)尺度空间关键点检测

通过下采样构造图像金字塔,每层只有一张图像,第s层的尺度为: σ s = σ 0 s \sigma_s=\sigma_0^s σs=σ0s,第s层的图像尺寸为: S i z e = ( H / σ s , W / σ s ) Size=(H/\sigma_s, W/\sigma_s) Size=(H/σs,W/σs)
在图像金字塔的每层图像中使用 FAST 检测关键点,然后使用Harris角点响应函数或FAST算法选择响应最强的N个点。通过检测每个尺度的关键点,使算法具有一定的尺度特征。

(2)确定关键点的方向

SIFT的定向算法计算量很大,而SURF的定向算法精度较差。ORB使用质心法对关键点确定唯一的主方向。
在以关键点为中心、尺度半径的邻域中,使用强度质心法(一阶矩)计算关键点的方向:
( C x , C y ) = ( m 10 / m 00 , m 01 / m 00 ) θ = a r c t a n ( m 01 , m 10 ) (C_x, C_y) = (m_{10}/m_{00}, m_{01}/m_{00}) \\ \theta = arctan(m_{01}, m_{10}) (Cx,Cy)=(m10/m00,m01/m00)θ=arctan(m01,m10)
通过确定每个关键点的方向, 以实现旋转不变性。

(3)使用rBRIEF(Rotation-Aware BRIEF )生成特征描述符。

BRIEF描述符对于方向变化非常敏感, 存在10度以上旋转时匹配性能很差。
ORB 将角度离散化为2π/30(12度),并构建了BRIEF模式的查找表。rBRIEF根据关键点方向来引导 BRIEF,按关键点的方向将采样窗口旋转角度 θ \theta θ后再构造特征区域,生成 rBRIEF 特征描述符,因此具有旋转不变性。

(4)rBRIEF 特征描述符的方差

BRIEF描述符的每个关键点对都具有很大的方差(均值接近于0.5),相关性较小,便于增强匹配性能。
但 rBRIEF 会减小特征点对的方差,相关性增大,可识别性降低。
为了恢复 rBRIEF 损失的方差,ORB在所有可能的二进制测试中进行贪婪搜索,以找到具有高方差和相关性弱的二进制点对。

ORB的优点是速度非常快,性能比较好,具有旋转不变性和一定的尺度不变性。由于没有专利限制可以免费使用,ORB 算法应用广泛,经常被用来代替 SIFT、SURF 算法。

计算速度: ORB>>SURF>>SIFT(各差一个量级)
旋转鲁棒性:SURF>ORB~SIFT(~表示差不多)
模糊鲁棒性:SURF>ORB~SIFT
尺度鲁棒性:SURF>SIFT>ORB(ORB的尺度变换性很弱)


6.9.2 OpenCV 中的 ORB 类

OpenCV 提供了丰富的特征检测算法,而且继承了 cv::Feature2D 类,采用了统一的定义和封装。

OpenCV 中提供 cv::ORB 类实现 ORB 算法,ORB 类继承了cv::Feature2D类,通过create静态方法创建。

ORB 类的构造函数为:

static Ptr<ORB> create(int nfeatures=500,float scaleFactor = 1.2f,int nlevels = 8,int edgeThreshold = 31,int firstLevel = 0,int WTA_K = 2,ORB::ScoreType scoreType = ORB::HARRIS_SCORE,int patchSize = 31,int fastThreshold = 20)

ORB 类继承 cv::Feature2D父类,在Python语言中通过接口函数cv.ORB_create或cv.ORB.create实例化ORB类,创建ORB对象。通过成员函数orb.detect检测关键点,函数orb.compute计算关键点描述符,函数orb.detectAndCompute检测关键点并生成描述符。

cv.ORB.create([, nfeatures=500, scaleFactor=1.2f, nlevels=8, edgeThreshold=31, firstLevel=0, WTA_K=2, scoreType=ORB::HARRIS_SCORE, patchSize=31, fastThreshold=20]) → retval
cv.ORB_create([, nfeatures=500, scaleFactor=1.2f, nlevels=8, edgeThreshold=31, firstLevel=0, WTA_K=2, scoreType=ORB::HARRIS_SCORE, patchSize=31, fastThreshold=20]) → retval
orb.detect(image[, mask]) → keypoints
orb.compute(image, keypoints[, descriptors=None]) → keypoints, descriptors
orb.detectAndCompute(image, mask[, descriptors[, useProvidedKeypoints]]) → keypoints, descriptors

参数说明:

  • nfeatures:关键点的最大数量,默认值为500。
  • scaleFactor:图像金字塔的缩放比,大于1的浮点数,默认值为1.2。
  • nlevels :图像金字塔的层数,默认值为8。
  • edgeThreshold:边界保留尺寸,不检测靠近边界的像素,默认值为31。
  • firstLevel:原始图像作为金字塔的第几层,默认值为0。
  • WTA_K:构造BRIEF描述符点对的像素点数,可选值2/3/4,默认值为2。
  • scoreType:响应排序方法,默认HARRIS_SCORE,表示按Harris响应函数排序。
  • patchSize:生成定向描述符的特征区域的尺寸,默认值为31。
  • fastThreshold:FAST阈值,默认值为20。
  • image:输入图像,单通道。
  • mask:掩模图像,指定查找关键点的区域,可选项。
  • keypoints:检测到的关键点,元组。
  • descriptors:关键点的描述符,形为(nfeatures,32)的Numpy数组。

注意事项:

  • 通过接口函数cv.ORB.create或cv.ORB_create实例化ORB类,在OpenCV的不同版本中可能只允许其中一种方式。
  • 函数detect、compute、detectAndCompute等是继承Feature2D类的成员函数,在程序中的格式为orb.detect,orb表示ORB类的实例对象。
  • 关键点描述符descriptor的形状为(nfeatures,32),nfeatures是关键点的数量,描述符的字节长度为32,对应于二进制编码长度为256。

例程 14.28:特征检测之 ORB 算法

# 【例程 14.28】特征检测之 ORB 算法
import cv2 as cv
import numpy as np
from matplotlib import pyplot as plt

if __name__ == '__main__':
    img = cv.imread("../images/Fig1701.png", flags=1)
    gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)
    print("shape of image: ", gray.shape)

    # Initiate ORB detector
    orb = cv.ORB_create()  # 实例化 ORB 类
    # kp, descriptors = orb.detectAndCompute(gray)  # 检测关键点和生成描述符
    kp = orb.detect(img, None)  # 关键点检测,kp 为元组
    kp, des = orb.compute(img, kp)  # 生成描述符
    print("Num of keypoints: ", len(kp))  # 500
    print("Shape of kp descriptors: ", des.shape)  # (500,32)
    imgS = cv.convertScaleAbs(img, alpha=0.5, beta=128)
    imgKp1 = cv.drawKeypoints(imgS, kp, None)  # 只绘制关键点位置
    imgKp2 = cv.drawKeypoints(imgS, kp, None, flags=cv.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS)  # 绘制关键点大小和方向
    plt.figure(figsize=(9, 3.5))
    plt.subplot(131), plt.title("1. Original")
    plt.axis('off'), plt.imshow(cv.cvtColor(img, cv.COLOR_BGR2RGB))
    plt.subplot(132), plt.title("2. ORB keypoints")
    plt.axis('off'), plt.imshow(cv.cvtColor(imgKp1, cv.COLOR_BGR2RGB))
    plt.subplot(133), plt.title("3. ORB keypoints scaled")
    plt.axis('off'), plt.imshow(cv.cvtColor(imgKp2, cv.COLOR_BGR2RGB))
    plt.tight_layout()
plt.show()


在这里插入图片描述


程序说明
程序运行结果如图所示。
⑴ 子图1是原始图像,子图2、子图3将ORB检测的关键点绘制在原始图像上。子图2只绘制了关键点的中心,子图3对每个关键点绘制表示关键点大小和方向的圆圈。
⑵ 例程检测到500个关键点,但子图2中显示的关键点数量似乎并不多。对比子图3可知,在一个关键点及其邻近点,可能在不同尺度被检测为很多个关键点,ORB算法并未对此进行抑制。



在这里插入图片描述

参考文献:Ethan Rublee, Vincent Rabaud, Kurt Konolige, and Gary Bradski. Orb: an efficient alternative to sift or surf. In Computer Vision (ICCV), 2011 IEEE International Conference on, pages 2564–2571. IEEE, 2011

【本节完】

版权声明:
youcans@xupt 原创作品,转载必须标注原文链接:(https://blog.csdn.net/youcans/article/details/128033070)
Copyright 2022 youcans, XUPT
Crated:2022-11-25

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

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

相关文章

【Hack The Box】linux练习-- SneakyMailer

HTB 学习笔记 【Hack The Box】linux练习-- SneakyMailer &#x1f525;系列专栏&#xff1a;Hack The Box &#x1f389;欢迎关注&#x1f50e;点赞&#x1f44d;收藏⭐️留言&#x1f4dd; &#x1f4c6;首发时间&#xff1a;&#x1f334;2022年11月23日&#x1f334; &…

函数调用在嵌入式架构设计中的应用

函数调用很好理解&#xff0c;即使刚学没多久的朋友也知道函数调用是怎么实现的&#xff0c;即调用一个已经封装好的函数&#xff0c;实现某个特定的功能。 把一个或者多个功能通过函数的方式封装起来&#xff0c;对外只提供一个简单的函数接口&#xff0c;然后在其他地方调用即…

SpringCloud - Config分布式配置中心

文章目录一.概述1. 分布式系统面临的配置问题2. 什么是配置中心3. 配置中心怎么用4. 配置中心能做什么二.Config服务端配置与测试1. 搭建1.1 在github上创建一个springcloud_config的新仓库1.2 获得新仓库的地址&#xff1a;1.3 本地硬盘目录上新建git仓库并clone1.4 创建文件1…

设置一个不能被继承的类

小屋杂谈&#xff0c;记录日常 方法1&#xff1a; 如果想让这个类不能被继承&#xff0c;可以把这个类的构造函数设置成私有&#xff0c;这样子类去继承他构造就会报错&#xff0c;这样的话这个类就是不能被继承的&#xff0c;如果需要用这个类的对象的话&#xff0c;在基类里…

机器学习中的交叉熵

文章目录一、背景二、概率论基础知识三、熵≈信息熵&#xff08;应用领域不同&#xff09;、相对熵KL散度、交叉熵、softmax、sigmoid、交叉熵损失图像分割如何理解CrossEntropyLoss()参考资料一、背景 学习机器学习过程中&#xff0c;总是会遇到交叉熵这个名词。通过交叉熵损…

SpringBoot整合knife4j

1.1 Swagger 前后端分离开发&#xff1a;前端和后端分开进行开发&#xff0c;2个项目&#xff0c;一个是前端项目&#xff0c;一个是后端项目 目前基本上很多小项目都是前后端分离&#xff0c;除了后台管理系统 前后端分离开发&#xff0c;前端(app、小程序、智能硬件等)怎么…

栈(C语言实现)

文章目录&#xff1a;1.栈的概念2.栈的结构3.接口实现3.1初始化栈3.2判断栈是否为空3.3压栈&#xff08;入栈&#xff09;3.4出栈3.5查看栈顶元素3.6统计栈内元素个数3.7销毁栈1.栈的概念 栈&#xff1a;一种特殊的线性表&#xff0c;其只允许在固定的一端进行插入和删除元素操…

Credly 数字证书

Credly 数字证书 Credly 简介 通过 Credly 颁发的徽章是对学习成果、经验或能力的数字表述。Credly 数字证书包括常见的组织徽章&#xff0c;如&#xff1a;AWS, Adobe, Autodesk, Certiport, Microsoft, CISCO, IBM 等等&#xff0c;以一种简单和安全的方式在线分享和验证&a…

基于改进人工蜂群算法的K均值聚类算法(Matlab代码实现)

&#x1f352;&#x1f352;&#x1f352;欢迎关注&#x1f308;&#x1f308;&#x1f308; &#x1f4dd;个人主页&#xff1a;我爱Matlab &#x1f44d;点赞➕评论➕收藏 养成习惯&#xff08;一键三连&#xff09;&#x1f33b;&#x1f33b;&#x1f33b; &#x1f34c;希…

基于SEIRD和元胞自动机(CA)模型的传染病发展趋势预测

目录前言一、模型假设二、符号说明三、SEIRD模型1. 模型求解四、元胞自动机&#xff08;CA)模型1. 模型求解2. 城市居民减少外出对疫情发展的影响3. 城市间人口流动对疫情发展的影响五 基于防疫政策的修正模型2 “全民戴口罩”“早发现&#xff0c;早隔离”“全民打疫苗”总结前…

Jsonp跨域的坑,关于jsonp你真的了解吗

先来介绍Jsonp跨域 Jsonp全称是Json with Padding&#xff0c;和Json没有关系 Json是一种数据交换格式&#xff0c;而Jsonp是一种依靠开发人员聪明才智创造出的一种费官方跨域数据交换协议。json是描述信息的格式&#xff0c;jsonp是信息传输的协议 在页面上直接发送一个跨域的…

树莓派之树莓派系统安装

树莓派系统安装 概述 树莓派(是为学习计算机编程教育而设计)&#xff0c;只有信用卡大小的微型电脑&#xff0c;其系统基于Linux。随着Windows 10 IoT的发布&#xff0c;我们也将可以用上运行Windows的树莓派。2014年刚知道有树莓派的时候好奇买了一块&#xff0c;型号&#x…

DSP-IIR滤波器设计

目录 滤波器的性能指标&#xff1a; 常用的模拟滤波器&#xff1a; 巴特沃斯滤波器&#xff1a; 巴特沃斯滤波器设计——一般已知Ωp及其衰减指标,Ωs及其衰减指标求得A&#xff0c;ε&#xff0c;N&#xff0c;Ωc&#xff1a; 巴特沃斯滤波器设计例题&#xff1a; 切比…

Python系列-Django

文章目录Python系列-Django用django实现社交媒体 social_book基本演示&#xff0c;点击可查看视频整体项目的创建数据库设计&#xff0c;基本用户创建表的设计 models.py创建用户查看数据库插件 database navigator登录、注册的实现用djangovue实现社交媒体 social_bookPython系…

【Java集合】Collection接口常用方法

文章目录Collection接口和常用方法> Collection接口常用方法> Collection接口遍历元素&#xff1a;使用Iterator&#xff08;迭代器&#xff09;> Collection接口遍历元素&#xff1a;增强 for 循环Collection接口和常用方法 Collection接口实现类的特点&#xff1a;…

CPU中的核与进程,线程间的关系讲解(操作系统基础概念)

CPU中的核与进程&#xff0c;线程间的关系讲解&#xff08;操作系统基础概念&#xff09; CPU中的内核 概念 CPU内核&#xff08;Die&#xff09;是CPU中间的核心芯片&#xff0c;由单晶硅制成&#xff0c;用来完成所有的计算、接受/存储命令、处理数据等&#xff0c;是数字…

Node.js | 详解 JWT 登录验证 的工作原理

&#x1f9d1;‍&#x1f4bc; 个人简介&#xff1a;一个不甘平庸的平凡人&#x1f36c; &#x1f5a5;️ 本系列专栏&#xff1a;Node.js从入门到精通 &#x1f5a5;️ TS知识总结&#xff1a;十万字超详细TS知识点总结 &#x1f449; 你的一键三连是我更新的最大动力❤️&…

【Java系列】一篇文章快速了解Java语言概述

Java语言概述1.Java简介2.JVM2.1JVM介绍2.2JVM特性3.Java特性4.搭建Java程序开发环境5.编写第一个Java应用程序6.小结第一个程序1.Java简介 java是面向对象的一门程序设计语言随着Java技术在web方面的不断成熟&#xff0c;已经成为Web应用程序的首选开发语言。后台开发&#x…

FRP进阶篇之安全认证

目录 一、前言 二、通信加密 1、概述 2、使用 三、BasicAuth 鉴权 1、概述 2、使用 2.1、客户端配置 2.2、启动客户端 2.3、效果验证 四、TLS双向身份验证 1、概述 2、使用 2.1、生成证书 2.2、服务端配置 2.3、客户端配置 一、前言 通过上次的《FRP入门篇》相信…

毕业设计-机器学习图像卡通动漫化图像风格迁移

前言 &#x1f4c5;大四是整个大学期间最忙碌的时光,一边要忙着备考或实习为毕业后面临的就业升学做准备,一边要为毕业设计耗费大量精力。近几年各个学校要求的毕设项目越来越难,有不少课题是研究生级别难度的,对本科同学来说是充满挑战。为帮助大家顺利通过和节省时间与精力投…