【OpenCV 例程 300篇】256. 特征检测之 CenSurE(StarDetector)算法

news2024/10/5 12:54:19

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


【youcans 的 OpenCV 例程 300篇】256. 特征检测之 CenSurE(StarDetector)算法


6.9.1 算法简介

中心环绕算法(Center Surround Extremas, CenSurE)是 Agrawal M 等于 2008年提出的关键点检测算法,具有尺度不变性,计算效率高,特征点坐标精确,性能良好,可以实时实现。

SIFT 和 SURF算法都是利用 Hessian 矩阵的行列式作为检测判据。Harris 和 Hessian 本质上是角探测器,善于在某个尺度上检测定位,但在尺度变化时并不稳健。而拉普拉斯算子在不同尺度上的最大值可以获取特征尺度,一些算法选择设计更高效的拉普拉斯梯度(LoG)模板,SIFT 算法中使用 DoG 近似 LoG,SURF 使用 Box 近似高斯梯度模板(以DoB代替DoG),CenSurE 则使用环形函数的梯度模板,DART 使用分片三角函数模板。

在 CenSurE 算法中,在所有位置和所有尺度计算简化的中心环绕滤波器,并在局部邻域中找到极值。

Agrawal 文中设计了如图的 4种环形梯度滤波器模板,圆形核近似 LoG 的性能最好,但计算复杂度太高。其它3种滤波器都可以使用积分图像快速计算,其中方形核 boxes 的计算效率最高,但其旋转不变性也最差;八边形的性能最好,计算速度也较快。

在这里插入图片描述

中心环绕算法 CenSurE 的重要特点是不构造图像金字塔,而是用不同尺度的检测器对原始图像进行检测,就可以检测出不同尺度的关键点。将圆形 BLoG中的内外圆替换为内外正方形,构造 CenSurE_DoB,产生基本的中心环绕 Haar 小波。

CenSurE 算法使用 7个尺度递增的检测器构建尺度空间 n=[1, 2, 3, 4, 5, 6, 7]。对应于不同尺度 n 的 CenSurE_DoB 滤波器的内外正方形的边长分别为 2 ∗ n + 1 2*n+1 2n+1 4 ∗ n + 1 4*n+1 4n+1。检测特征的最小尺度对应于边长为 2 的方块,相当于 σ = 1.885 \sigma=1.885 σ=1.885 的 LoG检测器。这 5个不同的检测尺度覆盖了 2.5 个倍频程,而且可以很容易地扩展到更大的检测尺度范围。

CenSurE_DoB 滤波器可以使用倾斜积分图实现快速计算,即旋转45度的像素值积分图像:
t i t l e d ( X , Y ) = ∑ y < Y , a b s ( x − X + 1 ) ≤ Y − y − 1 i m a g e ( x , y ) titled(X, Y) = \sum_{y<Y,abs(x-X+1)\le Y-y-1}image(x,y) titled(X,Y)=y<Y,abs(xX+1)Yy1image(x,y)
CenSurE 特征检测由三个步骤组成:

(1)使用倾斜积分图像,计算近似高斯差分(以DoB代替DoG);

(2)采用非极大值抑制,检测局部极大值;

(3)基于 Harris 边缘滤波器,剔除边缘上的不稳定特征点。

CenSurE 特征可以直接使用 SURF 描述符,而 MU-SURF 描述符的性能更好。


6.9.2 OpenCV 中的 cv::StarDetector 类

OpenCV 中实现的 CenSurE 算法称为 STAR 算法,对 CenSurE 算法进行了一些改进。

(1)STAR 滤波器的形状是两个交错重叠的正方形,构成一个八角形。

在这里插入图片描述

(2)STAR 算法选择 17个尺度递增的检测器 n=[1, 2, 3, 4, 6, 8, 11, 12, 16, 23, 32, 45, 46, 64, 90, 128],构成 17个不同尺寸的八角形,按下表形成 12个不同尺寸的滤波器。

尺度123456789101112
外核尺寸246812162232466490128
内核尺寸023468111623324564

(3)滤波器的卷积运算基于积分图像,但没有直接计算八角形内地灰度和,而是分别用积分图像和双倾斜积分图像分别计算后相加。

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

StarDetector 类的构造函数为:

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)
static Ptr<StarDetector> cv::xfeatures2d::StarDetector::create(int maxSize = 45, int responseThreshold = 30, int lineThresholdProjected = 10, int lineThresholdBinarized = 8,
int suppressNonmaxSize = 5)

在 Python 语言中,OpenCV 提供了接口函数 cv.xfeatures2d.StarDetector.create, 实例化 StarDetector 类。

cv.xfeatures2d.StarDetector.create(	[, maxSize=45, responseThreshold=30, lineThresholdProjected=10, lineThresholdBinarized=8, suppressNonmaxSize=5]	) → retval
cv.xfeatures2d.StarDetector_create(	[, maxSize=45, responseThreshold=30, lineThresholdProjected=10, lineThresholdBinarized=8, suppressNonmaxSize=5]	) → retval
star.detect(image[, mask]) → keypoints

参数说明:

  • maxSize:使用滤波器的最大尺寸,默认值为 45,可选值为 4, 6, 8, 11, 12, 16, 23, 32, 45, 46, 64, 90, 128
  • responseThreshold:非最大值抑制中的阈值,默认值为 30
  • lineThresholdProjected:直线抑制中的阈值,默认值为 10
  • lineThresholdBinarized:直线抑制中尺寸矩阵的阈值,默认值为 8
  • suppressNonmaxSize:非极大值抑制的邻域范围,默认值为 5
  • image:输入图像,单通道。
  • mask:掩模图像,指定查找关键点的区域,可选项。
  • keypoints:检测到的关键点,元组。
  • descriptors:关键点的描述符,形为(nfeatures,32)的Numpy数组。

注意事项:

  • ⑴ 通过接口函数cv.xfeatures2d.StarDetector.create或cv.xfeatures2d.StarDetector_create实例化StarDetector类,在OpenCV的不同版本中可能只允许其中一种方式。

  • ⑵ OpenCV 中的StarDetector类是特征点检测算法,并不涉及特征描述符的构造,因此不能使用Feature2D类中的compute、detectAndCompute等计算特征描述符的成员函数。


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

# 14.28 特征检测之 StarDetector 算子
    # 读取基准图像
    imgRef = cv.imread("../images/Circuit04.png", flags=1)  # (480, 600, 3)
    refer = cv.cvtColor(imgRef, cv.COLOR_BGR2GRAY)  # 基准图像
    height, width = imgRef.shape[:2]  # 图片的高度和宽度
    print("shape of image: ", height, width)  # 480 600
    # 读取或构造目标图像
    top, left = int(0.1*height), int(0.1*width)
    border = cv.copyMakeBorder(imgRef, top, top, left, top, borderType=cv.BORDER_CONSTANT, value=(32,32,32))
    zoom = cv.resize(border, (width, height), interpolation=cv.INTER_AREA)
    theta= 10  # 顺时针旋转角度,单位为角度
    x0, y0 = width//2, height//2  # 以图像中心作为旋转中心
    MAR = cv.getRotationMatrix2D((x0,y0), theta, 1.0)
    imgObj = cv.warpAffine(zoom, MAR, (width, height))  # 旋转变换,默认为黑色填充
    # imgObj = cv.imread("../images/Circuit04B.png", flags=1)  # (480, 600, 3)
    object = cv.cvtColor(imgObj, cv.COLOR_BGR2GRAY)  # 目标图像
    print("shape of image: ", imgObj.shape)  # (480, 600, 3)

    # STAR 关键点检测
    star = cv.xfeatures2d.StarDetector_create()  # STAR 特征检测
    brief = cv.xfeatures2d.BriefDescriptorExtractor_create()  # BRIEF 特征描述
    kpStarRef = star.detect(imgRef, None)  # STAR 基准图像关键点检测
    kpStarObj = star.detect(imgObj, None)  # STAR 目标图像关键点检测
    # BRIEF 特征描述
    kpStarRef, desBriefRef = brief.compute(imgRef, kpStarRef)  # 通过 BRIEF 计算描述子
    kpStarObj, desBriefObj = brief.compute(imgObj, kpStarObj)  # 通过 BRIEF 计算描述子

    # 特征点匹配,Brute-force matcher
    matcher = cv.BFMatcher()  # 构造 BFmatcher 对象
    matches = matcher.match(desBriefRef, desBriefObj)  # 对描述子 des1, des2 进行匹配
    matches = sorted(matches, key=lambda x: x.distance)
    matches1 = cv.drawMatches(imgRef, kpStarRef, imgObj, kpStarObj, matches[:100], None, flags=2)
    print('queryIdx=%d' % matches[0].queryIdx)
    print('trainIdx=%d' % matches[0].trainIdx)
    print('distance=%d' % matches[0].distance)
    print("bf.match:{}".format(len(matches)))

    imgRefStar = cv.drawKeypoints(imgRef, kpStarRef, None, flags=cv.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS)  # 绘制关键点大小和方向
    imgObjStar = cv.drawKeypoints(imgObj, kpStarObj, None, flags=cv.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS)  # 绘制关键点大小和方向
    print(desBriefRef.shape, desBriefObj.shape)

    plt.figure(figsize=(9, 6))
    ax1 = plt.subplot(212)
    ax1.set_title("Star detector & Brief descriptor")
    plt.imshow(cv.cvtColor(matches1, cv.COLOR_BGR2RGB)), plt.axis('off')
    ax2 = plt.subplot(221)
    plt.axis('off'), plt.imshow(cv.cvtColor(imgRefStar, cv.COLOR_BGR2RGB))
    ax2.set_title("Star keypoints (Ref)")
    ax3 = plt.subplot(222)
    plt.axis('off'), plt.imshow(cv.cvtColor(imgObjStar, cv.COLOR_BGR2RGB))
    ax3.set_title("Star keypoints (Obj)")
    plt.tight_layout()
    plt.show()

程序说明
程序运行结果如图所示。

在这里插入图片描述


参考文献: Motilal Agrawal, Kurt Konolige, and Morten Rufus Blas. Censure: Center surround extremas for realtime feature detection and matching. In Computer Vision–ECCV 2008, pages 102–115. Springer, 2008.

在这里插入图片描述

【本节完】

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

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

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

相关文章

K8S StatefulSet基本使用

K8S StatefulSet 清空K8S对象 为了避免之前学习的内容造成的影响&#xff0c;先手动把K8S集群中的所有对象清空&#xff0c;使用一个全新的环境来学习StatefulSet的基本使用。 查看对象 查看service对象 kubectl get services查看ReplicaSet对象 kubectl get rs查看Repli…

达梦数据库导入dmp文件

找到达梦数据库安装文件的bin目录按着Shift键&#xff0c;右键输入以下命令&#xff08;注意更改参数&#xff09;.\dimp DGYH(用户名)/DGYH(密码)127.0.0.1 FILEdmp所在文件夹路径\20230103.dmp fullY然后根据提示,写Y 或 N 回车即可注意&#xff1a;若导入成功&#xff0c;但…

Java9的新特性模块化(Module)

一、 模块化是什么&#xff1f; Java 9引入了模块化系统&#xff0c;称为"Java Platform Module System"&#xff08;JPMS&#xff09; 这个系统允许将Java程序分成模块&#xff0c;每个模块都有自己的规范&#xff0c;可以明确地声明它依赖于哪些其他模块&#xff…

小波分析在电力系统暂态信号处理中的应用

前面我们主要讲了小波分析在机械振动信号或者其他时间序列中的应用 基于小波包特征提取和随机森林的CWRU轴承数据集故障识别 - 哥廷根数学学派的文章 - 知乎 https://zhuanlan.zhihu.com/p/556172942 基于小波区间相关&#xff08;Interval-Dependent&#xff09;的信号降噪方…

nacos源码分析-心跳检测(服务端)

前言 前面我们讲了《nacos源码分析-服务注册(客户端)》 和 《nacos源码分析-服务注册(服务端)》&#xff0c;主要是讲的服务注册流程&#xff0c;本章节我们来讲服务心跳检测机制。 心跳续约客户端 其实我们在讲 nacos服务注册客户端的时候顺带就说了心跳&#xff0c;服务注…

iNav飞控AOCODARC-F7MINI固件编译

iNav飞控AOCODARC-F7MINI固件编译1. 编译目标&#xff08;AOCODARC-F7MINI&#xff09;2. 编译步骤Step 1 软件配置环境准备Step 2 获取开源代码Step 3 构建命令介绍Step 4 厂家目标板查询Step 5 目标固件编译Step 6 目标固件清理3. 参考资料iNav是一款非常出色的飞控航模开源软…

怎么恢复360删除的文件?360文件恢复,快速完成

日常生活和工作中&#xff0c;使用电脑总会保存着很多数据。其中有我们很多的文件&#xff0c;如果不小心删除了重要的文件&#xff0c;我们该怎么恢复呢&#xff1f; 很多人都喜欢在电脑上安装3 60安 全卫士&#xff0c;文件被误删&#xff0c;我们可以通过它来恢复数据。文件…

来看看我在CSDN上的好朋友们吧,看看有没有你

首先&#xff0c;感谢支持我的所有人&#xff0c;其次&#xff0c;感谢支持我的所有人&#xff0c;然后感谢支持我的所有人&#xff0c;最后&#xff0c;感谢支持我的所有人&#xff08;我这是废话吗&#xff1f;&#xff1f;&#xff1f;不是吧&#xff09; 今天就来看看我在…

基于transfomer架构的模型[GPT、BERT、VIT、ST、MAE等等]总结

Transformer首先我们来回顾一下Transformer模型架构图对于Transformer从宏观角度可以可以理解为6个Encoder6个Decoder组成各部分介绍输入部分主要就是词嵌入位置编码对于词嵌入比较简单&#xff0c;就是对一个句子里的每个词做一个嵌入操作映射到相应的维度。一般来说就是先把句…

一次非典型的Netty内存泄露案例复盘

背景 作为后端开发相信大家或多或少都接触过Nettty&#xff0c;说起Netty真实又爱又恨&#xff0c;因为基于它可以很简单的开发高性能的Java网络通信服务&#xff0c;但同时要是不小心就会出现各种奇奇怪怪的问题&#xff0c;特别是由于特殊的内存管理机制很容易出现内存泄漏问…

数据大佬的成长经验分享 | ​我的非典型数据分析之路

小飞象交流会哪有什么错过的人&#xff0c;会离开的都是路人。哪有什么命运不公&#xff0c;都是懒惰让你变得无能。内部交流│19期数据大佬的成长经验分享我的非典型数据分析之路data analysis●●●●分享人&#xff1a;夏宇‍在大数据、人工智能热、5G、物联网的时代&#x…

1、Mavan项目管理工具

1.1 什么是 Maven 1.1.1 什么是 Maven Maven 的正确发音是[ˈmevən]&#xff0c;而不是“马瘟”以及其他什么瘟。Maven 在美国是一个口语化的词 语&#xff0c;代表专家、内行的意思。 一个对 Maven 比较正式的定义是这么说的&#xff1a;Maven 是一个项目管理工具&#xff0…

Spring Boot学习篇(十)

Spring Boot学习篇(十) shiro安全框架使用篇(二)——登录实例(密码以密文方式存储,不含记住密码) 1.模拟注册时,生成密文到数据库中 1.1 在zlz包下创建util包,并在下面创建SHAUtil01类(初始里面无方法)和SHAUtil02类,其目录结构如下所示 1.2 两种生成密文的方式 1.2.1 自己…

一篇文章彻底搞懂折半查找法[二分查找法]算法~

算法实现的要求&#xff1a; 折半查找法又称为二分查找法&#xff0c;这种方法对待查找的列表有两个要求&#xff1a; 1&#xff1a;必须采用顺序存储结构 2&#xff1a;必须按关键字大小有序排列算法思想&#xff1a; 将表中间位置记录的关键字与查找关键字进行比较&#x…

性能测试时那些「难以启齿」的问题-CPU相关

NO.1 为什么cpu使用率可以>100%? 小白的我在进行压测的时候&#xff0c;查看服务的cpu总使用率如下&#xff0c;总使用率会超过100%&#xff0c;这个数据是怎么来的呢&#xff0c;为什么会有大于100%的情况呢&#xff1f; 作为小白的我刚开始觉得这个问题应该很基础&#x…

Go语言实现猜数字小游戏

目录 前言 一、设计思路 二、代码编写 2.1 产生随机数 2.2 用户输入数据 2.3 核心代码 三、 全部代码 四、效果图 总结 前言 最近在学习go语言&#xff0c;刚刚学完go语言的基础语法。编写了一个猜数字的小游戏来练习循环、分支语句、变量定义、输入输出等基础的go语…

4、变量与常量

目录 一、标识符和关键字 1.标识符 2.关键字 二、声明变量 三、声明常量 四、变量的有效范围 1. 成员变量 2. 局部变量 一、标识符和关键字 1.标识符 Java语言规定标识符由任意顺序的字母、下画线&#xff08;_&#xff09;、美元符号&#xff08;$&#xff09;和数字…

【数据结构】手撕八大排序算法

作者&#xff1a;一个喜欢猫咪的的程序员 专栏&#xff1a;《数据结构》 喜欢的话&#xff1a;世间因为少年的挺身而出&#xff0c;而更加瑰丽。 ——《人民日报》 目录 1.排序的概念&#xff1a; 2.八大排序的思路及其细节 2.1直接插入排序 …

适合编程初学者的开源项目:小游戏2048(安卓Compose版)

目标 为编程初学者打造入门学习项目&#xff0c;使用各种主流编程语言来实现。 2048游戏规则 一共16个单元格&#xff0c;初始时由2或者4构成。 1、手指向一个方向滑动&#xff0c;所有格子会向那个方向运动。 2、相同数字的两个格子&#xff0c;相遇时数字会相加。 3、每次…

SpringMVC面试题

概述 什么是Spring MVC&#xff1f;简单介绍下你对Spring MVC的理解&#xff1f; Spring MVC是一个基于Java的实现了MVC设计模式的请求驱动类型的轻量级Web框架&#xff0c;通过把模型-视图-控制器分离&#xff0c;将web层进行职责解耦&#xff0c;把复杂的web应用分成逻辑清…