OpenCV实战(17)——FAST特征点检测

news2025/2/26 18:45:22

OpenCV实战(17)——FAST特征点检测

    • 0. 前言
    • 1. FAST 特征点检测
    • 2. 自适应特征检测
    • 3. 完整代码
    • 小结
    • 系列链接

0. 前言

Harris 算子根据两个垂直方向上的强度变化率给出了角点(或更一般地说,兴趣点)的数学定义。但使用这种定义需要计算图像导数,计算代价较为高昂,特别是兴趣点检测通常只是更复杂算法的先决步骤。
在本中,我们将学习另一个特征点检测算子 FAST (Features from Accelerated Segment Test)。其专门设计用于快速检测图像中的兴趣点;关键点检测仅基于几个像素的比较。

1. FAST 特征点检测

使用 OpenCV 通用接口进行特征点检测,能够轻松使用任意特征点检测器。本节将介绍 FAST 检测器,顾名思义,其被设计为进行快速计算。

(1) 创建一个关键点向量来存储结果:

std::vector<cv::KeyPoint> keypoints;

(2) 创建一个阈值为 40 的 FAST 检测器:

// FAST 检测器
cv::Ptr<cv::FastFeatureDetector> ptrFAST = new cv::FastFeatureDetector(40);

(3) 检测加载图像的所有关键点:

ptrFAST->detect(image, keypoints);

OpenCV 还提供了一个通用函数来在图像上绘制关键点:

cv::drawKeypoints(image, keypoints, image, cv::Scalar(255, 255, 255), cv::DrawMatchesFlags::DRAW_OVER_OUTIMG);

通过指定绘图标志,将关键点绘制在输入图像上,可以得到以下输出结果:

FAST特征检测结果
当我们将关键点颜色指定为负值时,绘制的每个圆圈将使用不同的随机颜色。
Harris 角点一样,FAST 特征算法源于角点定义,该定义基于特征点周围的图像强度。关键点的检测通过检查以候选点为中心的像素圆进行,如果找到长度大于圆周长 3/4 的连续点(弧),其所有像素都与中心点的强度显着不同,则该候选点为一个关键点。
这是一个可以快速计算的检测过程。此外,在其公式中,该算法使用了一个额外的技巧来进一步加快计算过程。事实上,如果我们首先测试圆上相距 90 度的四个点(例如,上、下、右、左),为了满足检测条件,其中至少三个点都必须比中心像素更亮或更暗,否则,可以立即否定该点,而无需检查圆周上的其他点。这是一个非常高效的检测技巧,因为在实践中,大多数图像点都无法满足此四点检测条件。
要检查像素圆的半径是该方法需要考虑的一个因素,在实践中发现,半径为 3 时检测效果较好,效率也更高,此时,需要考虑圆周上的 16 个像素:
R ≈ [ 16 1 2 15 3 14 4 13 0 5 12 6 11 7 10 9 8 ] R\approx\left[ \begin{array}{ccc} & & 16 & 1 & 2 & &\\ & 15 & & & & 3& \\ 14&&&&&&4\\ 13&&&0&&&5\\ 12&&&&&&6\\ & 11 & & & & 7&\\ & & 10 & 9 & 8 & &\\\end{array}\right] R 141312151116101092837456

在以上示例中,用于预测试的四个点的像素值为 15913,所需满足条件的连续较暗或较亮的像素点数为 12。但是,可以观察到通过将连续段的长度减少到 9,可以更好的检测到角点在不同图像上的可重复性。这种变体通常称为 FAST-9 角点检测器,这也是 OpenCV 中所采用的。此外,OpenCV 中的 cv::FASTX 函数实现了 FAST 检测器的另一个变体。
一个像素点的强度必须与中心像素的强度相差指定的量才会被视为满足更暗或更亮的检测条件,相差的量使用函数中的阈值参数指定,阈值越大,检测到的角点就越少。
而对于 Harris 特征而言,通常需要对已经检测到的角点进行非极大值抑制。因此,需要定义角点强度度量。也可以考虑以下替代方案,角点强度由中心像素与所识别的连续弧上的像素之间的绝对差之和给出,该算法也可通过直接函数调用实现:

cv::FAST(image,     // 输入图像
        keypoints,  // 输出关键点向量
        40,         // 阈值
        false);     // 是否使用非极大值抑制

但是,推荐使用 cv::FeatureDetector 接口,提高应用程序的灵活性。
FAST 特征点检测算法实现了非常快的兴趣点检测,因此,当程序需要效率优先时,应该首选该算法,例如,在实时视觉跟踪或对象识别应用程序中,必须在实时视频流中跟踪或匹配多个特征点。
为了改进特征点的检测,OpenCV 提供使用许多类适配器,以更好地控制关键点的提取。

2. 自适应特征检测

如果希望更好地控制特征点的数量,可以使用 cv::FeatureDetector 类的子类 cv::DynamicAdaptedFeatureDetector,其可以指定检测的兴趣点数量,在 FAST 特征检测器中用法如下:

cv::DynamicAdaptedFeatureDetector fastD(
    new cv::FastAdjuster(40),   // 特征检测器
    150,                        // 最少特征数量
    200,                        // 最大特征数量
    50);                        // 最大迭代次数
fastD->detect(image, keypoints);

然后迭代地检测兴趣点,每次迭代后,检查检测到的兴趣点数量,并相应地调整检测器阈值以产生更多或更少的点;重复此过程,直到检测到的兴趣点数位于指定的区间内。
通过指定最大迭代次数,避免过多检测耗费太多时间。要以通用方式实现此方法,使用的 cv::FeatureDetector 类必须实现 cv::AdjusterAdapter 接口,该类包括一个 tooFew 方法和一个 tooMany 方法,这两个方法都会修改检测器的内部阈值以产生更多或更少的关键点;此外,还有一个断言方法,当检测器阈值仍然可以调整时返回 true
虽然可以使用 cv::DynamicAdaptedFeatureDetector 类获得适当数量的特征点,但是这需要以降低效率为代价;此外,该类无法保证一定会在指定的迭代次数内获得所需数量的特征点。
可以看到,我们将动态分配对象的地址作为参数传递,以指定适配器类将使用的特征检测器。我们无需手动释放分配的内存来避免内存泄漏,这是因为指针会被转移到 cv::Ptr<FeatureDetector> 参数,它会自动释放所指向的对象。
另一个有用的类适配器是 cv::GridAdaptedFeatureDetector 类,它会在图像上定义网格,然后,可以限制每个单元格包含的最大元素数量,以将检测到的关键点散布在图像上。在检测图像中的关键点时,通常会在特定纹理区域中看到集中的兴趣点。例如,在以上图像的眼睛周围检测到非常密集的 FAST 特征点,通过使用此类适配器可以改进检测结果:

cv::GridAdaptedFeatureDetector fastG(
    new cv::FastFeatureDetector(10),   // 特征检测器
    1200,                              // 最大特征点数量
    5,                                 // 网格行数
    2);                                // 网格列数
fastG->detect(image, keypoints);

类适配器通过使用提供的 cv::FeatureDetector 对象检测每个单元格上的特征点,还可以指定最大总特征点数,在每个单元格中只保留强度最大的数个点,以免超过指定的最大值。
cv::PyramidAdaptedFeatureDetector 适配器可以在图像金字塔上应用特征检测器,结果组合在关键点的输出向量中:

cv::PyramidAdaptedFeatureDetector fastP(
    new cv::FastFeatureDetector(60),   // 特征检测器
    3);                                // 金字塔层数
fastP->detect(image, keypoints);

每个点的坐标通过原始图像坐标指定,此外设置 cv::Keypoint 类的 size 属性,以便在原始分辨率的一半处检测到的点的大小是原始图像中检测到的点的大小的两倍。将 cv::drawKeypoints 函数中的 flag 参数设为 cv::DrawMatchesFlags::DRAW_RICH_KEYPOINTS,可以令绘制的半径等于关键点 size 属性。

3. 完整代码

头文件 (harrisDetector.h) 完整代码参考 Harris 特征点检测一节,主函数文件 (fastCorners.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() {
    // 读取图像
    cv::Mat image = cv::imread("1.png", 0);
    if (!image.data) return 0;
    cv::transpose(image, image);
    cv::flip(image, image, 0);
    cv::namedWindow("Original");
    cv::imshow("Original",image);
    std::vector<cv::KeyPoint> keypoints;
    // FAST 特征
    image = cv::imread("1.png", 0);
    cv::transpose(image, image);
    cv::flip(image, image, 0);
    keypoints.clear();
    // FAST 检测器
    cv::Ptr<cv::FastFeatureDetector> ptrFAST = cv::FastFeatureDetector::create(40);
    ptrFAST->detect(image, keypoints);
    cv::drawKeypoints(image, keypoints, image, cv::Scalar(255, 255, 255), cv::DrawMatchesFlags::DRAW_OVER_OUTIMG);
    std::cout << "Number of keypoints (FAST): " << keypoints.size() << std::endl;
    cv::namedWindow("FAST");
    cv::imshow("FAST",image);
    // 未使用非极大值抑制的 FAST 特征
    image = cv::imread("1.png", 0);
    cv::transpose(image, image);
    cv::flip(image, image, 0);
    keypoints.clear();
    ptrFAST->setNonmaxSuppression(false);
    ptrFAST->detect(image, keypoints);
    cv::drawKeypoints(image, keypoints, image, cv::Scalar(255, 255, 255), cv::DrawMatchesFlags::DRAW_OVER_OUTIMG);
    cv::namedWindow("FAST Features (all)");
    cv::imshow("FAST Features (all)",image);
    // 读取图像
    image = cv::imread("1.png", 0);
    cv::transpose(image, image);
    cv::flip(image, image, 0);
    int total(100);         // 关键点数量
    int hstep(5), vstep(3); // 4x3 的网格
    int hsize(image.cols/hstep), vsize(image.rows/vstep);
    int subtotal(total/(hstep*vstep));  // 每个网格中的关键点数量
    cv::Mat imageROI;
    std::vector<cv::KeyPoint> gridpoints;
    std::cout << "Grid of " << vstep << " by " << hstep << " each of size " << vsize << " by " << hsize << std::endl;
    // 使用低阈值探测
    ptrFAST->setThreshold(20);
    // 非极大值抑制
    ptrFAST->setNonmaxSuppression(true);
    keypoints.clear();
    for (int i=0; i<vstep; i++) {
        for (int j=0; j<hstep; j++) {
            // 在当前网格上创建ROI
            imageROI = image(cv::Rect(j*hsize, i*vsize, hsize, vsize));
            // 在网格中检测关键点
            gridpoints.clear();
            ptrFAST->detect(imageROI, gridpoints);
            std::cout << "Number of FAST in grid " << i << "," << j << ": " << gridpoints.size() << std::endl;
            if (gridpoints.size()>subtotal) {
                for (auto it=gridpoints.begin(); it!=gridpoints.end()+subtotal; ++it) {
                    std::cout << "  " << it->response << std::endl;
                }
            }
            // 获取最强 FAST 特征
            auto itEnd(gridpoints.end());
            if (gridpoints.size()>subtotal) {
                std::nth_element(gridpoints.begin(), 
                                gridpoints.end()+subtotal, 
                                gridpoints.end(),
                                [](cv::KeyPoint& a, cv::KeyPoint& b) {return a.response>b.response;});
                itEnd = gridpoints.begin() + subtotal;
            }
            // 添加到全局关键点向量
            for (auto it=gridpoints.begin(); it!=itEnd; ++it) {
                it->pt += cv::Point2f(j*hsize, i*vsize);
                keypoints.push_back(*it);
                std::cout << " " << it->response << std::endl;
            }
        }
    }
    cv::drawKeypoints(image, keypoints, image, cv::Scalar(255, 255, 255), cv::DrawMatchesFlags::DRAW_RICH_KEYPOINTS);
    cv::namedWindow("FAST Features (grid)");
    cv::imshow("FAST Features (grid)", image);
    cv::waitKey();
    return 0;
}

小结

为了解决 Harris 角点检测算法计算代价较为高昂的缺点,特征点检测算子 FAST (Features from Accelerated Segment Test) 被专门设计用于快速检测图像中的角点。本节,我们介绍了如何使用通用接口调用 OpenCV 中的 FAST 特征点检测算法。

系列链接

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)——角点检测详解

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

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

相关文章

Android 14 新 API:直接监听截屏操作,不用再观察媒体文件了~

截屏可以说是手机设备最常用的功能了&#xff0c;Android 系统非常重视截屏方面的体验&#xff0c;近几年的更新都不忘去优化这方面的体验。 从一开始仅在通知栏提醒已截屏&#xff0c;到 Android 11 支持在左下角生成截屏缩略图供编辑或分享&#xff0c;再到 Android 12 支持…

计算机图形学 | 变换与观察

计算机图形学 | 变换与观察计算机图形学 | 变换与观察6.1 神奇的齐次坐标回顾几何阶段几何变换平移比例旋转对称错切齐次坐标的引入齐次坐标的概念和相关问题基于齐次坐标的变换6.2 三维模型&#xff0c;动起来&#xff01;基本三维变换平移比例旋转对称错切整体比例变换逆变换…

《计算机网络——自顶向下方法》精炼——1.4到1.7

三更灯火五更鸡&#xff0c;努力学习永不止。无惧困难与挑战&#xff0c;砥砺前行向成功。 文章目录引言正文时延排队时延吞吐量协议层次&#xff0c;服务模型&#xff08;重点&#xff09;封装&#xff08;重点&#xff09;网络安全&#xff08;选看&#xff09;恶意软件的分类…

【数据分析与挖掘】数据预处理

目录概述一、数据清洗1.1 缺失值处理1.1.1 拉格朗日插值法1.1.2 牛顿插值法1.2 异常值处理二、数据集成2.1 实体识别2.2 冗余属性识别三、数据变换3.1 简单函数变换3.2 规范化3.3 连续属性离散化3.4 属性构造3.5 小波变换四、数据规约4.1 属性规约4.2 数值规约概述 数据挖掘过…

Spring Boot中使用Redis

目录 1.依赖 2.依赖关系 3.配置 4.RedisTemplate 5.基础操作 6.事务 1.依赖 maven依赖如下&#xff0c;需要说明的是&#xff0c;spring-boot-starter-data-redis里默认是使用lettuce作为redis客户端的驱动&#xff0c;但是lettuce其实用的比较少&#xff0c;我们常用的…

如何在 Web 实现支持虚拟背景的视频会议

前言 众所周知&#xff0c;市面上有比如飞书会议、腾讯会议等实现视频会议功能的应用&#xff0c;而且随着这几年大环境的影响&#xff0c;远程协作办公越来越成为常态&#xff0c;关于视频会议的应用也会越来越多&#xff0c;且在远程办公的沟通协作中对沟通软件的使用要求会…

ARMv8-A非对齐数据访问支持(Alignment support)

目录 1&#xff0c;对齐传输和非对齐传输 2&#xff0c;AArch32 Alignment support 2.1 Instruction alignment 指令对齐 2.2 Unaligned data access 非对齐数据访问 2.3 SCTLR.A Alignment check enable 3&#xff0c;AArch64 Alignment support 3.1 Instruction align…

Text to image论文精读GigaGAN: 生成对抗网络仍然是文本生成图像的可行选择

GigaGAN是Adobe和卡内基梅隆大学学者们提出的一种新的GAN架构&#xff0c;作者设计了一种新的GAN架构&#xff0c;推理速度、合成高分辨率、扩展性都极其有优势&#xff0c;其证明GAN仍然是文本生成图像的可行选择之一。 文章链接&#xff1a;https://arxiv.org/abs/2303.0551…

大数据周会-本周学习内容总结07

目录 01【hadoop】 1.1【编写集群分发脚本xsync】 1.2【集群部署规划】 1.3【Hadoop集群启停脚本】 02【HDFS】 2.1【HDFS的API操作】 03【MapReduce】 3.1【P077- WordCount案例】 3.2【P097-自定义分区案例】 历史总结 01【hadoop】 1.1【编写集群分发脚本xsync】…

【vue3】关于ref、toRef、toRefs那些事

&#x1f609;博主&#xff1a;初映CY的前说(前端领域) &#x1f4d2;本文核心&#xff1a;ref、toRef、toRefs的使用方法 【前言】我们在上一节的学习当中&#xff0c;使用了reactive()函数将vue3中的数据变成响应式的数据&#xff0c;本文中所讲的三个方法也能实现将数据转化…

安全防御之IPsec VPN篇

目录 1.什么是数据认证&#xff0c;有什么用&#xff0c;有哪些实现的技术手段&#xff1f; 2.什么是身份认证&#xff0c;有什么用&#xff0c;有哪些实现的技术手段&#xff1f; 3.什么是VPN技术&#xff1f; 4.VPN技术有哪些分类&#xff1f; 5.IPsec技术能够提供哪些安…

走进小程序【八】微信小程序中使用【Vant组件库】

文章目录&#x1f31f;前言&#x1f31f;Vant介绍&#x1f31f;Vant安装&#x1f31f;npm 支持&#x1f31f;使用Vant&#x1f31f;引入组件&#x1f31f;页面使用组件&#x1f31f;样式覆盖&#x1f31f;介绍&#x1f31f;解除样式隔离&#x1f31f;使用外部样式类&#x1f31…

基于冯洛伊曼拓扑的鲸鱼算法用于滚动轴承的故障诊断研究(Matlab代码实现)

&#x1f468;‍&#x1f393;个人主页&#xff1a;研学社的博客&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5;&#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密…

【YOLO】YOLOv8实操:环境配置/自定义数据集准备/模型训练/预测

YOLOv8实操&#xff1a;环境配置/自定义数据集准备/模型训练/预测引言1 环境配置2 数据集准备3 模型训练4 模型预测引言 源码链接&#xff1a;https://github.com/ultralytics/ultralytics yolov8和yolov5是同一作者&#xff0c;相比yolov5&#xff0c;yolov8的集成性更好了&a…

C++面向对象丨1. 内存分区模型

Author&#xff1a;AXYZdong 硕士在读 工科男 有一点思考&#xff0c;有一点想法&#xff0c;有一点理性&#xff01; 定个小小目标&#xff0c;努力成为习惯&#xff01;在最美的年华遇见更好的自己&#xff01; CSDNAXYZdong&#xff0c;CSDN首发&#xff0c;AXYZdong原创 唯…

图解NLP模型发展:从RNN到Transformer

图解NLP模型发展&#xff1a;从RNN到Transformer 自然语言处理 (NLP) 是深度学习中一个颇具挑战的问题&#xff0c;与图像识别和计算机视觉问题不同&#xff0c;自然语言本身没有良好的向量或矩阵结构&#xff0c;且原始单词的含义也不像像素值那么确定和容易表示。一般我们需…

【随笔记】Win11、RTX3070、CUDA117的深度学习机器学习环境配置

文章目录一、创建深度学习 Conda 虚拟环境二、安装 Pytorch-Gpu三、安装 PyTorch Geometric四、安装 Sklearn五、Jupyter 配置5.1 将虚拟环境加入内核5.2 插件配置5.3 主题、字体、字号配置假设你已经安装了Anaconda3&#xff08;最新Anaconda3的安装配置及使用教程&#xff08…

里程碑,ChatGPT插件影响几何?

目录插件发布网络浏览器代码解释器平台生态微软魄力总结3月15日OpenAI推出了GPT-4&#xff0c;引起了全球轰动&#xff0c;仅仅过去一周多时间&#xff0c;OpenAI又宣布推出插件功能。如果说ChatGPT是AI的“iPhone时刻”&#xff0c;那么插件就是ChatGPT的“App Store”。超强的…

SpringBoot整合Flink(施耐德PLC物联网信息采集)

SpringBoot整合Flink&#xff08;施耐德PLC物联网信息采集&#xff09;Linux环境安装kafka前情&#xff1a;施耐德PLC设备&#xff08;TM200C16R&#xff09;设置好信息采集程序&#xff0c;连接局域网&#xff0c;SpringBoot订阅MQTT主题&#xff0c;消息转至kafka&#xff0c…

【chatgpt-01】部署学术神器chatgpt_academic

目录1 chatgpt_academic简介2 前置准备3 项目下载/配置4 安装依赖5 项目配置6 运行7 测试实验性功能1 chatgpt_academic简介 chatgpt_academic是一个科研工作专用ChatGPT拓展&#xff0c;特别优化学术Paper润色体验&#xff0c;支持自定义快捷按钮&#xff0c;支持markdown表格…