news 2026/3/10 9:41:54

OPENCV(python)--初学之路(十七)二进制鲁棒独立(BRIEF)和定向快速和轮换(ORB)

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
OPENCV(python)--初学之路(十七)二进制鲁棒独立(BRIEF)和定向快速和轮换(ORB)

一前言

今天我们这里下雪了,还挺大的,但是很美,大家可以听听雪落下的声音,雪景总是伴随别离,我和我的前女友就是分别于一场雪,而我们这个OPENCV的系列也即将结束,预计还有两次更新,我们就将开始yolov8代码学习,等我总结出来我会从搭建环境开始到做一个项目。我还报名了蓝桥杯,算促进我的学习了,大家也要努力呀。

二主要内容

一BRIEF(Binary Robust Independent Elementary Features)

理论

我们知道 SIFT 使用 128 维向量作为描述子。由于它使用浮点数,因此需要 512 个字节。类似地,SURF 也至少需要 256 个字节(对于 64 维描述子)。为数千个特征点创建这样的向量需要大量的内存,这在资源有限的情况下是不可行的,特别是嵌入式系统。内存越大,匹配所需的时间越长。

但实际匹配时可能不需要所有的维度。我们可以使用 PCA,LDA 等几种方法对其进行压缩。甚至使用 LSH(Locality Sensitive Hashing,局部敏感哈希)等其他方法也可以将浮点数格式的这些 SIFT 描述子转换为二进制字符串。对这些二进制字符串使用汉明距离进行匹配。这样速度更快,因为计算汉明距离只需要进行异或和位计数,这在具有 SSE 指令的现代 CPU 中非常快。但是我们仍然需要先找到描述符,然后才能应用哈希方法,这并不能解决我们在内存上的初始问题。

这就需要 BRIEF 算法。

它是一个二进制描述符,用于高效地描述图像中关键点(如角点)周围的局部外观。它不是特征检测器(它不寻找关键点,你需要先用像FAST、SIFT、ORB等检测器找到关键点),而是特征描述器。而且 BREIF 算法对于 CenSurE 特征点的效果比 SURF 特征点稍微好

它提供了直接查找二进制字符串而无需找到描述子的快捷方式。它采用平滑后的图像,并以特定的方式(在文中解释)选择一组\(\(n_d\)\)(x,y)位置对。然后在这些位置对上进行一些像素强度比较。例如,让第一个位置对为\(\(p\)\)和\(\(q\)\)。如果\(\(I(p)\lt I(q)\)\),则其结果为 1,否则为 0。对所有\((n_d (\(位置对进行对比以获得\)\)n_d\)\)维二进制字符串。一个长度为256的描述符可能看起来像这样:11001011...0110

OpenCV 中的 BRIEF

下面的代码展示了在 CenSurE 检测器的帮助下计算 BRIEF 描述子的方法。 (CenSurE 探测器在 OpenCV 中被称为 STAR 探测器)

请注意,您需要 opencv contrib 来使用它。(需要在虚拟下安装包pip install opencv-contrib-python 直接pip)

但是还有个问题就是你的opencv的版本是否兼容这个函数,我给出以下方法

1检查opencv版本是否兼容

import cv2 as cv print(f"OpenCV 版本: {cv.__version__}") print(f"构建信息中包含 contrib: {'contrib' in cv.getBuildInformation()}") # 检查 xfeatures2d 是否可用 try: # 尝试导入 xfeatures2d from cv2 import xfeatures2d print("xfeatures2d 模块可用") # 测试具体函数 star = cv.xfeatures2d.StarDetector_create() brief = cv.xfeatures2d.BriefDescriptorExtractor_create() print("STAR 和 BRIEF 创建成功") except ImportError: print("xfeatures2d 模块不可用") except AttributeError as e: print(f"函数不可用: {e}")

2安装 opencv-contrib-python

# 卸载原有 opencv-python
pip uninstall opencv-python opencv-contrib-python -y

# 安装 contrib 版本
pip install opencv-contrib-python

# 或指定版本(确保兼容性)
pip install opencv-contrib-python==4.8.1.78

因为我的版本兼容,所以我就直接演示了

import numpy as np import cv2 as cv from matplotlib import pyplot as plt # 读取灰度图像 img = cv.imread(r'D:\python_code\pic\sumoiao.webp', 0) # 初始化STAR特征检测器 star = cv.xfeatures2d.StarDetector_create() # 初始化BRIEF描述符提取器 brief = cv.xfeatures2d.BriefDescriptorExtractor_create() # 使用STAR检测关键点 kp = star.detect(img, None) # 使用BRIEF计算描述符 kp, des = brief.compute(img, kp) # 输出BRIEF描述符大小和描述符矩阵形状 print(brief.descriptorSize()) print(des.shape)

结果如下

函数 brief.getDescriptorSize()给出以字节为单位的\(\(n_d\)\)大小。默认情况下为 32。下一步是匹配,这将在另一章中完成。

二ORB(Oriented FAST and Rotated BRIEF)

理论(太理论,不用看)

作为 OpenCV 爱好者,关于 ORB 最重要的是它来自“OpenCV Labs”。这个算法在 2011 年由 Ethan Rublee,Vincent Rabaud,Kurt Konolige 和 Gary R. Bradski 在他们的论文ORB: An efficient alternative to SIFT or SURF中提出的。如标题所述,它是一个很好的 SIFT 和 SURF 的替代,在计算成本,匹配性能,尤其是专利方面。是的,SIFT 和 SURF 已获得专利,您应该支付它们的使用费用。但是 ORB 不是!!!

ORB 基本上是 FAST 特征点检测器和 Brief 描述子的融合,并进行了许多修改以增强性能。首先,它使用 FAST 查找特征点,然后应用 Harris 角点的测量方法来查找其中的前 N 个点。它还使用金字塔来生成多尺度特征。但有一个问题是,FAST 不计算方向。那么旋转不变性呢?作者提出了以下修改。

它计算以角点为中心的图像块的强度加权质心。从该角点到质心的矢量方向给出了方向。为了改善旋转不变性,使用 x 和 y 计算矩,该 x 和 y 应该在半径为$$r \(的圆形区域中,其中\)r $$是图像块的大小。

BRIEF 具有一个重要特性,即每个位特征具有较大的方差,平均值接近 0.5。但是一旦它沿着特征点方向定向,它就会失去这个特性并变得更加分散。高的方差使得特征更易于分辨,因为它对输入有不同的响应。另一个理想的特性是使测试不相关,因为每次测试都会对结果产生影响。为了解决所有这些问题,ORB 在所有可能的二进制测试中运行贪婪搜索,以找到具有高方差和意味着接近 0.5 的那些,以及不相关的。结果称为rBRIEF

对于描述子匹配,使用对传统 LSH 进行改善后的多探针 LSH。该论文称 ORB 比 SURF 和 SIFT 快得多,并且 ORB 描述子比 SURF 效果更好。 ORB 是用于全景拼接等的低功率设备的不错选择。

OpenCV 中的 ORB

像往常一样,我们必须使用函数cv.ORB()

ORB 参数详解

参数默认值说明
nfeatures500要保留的最大特征点数量
scaleFactor1.2金字塔缩放因子,>1.0
nlevels8金字塔层数
edgeThreshold31不检测边界的像素数
firstLevel0第一层金字塔
WTA_K2产生描述子的点数(2,3,4)
scoreTypeORB_HARRIS_SCORE评分类型:HARRIS 或 FAST
patchSize31描述符使用的 patch 大小
fastThreshold20FAST 阈值

它有许多可选参数。最有用的是 nFeatures,表示要保留的最大要素数量(默认为 500),scoreType 表示对特征点进行排序使用 Harris 得分或 FAST 得分(默认情况下为 Harris 得分)等。另一个参数 WTA_K 决定生成一个 oriented BRIEF 描述子的所用的像素点数目。默认情况下它是 2,即一次选择两个点。在这种情况下进行匹配,使用 NORM_HAMMING 距离。如果 WTA_K 为 3 或 4,则需要 3 或 4 个点来产生 BRIEF 描述子,匹配距离由 NORM_HAMMING2 定义。

代码如下

import numpy as np import cv2 as cv from matplotlib import pyplot as plt # 读取灰度图像 img = cv.imread(r'D:\python_code\pic\sumoiao.webp', 0) # 初始化ORB检测器 orb = cv.ORB_create() # 检测图像中的ORB关键点 kp = orb.detect(img, None) # 计算关键点描述符 kp, des = orb.compute(img, kp) # 绘制关键点(仅位置,不包含大小和方向) img2 = cv.drawKeypoints(img, kp, None, color=(0, 255, 0), flags=0) # 显示结果图像 plt.imshow(img2) plt.show()

效果如下

三最后一语

今天就写这么多吧,写的时候一直在下雪,还是挺有意境的,大家记得保暖,注意身体

余拏一小舟,拥毳衣炉火,独往湖心亭看雪。--张岱

崇祯五年的雪就这么下了三百年

感谢观看,共勉!!

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/3/10 19:46:53

m4s-converter:3分钟解决B站缓存播放难题的终极方案

m4s-converter:3分钟解决B站缓存播放难题的终极方案 【免费下载链接】m4s-converter 将bilibili缓存的m4s转成mp4(读PC端缓存目录) 项目地址: https://gitcode.com/gh_mirrors/m4/m4s-converter 还在为B站缓存的m4s文件无法播放而烦恼吗?m4s-conv…

作者头像 李华
网站建设 2026/3/10 4:03:44

27、深入理解库 I/O 函数:原理、应用与实现

深入理解库 I/O 函数:原理、应用与实现 1. 库 I/O 函数算法 在文件操作中,库 I/O 函数起着至关重要的作用。下面详细介绍几个关键库 I/O 函数的算法。 - fread 算法 - 首次调用 :当首次调用 fread() 时, FILE 结构的缓冲区为空。它会使用保存的文件描述符 fd …

作者头像 李华
网站建设 2026/3/9 0:07:08

FastAPI 路由系统深度探索:超越基础 CRUD 的高级模式与架构实践

FastAPI 路由系统深度探索:超越基础 CRUD 的高级模式与架构实践 引言:为什么需要深入研究 FastAPI 路由? FastAPI 作为现代 Python Web 框架,以其卓越的性能、直观的类型提示和自动 API 文档生成而广受欢迎。大多数教程停留在基础…

作者头像 李华
网站建设 2026/2/26 3:24:05

Python数据可视化进阶:超越基础图表,构建专业级数据叙事

Python数据可视化进阶:超越基础图表,构建专业级数据叙事 在数据科学领域,可视化远不止是生成图表那么简单,它是数据探索、分析与叙事的关键桥梁。尽管Matplotlib、Seaborn等传统库为人熟知,但现代数据可视化需求已超越…

作者头像 李华
网站建设 2026/3/5 15:07:25

Player.js 终极指南:掌控嵌入式视频播放的完整教程

Player.js 终极指南:掌控嵌入式视频播放的完整教程 【免费下载链接】player.js Interact with and control an embedded Vimeo Player. 项目地址: https://gitcode.com/gh_mirrors/pl/player.js Player.js 是一个强大的 JavaScript 库,专门用于与…

作者头像 李华
网站建设 2026/3/7 2:32:49

35、I/O 缓冲区管理算法:从 Unix 到新算法的演进

I/O 缓冲区管理算法:从 Unix 到新算法的演进 1. 异步写入与物理块设备 I/O 1.1 异步写入函数 awrite 异步写入函数 awrite 用于启动对缓冲区的异步 I/O 操作,其代码如下: awrite(BUFFER *bp) {bp->opcode = ASYNC;// for ASYNC write;start_io(bp); }awrite 调…

作者头像 李华