OpenCV实战——多尺度FAST特征检测

news/2024/4/25 12:46:50/文章来源:https://blog.csdn.net/LOVEmy134611/article/details/130037808

OpenCV实战——多尺度FAST特征检测

    • 0. 前言
    • 1. BRISK 特征检测器
      • 1.1 BRISK 检测关键点
      • 1.2 多尺度关键点快速检测
    • 2. ORB 特征检测算法
    • 3. 完整代码
    • 相关链接

0. 前言

FAST 是用于快速检测图像中关键点的方法,而 SURF 和 SIFT 算法的设计重点是尺度不变性。为了同时实现快速检测和尺度不变性,OpenCV 中引入了新的兴趣点检测器,包括 BRISK (Binary Robust Invariant Scalable Keypoints) 检测器(基于 FAST 特征检测器)和 ORB (Oriented FAST and Rotated BRIEF) 检测器。当需要快速可靠的图像匹配时,可以使用特征点检测器 BRISKORB

1. BRISK 特征检测器

可以利用 cv::FeatureDetector 抽象类使用 BRISK 检测关键点。

1.1 BRISK 检测关键点

(1) 首先创建一个检测器的实例,然后在输入图片上调用 detect 方法:

cv::Ptr<cv::xfeatures2d::SiftFeatureDetector> ptrSIFT = new cv::xfeatures2d::SiftFeatureDetector();
ptrSIFT->detect(image, keypoints);

在图像中检测到的多尺度关键点如下图所示:

多尺度关键点检测结果
BRISK 不仅是一个特征点检测器,而且该方法还包括每个检测到的关键点的邻域,接下来,我们将介绍如何使用 BRISK 执行多尺度关键点的快速检测。

1.2 多尺度关键点快速检测

为了检测不同尺度的兴趣点,BRISK 方法首先通过两个下采样过程构建图像金字塔,第一个过程从原始图像大小开始,并在每一层(或 octave) 上将其缩小一半,中间层是通过将原始图像向下采样 1.5 倍来创建的,在这些中间层中,原始图像通过连续的 1/2 采样生成附加层:

中间层生成

然后将 FAST 特征检测器应用于该金字塔的所有图像,关键点提取与 SIFT 使用类似的标准。首先,当将其强度与其八个空间邻居之一进行比较时,可接受的兴趣点必须是局部最大值,然后将该点与上下层中相邻点的分数进行比较,如果它的分数同样更高,那么它就被认为是一个兴趣点,BRISK 的关键在于金字塔的不同层具有不同的分辨率。
该方法需要在尺度和空间上进行插值,以便精确定位每个关键点,插值基于 FAST 关键点分数。在空间中,插值是在 3x3 邻域上执行的,在尺度上,它是通过沿着尺度轴拟合一个一维抛物线通过当前点及其上下两个相邻的局部关键点来计算的;上图中说明了如何进行这种关键点定位。因此,即使在离散图像尺度上执行 FAST 关键点检测,与每个关键点关联的结果检测尺度也是一个连续值。
cv::BRISK 类提供了两个可选参数来控制关键点的检测,第一个参数是 FAST 关键点的阈值,第二个参数是图像金字塔中将生成的 octave 数:

cv::Ptr<cv::BRISK> ptrBRISK = cv::BRISK::create(60,     // BRISK 关键点可接受的阈值5);     // octave 数量
ptrBRISK->detect(image, keypoints);

OpenCV 中,除了 BRISK 可以作为多尺度快速检测器外,ORB 特征检测器也可以高效的执行关键点检测。

2. ORB 特征检测算法

ORB (Oriented FAST and Rotated BRIEF) 的第一部分指的是关键点检测部分,而第二部分指的是 ORB 提出的描述符,本节中,我们将专注于检测方法。
BRISK 一样,ORB 首先创建一个由多个层组成图像金字塔,其中每一层都是由前一层按特定比例因子(由 cv::ORB 函数中的参数)下采样获得。然后接受最强的 N 个关键点,其中关键点分数由 Harris 角度度量定义。
ORB 检测器的方向与每个检测到的兴趣点相关联,这些信息有助于对齐在不同图像中检测到的关键点的描述符,ORB 中使用关键点周围圆形邻域的质心方向。根据定义,由于 FAST 关键点始终具有偏心的质心,因此连接中心点和质心的直线的角度可以很好的定义质心方向。ORB 特征检测调用方法如下:

cv::Ptr<cv::ORB> ptrORB = cv::ORB::create(75,     // 关键点总数1.2,    // 层间缩放因子8);     // 金字塔中层数
ptrORB->detect(image, keypoints);

得到的结果如下所示:

ORB 特征检测结果

如上图所示,由于关键点是在每个金字塔层上独立检测的,因此检测器可以在不同尺度上重复检测相同的特征点。

3. 完整代码

头文件 (harrisDetector.h) 完整代码参考 Harris 特征点检测一节,主函数文件 (briskCorners.cpp) 完整代码如下所示:

#include <iostream>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/features2d/features2d.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/xfeatures2d.hpp>#include "harrisDetector.h"int main() {// Harriscv::Mat image = cv::imread("1.png", 0);if (!image.data) return 0;std::vector<cv::KeyPoint> keypoints;cv::Mat featureImage;// BRISKcv::transpose(image, image);cv::flip(image, image, 0);keypoints.clear();cv::Ptr<cv::BRISK> ptrBRISK = cv::BRISK::create(60,     // BRISK 关键点可接受的阈值5);     // octave 数量ptrBRISK->detect(image, keypoints);cv::drawKeypoints(image, keypoints, featureImage, cv::Scalar(255, 255, 255), cv::DrawMatchesFlags::DRAW_RICH_KEYPOINTS);cv::namedWindow("BRISK");cv::imshow("BRISK", featureImage);std::cout << "Number of BRISK keypoints: " << keypoints.size() << std::endl;// ORBimage = cv::imread("1.png", 0);cv::transpose(image, image);cv::flip(image, image, 0);keypoints.clear();cv::Ptr<cv::ORB> ptrORB = cv::ORB::create(75,     // 关键点总数1.2,    // 层间缩放因子8);     // 金字塔中层数ptrORB->detect(image, keypoints);cv::drawKeypoints(image, keypoints, featureImage, cv::Scalar(255, 255, 255), cv::DrawMatchesFlags::DRAW_RICH_KEYPOINTS);cv::namedWindow("ORB");cv::imshow("ORB", featureImage);std::cout << "Number of ORB keypoints: " << keypoints.size() << std::endl;cv::waitKey();return 0;
}

相关链接

OpenCV实战(1)——OpenCV与图像处理基础
OpenCV实战(2)——OpenCV核心数据结构
OpenCV实战(3)——图像感兴趣区域
OpenCV实战(4)——像素操作
OpenCV实战(5)——图像运算详解
OpenCV实战(6)——OpenCV策略设计模式
OpenCV实战(7)——OpenCV色彩空间转换
OpenCV实战(8)——直方图详解
OpenCV实战(9)——基于反向投影直方图检测图像内容
OpenCV实战(10)——积分图像详解
OpenCV实战(11)——形态学变换详解
OpenCV实战(12)——图像滤波详解
OpenCV实战(13)——高通滤波器及其应用
OpenCV实战(14)——图像线条提取
OpenCV实战(15)——轮廓检测详解
OpenCV实战(16)——角点检测详解
OpenCV实战(17)——FAST特征点检测

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

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【软件设计师10】软件工程

软件工程 1. 瀑布模型SDLC - 结构化 优点&#xff1a;结构化方法模型&#xff0c;每个阶段分工明确&#xff1b;出现问题可以向上层回溯 缺点&#xff1a;需求阶段难以把控&#xff0c;在项目初期&#xff0c;软件的需求几乎是不明确的&#xff0c;等开发完用户往往再提出问…

微信小程序 | 网易云+ChatGPT实现一个智能音乐推荐小程序

文章目录* 效果预览** 分析用户的输入产生推荐** 分析用户的选择标签进行推荐一、需求背景二、项目原理及架构2.1 实现原理&#xff08;1&#xff09; 基于用户的喜欢歌手推荐&#xff08;2&#xff09;基于用户的兴趣标签推荐&#xff08;3&#xff09;改进上一步推荐的结果2.…

IM即时通讯-N-如何保证消息的可靠性展示

结论先行 客户端如何在推拉结合的模式下保证消息的可靠性展示&#xff1f; 原则&#xff1a; server拉取的消息一定是连续的原则&#xff1a; 端侧记录的消息的连续段有两个作用&#xff1a; 1. 记录消息的连续性&#xff0c; 即起始中间没有断层&#xff0c; 2. 消息连续&am…

【数据结构】树与二叉树的基本概念及性质

目录 一、树的基本概念 1️⃣树的定义 2️⃣基本术语 3️⃣树的性质 二、二叉树的概念 1️⃣二叉树的定义 2️⃣特殊二叉树 3️⃣二叉树的性质 参考资料 一、树的基本概念 1️⃣树的定义 数据结构中的树是什么❓ 树是 个结点的有限集。有且仅有一个特定的称为根(上图A结点…

零基础教学必会篇(详解字符函数和字符串函数)(完结版)

各位csdn的友友们好&#xff0c;上次阿博给大家讲了一些简单的字符串函数的功能和模拟实现&#xff0c;今天就和阿博一起再上一个台阶继续拿捏它们&#x1f60a;&#x1f60a;&#x1f60a; 文章目录1.strstr的功能介绍2.strstr函数的模拟实现3.strtok的功能介绍4.strerror和pe…

零基础学习Java 06

目录 String String构造方法 字符串查找 字符串截取 字符串替换 字符串拆分 字符串修改 String String类在java.lang包下&#xff0c;所以使用的时候不需要导包。 String构造方法 字符串查找 char charAt(int index)&#xff0c;输入位置index&#xff0c;找单个字符 …

MAE论文笔记+Pytroch实现

Masked Autoencoders Are Scalable Vision Learners&#xff0c; 2021 近期在梳理Transformer在CV领域的相关论文&#xff0c;落脚点在于如何去使用Pytroch实现如ViT和MAE等。通过阅读源码&#xff0c;发现不少论文的源码都直接调用timm来实现ViT。故在此需要简单介绍一下timm…

Linux 中的 /dev/random 和 /dev/urandom 是什么?

在Linux系统中&#xff0c;/dev/random和/dev/urandom是两个特殊的设备文件&#xff0c;用于生成随机数。在本文中&#xff0c;我们将深入探讨这两个设备文件的区别&#xff0c;以及它们在Linux系统中的作用。 /dev/random /dev/random是一个随机数生成器设备文件&#xff0c;…

windows10下编译zlib库

系列文章目录 文章目录系列文章目录前言一、问题原因二、准备具体操作编译zlib工程前言 我使用CMake编译zlib源码&#xff0c;出现警告&#xff1a;CMake Deprecation Warning at CMakeLists.txt:1 (cmake_minimum_required): Compatibility with CMake < 2.8.12 will be r…

五、基础初始化(init_sequence)

初始化序列数组 # < lib_arm\board.c > init_fnc_t *init_sequence[] { board_init, /* basic board dependent setup */ timer_init, /* initialize timer */ env_init, /* initialize environment */ init_baudrate, /* initialze baudrate settings */ serial_…

VUE3 学习笔记(七)动态样式 class 实现

目录 一、绑定 HTML class 1. 绑定对象 2. 绑定数组 3. 在组件上使用 二、绑定内联样式 1. 绑定对象 2. 绑定数组 3. 自动前缀 4. 样式多值 数据绑定的一个常见需求场景是操纵元素的 CSS class 列表和内联样式。因为 class 和 style 都是 attribute&#xff0c;我们可…

一道小学题,解答了我与学霸的差距

目录一、背景二、题目三、过程1.形式转换2.个位数相加只能向前进一位嘛&#xff1f;进两位可以吗&#xff1f;进三位呢&#xff1f;3.十位数上要填写的内容&#xff0c;可以是0嘛&#xff1f;你想到了吗&#xff1f;4.如何下意识的去做结构化&#xff1f;四、总结五、升华一、背…

讲一下dns过程:给一个网址www.google.com,dns服务器如何逐级解析的?

DNS 中的域名都是用句点来分隔的&#xff0c;比如 www.server.com&#xff0c;这里的句点代表了不同层次之间的界限。在域名中&#xff0c;越靠右的位置表示其层级越高。域名最后还有一个点&#xff0c;比如 www.server.com.&#xff0c;这个最后的一个点代表根域名。 根DNS服…

UDP套接字

大家好,又见面了,&#x1f389;&#x1f389;&#x1f389;&#x1f338;&#x1f338;&#x1f338; 今天为大家带来UDP套接字的相关知识 文章目录认识socketUDP和TCP认识UDPAPI有关方法基于UDP实现回显服务器UDP的方法基于UDP实现回显程序认识socket UDP和TCP 认识UDPAPI有…

腾讯空降测试工程师,绩效次次拿S,真是砂纸擦屁股,给我露了一手啊

​上周我们公司的绩效面谈全部结束了&#xff0c;每年到这个时间点就是打绩效的时候了&#xff0c;对于职场打工人来说绩效绝对是最重要的事情之一&#xff0c;原因也很简单&#xff1a;奖金、晋升、涨薪都和它有关系。 比如下面这个美团员工在脉脉上的自曝就很凄凉&#xff1…

多种方法解决VS在创建多个源文件后运行时出现的重定义错误:main已经在1.obj中定义

名人说&#xff1a;博学之&#xff0c;审问之&#xff0c;慎思之&#xff0c;明辨之&#xff0c;笃行之。——《中庸》 创作者&#xff1a;Code_流苏(CSDN) 本篇文章收录于&#xff1a;各类问题记录专栏 记录一、原因经过二、解决方法1️⃣方法一 注释2️⃣方法二 生成排除3️⃣…

学习Python的一些知识点记录

一、对象比较 Python中有两种对象比较方式&#xff1a; 值比较。使用比较符号&#xff08;、>、<等&#xff09;标识符比较。使用 is、not 关键字。标识符就是对象在内存中的有效地址&#xff0c;使用 id() 函数可以得到对象的标识符。二、None 对象 这是一个特殊对象…

【Python】数学 - 用 Python 自动化求解函数 f(x) 的值

目录 1、缘起 2、求以下函数的值 3、代码清单 3.1、求解 f(0)、f(1)、 f(​编辑)、f(​编辑) 3.2、求解 g(0)、g(1)、g(​编辑)、g(​编辑) 3.3、求解 h(0)、h(1)、h(​编辑)、h(​编辑) 4、总结 1、缘起 Python 是一种强大的编程语言&#xff0c;它具有广泛的应用领域。…

四、第二阶段

全局数据 声明 # < lib_arm\board.c > DECLARE_GLOBAL_DATA_PTR; 定义 # < include\asm\global_data.h > typedef struct global_data { bd_t *bd; unsigned long flags; unsigned long baudrate; unsigned long have_console; /* serial_init() was calle…

使用adb 命令删除手机预装app

1. 手机开启开发者选项&#xff0c;允许usb调试&#xff1b; 2.pc 安装adb&#xff0c; 1&#xff09;Windows版本&#xff1a;https://dl.google.com/android/repository/platform-tools-latest-windows.zip 2&#xff09;按键windowsr打开运行&#xff0c;输入sysdm.cpl&a…