【OpenCV-Python】教程:4-4 SIFT 介绍

news2024/11/16 19:52:59

OpenCV Python SIFT (尺度不变特征变换)

【目标】

  • SIFT算法
  • SIFT特征点和描述子

【理论】

前面的章节中,我们提到了角点检测,例如Harris角点,他们是旋转不变的,因为,图像无论如何旋转,其角点特性不会发生改变,所以这类特征也称为旋转不变特征。但是如果图像缩放,原本在小图像中一定的窗口下是角点,放大后,却是平坦区域,即不是角点。如下图:

在这里插入图片描述

D.Lowe, Distinctive Image Features from Scale-Invariant Keypoints

步骤

1. 检测尺度空间的极值

从上图可以看出,我们不能用同样的窗口来检测不同尺度的关键点,对于小角点是可以的。,但为了探测更大的拐角,我们需要更大的窗口。为此,使用尺度空间过滤。文中给出了不同 σ σ σ值的高斯拉普拉斯(LoG)算子应用于图像。LoG作为一个blob检测器,它检测由于 σ σ σ变化而产生的各种大小的blob。简而言之, σ σ σ作为一个尺度参数。例如上图中, σ σ σ值低的高斯核对于小角的值较高,而 σ σ σ值高的高斯核对于大拐角的值较好。因此,我们可以在尺度和空间上找到局部极大值,这给了我们一个 ( x , y , σ ) (x,y, σ) (x,y,σ)值的列表,这意味着在 σ σ σ尺度上 ( x , y ) (x,y) (x,y)有一个潜在的关键点。

但是这个LoG还是比较耗时的,所以SIFT算法使用了近似于LoG的高斯差分。高斯差分图像是通过使用不同的 σ \sigma σ对图像进行模糊得到的高斯模糊图像再进行差分获得。分别设它们为 σ σ σ k σ kσ kσ。这一过程是对不同阶数的高斯金字塔图像进行的。如下图所示:

在这里插入图片描述

一旦完成了DoG计算,就会在图像的不同尺度和空间上搜索局部极值,例如,一个像素会与当前尺度的8邻域、上一尺度的9个像素和下一个尺度的9个像素进行比较,如果是局部极值,这就有可能是关键点,如下图所示

在这里插入图片描述

针对不同的参数,本文给出了一些经验数据,可归纳为:高斯金字塔层级数: 4 4 4, 每一层的尺度数 5 5 5, 初始 σ = 1.6 \sigma=1.6 σ=1.6, k = 2 k=\sqrt{2} k=2 等等。

2. 关键点定位

一旦找到了潜在的关键点位置,就必须对其进行细化以获得更准确的结果。他们使用尺度空间的泰勒级数展开来获得更准确的极值位置,如果该极值处的强度小于阈值(根据论文的说法为0.03),则会被拒绝。这个阈值在OpenCV中称为contrastThreshold

DoG对边缘有较高的响应,因此也需要去除边缘。为此,使用了类似于Harris 角点检测器的概念。他们使用2x2 Hessian 矩阵(H)来计算主曲率。我们从 Harris 角点检测器得知,对于边,一个特征值比另一个大。这里他们用了一个简单的函数,

如果这个比值大于一个阈值 ( OpenCV 中称为 edgeThreshold ),则该关键点将被丢弃。论文中是10

因此,它消除了任何低对比度的关键点和边缘关键点,剩下的是强烈的兴趣点。

3. 定向分配

现在为每个关键点分配方向,以实现图像旋转的不变性。根据尺度在关键点位置周围取邻域,并在该区域内计算梯度大小和方向。创建36个 bins 覆盖 360度 的梯度方向直方图(采用梯度幅值和高斯加权圆窗口加权, σ σ σ 等于关键点尺度的1.5倍)。取直方图中最高的峰值,任何超过其 80% 的峰值也被视为计算方向。它创建的关键点具有相同的位置和尺度,但方向不同。它有助于匹配的稳定性。

4. 关键点描述

现在关键点描述子已经创建。取关键点邻域的 16*16 区域,它被分为164x4 大小的子块。对于每个子块,创建8个bin 方向直方图。所以总共有128个 bin 值可用。将其表示为一个向量,形成关键点描述子。除此之外,还采取了一些措施来实现对光照变化、旋转等的鲁棒性。

5. 关键点匹配

两个图像之间的关键点通过识别它们最近的邻居来匹配。但在某些情况下,第二个最接近的匹配可能非常接近第一个。这可能是由于噪音或其他原因造成的。在这种情况下,取最近距离与次近距离的比值。如果大于0.8,则拒绝它们。根据这篇论文,它消除了大约90%的错误匹配,而只丢弃了5%的正确匹配。

这是对SIFT算法的总结。要了解更多细节和理解,强烈建议阅读原文。

【代码】

在这里插入图片描述

在这里插入图片描述

import numpy
import cv2 

# 读图像
img = cv2.imread("assets/home.jpg")
img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

# 创建 SIFT 检测器
sift = cv2.SIFT_create()

# 检测 SIFT 关键点
kp = sift.detect(img_gray, None)

# 另一种:检测 SIFT 关键点并 计算特征描述
# kp, descriptors = sift.detectAndCompute(img_gray, None)

# 画出所有关键点
# img = cv2.drawKeypoints(img_gray, kp, img)
# 画出尺度方向等丰富的信息
img = cv2.drawKeypoints(img_gray, kp, img, flags=cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS)

cv2.imshow("result", img)
cv2.waitKey(0)
cv2.destroyAllWindows()

【接口】

  • SIFT_create
cv2.SIFT_create(	[, nfeatures[, nOctaveLayers[, contrastThreshold[, edgeThreshold[, sigma]]]]]	) ->	retval
cv2.SIFT_create(	nfeatures, nOctaveLayers, contrastThreshold, edgeThreshold, sigma, descriptorType	) ->	retval

创建 SIFT 检测器

  • nfeatures: 最好关键点的数量,SIFT里用局部对比度作为排序的分数。
  • nOctaveLayers: 每一个金字塔层级里 层的数量,论文中为 3; 金字塔层级根据图像分辨率自动推导。
  • contrastThreshold: 对比度阈值,过滤那些对比度比较小的关键点,阈值越大,剩下的关键点越少。
  • edgeThreshold: 用于过滤那些类似边缘的特征。不同于 contrastThreshold,阈值越大,过滤的越少。
  • sigma: 在原始图像中 高斯核的 sigma, 如果图像质量较差,减小该数值。
  • descriptorType: 描述子类型。
  • detect
detect(	image[, mask]	) ->	keypoints
detect(	images[, masks]	) ->	keypoints

在应用的时候,根据 SIFT_Create创建的对象,再调用detect 检测关键点

  • image: 待检测的图像;
  • keypoints: 检测到的关键点,
  • mask: 掩码图像,ROI
  • compute
compute(	image, keypoints[, descriptors]	) ->	keypoints, descriptors
compute(	images, keypoints[, descriptors]	) ->	keypoints, descriptors

在应用的时候,根据 SIFT_Create创建的对象,再调用compute 检测关键点

  • image: 待计算的图像
  • keypoints: 输入的关键点,关键点因为无法计算特征的时候被删除,也可以添加;
  • descriptors: 计算的特征描述
  • detectAndCompute
detectAndCompute(	image, mask[, descriptors[, useProvidedKeypoints]]	) ->	keypoints, descriptors

检测关键点,并计算特征描述,参数描述见上述两个函数。

  • drawKeypoints
cv2.drawKeypoints(	image, keypoints, outImage[, color[, flags]]	) ->	outImage

绘制关键点

  • image: 源图像
  • keypoints: 源图像对应的关键点
  • outImage: 输出的图像,
  • color: 颜色
  • flags: Python API, flags are modified as cv2.DRAW_MATCHES_FLAGS_DEFAULT, cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS, cv2.DRAW_MATCHES_FLAGS_DRAW_OVER_OUTIMG, cv2.DRAW_MATCHES_FLAGS_NOT_DRAW_SINGLE_POINTS
  • cv2.KeyPoint 类的属性
  • angle: float
  • class_id: int, 类别
  • octave: int, 金字塔层级
  • pt: Point2f,坐标点
  • response: float 响应值
  • size: float 有效邻域尺寸

【参考】

  1. OpenCV官方文档
  2. DoG和LoG算子
  3. David G. Lowe. Distinctive image features from scale-invariant keypoints. Int. J. Comput. Vision, 60(2):91–110, November 2004.

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

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

相关文章

世界杯8强盘点

2022年卡塔尔世界杯(英语:FIFA World Cup Qatar 2022)是第二十二届世界杯足球赛,是历史上首次在卡塔尔和中东国家境内举行、也是第二次在亚洲举行的世界杯足球赛。除此之外,卡塔尔世界杯还是首次在北半球冬季举行、首次…

docker(八)compose

compose 一 简介: 通过前面几篇文章,我们了解了docker的基本知识,docker帮我们解决了服务打包安装的问题,但是随着服务的不断增多带来了如下问题: 多次使用Dockerfile Build Image或者DockerHub拉取Image;需要创建多…

Spark 动态资源分配参数与源码原理分析

1.1.1、Dynamic Allocation 1.1.1.1 参数说明 1.2 版本 参数名及默认值含义spark.dynamicAllocation.enabled false是否开启动态资源分配,主要是基于集群负载分配executorspark.dynamicAllocation.executorIdleTimeout60sexecutor空闲时间达到规定值&#xff0c…

程序人生:化解互联网 “寒冬” 危机,我教你摆脱困境

三年反复的yi情,近20年史无前例的互联网裁员潮汹涌而至。 寒冬来袭,每一个职场打工人,都感到了寒意。 互联网企业大裁员的底层逻辑,一方面是受宏观环境影响(yq、互联网红利结束、政策变化等),…

ChatGPT震撼上市,AI也开始跟你卷了,来一起看看怎么用ChatGPT!!!

强大AI产品,ChatGPT震撼上市,程序员真的要失业了吗? 最近聊天机器人异常火爆,火爆到什么程度,卖个关子,下文解释。 OpenAI推出了ChatGPT,它能够回答各种各样的问题,包括生成代码&a…

Node.js学习下(70th)

一、Buffer 缓冲区 背景 1、浏览器没有储存图片文件等媒体文件的需求,JS 存的都是一些基本数据类型。 2、服务器需要存储图片/视频/音频等媒体文件,因此有了 Buffer 缓冲器。 1. Buffer 是什么 Buffer 是一个和数组类似的对象,不同是 Buf…

python代码学习1

\n 换行符号 \r 回车 \b 后退一个格 \t 制表符(4个字符为一组,当不字符被占有时,重新生成一个制表符。如果被占据,不满4个字符时,生成剩余部分空格。) #原字符 不希望字符串中转义字符起作用&#xff0…

FME Server 无代码环境中自动化您数据和应用集成工作流

专为现代企业打造 简化数据和应用程序集成,让您的数据为您所用。在FME Desktop中创作工作流,并使用 FME Server 将其自动化,以按计划或响应事件运行数据集成。 构建无代码 Web 应用程序,提供自助式数据提交和验证,并向…

Java学习之动态绑定机制

目录 举例说明 父类 子类 main类 运行结果 ​编辑 动态绑定 举例说明 父类 子类 main类 分析 运行结果 Java重要特性:动态绑定机制(非常重要) 举例说明 父类 class A {//父类public int i 10;public int sum() {return getI(…

2022年11月国产数据库大事记-墨天轮

本文为墨天轮社区整理的2022年11月国产数据库大事件和重要产品发布消息。 文章目录11月国产数据库大事记(时间线)产品/版本发布兼容认证排行榜新增数据库11月国产数据库大事记(时间线) 11月1日,国际知名研究机构 IDC …

什么是内存对齐

内存对齐 什么是内存对齐为什么要内存对齐内存对齐的规则结构体中内存对齐 sizeof无嵌套有嵌套 iOS中对象内存对齐 iOS中获取内存大小方式 class_getInstanceSize()malloc_size() iOS中内存对齐 实际占用内存对齐方式系统分配内存对齐方式问题 内存优化 总结 内存对齐 什么…

基于C++的AGV机器人无线控制

1 AGV系统概述 1.1AGV原理 AGV行走控制系统由控制面板、导向传感器、方向电位器、状态指示灯、避障传感器、光电控制信号传感器、驱动单元、导引磁条、电源组成。 AGV的导引(Guidance)是指根据AGV导向传感器(Navigation)所得到…

基于FFmpeg进行rtsp推流及拉流(详细教程)

目录 1.1 Windows系统 1.2 Ubuntu 和 Debian 系统 1.3 CentOS 和 Fedora 系统 1.4 macOS系统 2. 安装rtsp-simple-server 3. FFmpeg推流 3.1 UDP推流 3.2 TCP推流 3.3 循环推流 4 拉流 4.1 ffplay/VLC拉流显示 4.2 FFmpeg拉流保存成视频 1. 安装FFmpeg FFmpeg 是一…

tftp服务/nfs服务/二进制工具集/uboot基础

一、什么是系统移植 1)系统移植就是给开发板搭建一个linux操作系统 2)从官方获取源码,进行配置和编译,生成板子需要的镜像文件 二、为什么系统移植 1)为后面学习驱动开发课程打基础 2)驱动开发工程师必…

入行4年,跳槽2次,在软件测试这一行我已经悟了!

近年来,软件测试行业如火如荼。互联网及许多传统公司对于软件测试人员的需求缺口逐年增大。然而,20年的疫情导致大规模裁员,让人觉得行业寒冬已经到来。软件测试人员的职业规划值得我们深思。 大家对软件测试行业比较看好,只是因…

【云服务器 ECS 实战】专有网络 VPC、弹性网卡的概述与配置

一、ECS 专有网络 VPC1. 传统经典网络与专有网络 VPC 对比2. 建立自己的专有网络 VPC二、弹性网卡1. 弹性网卡的概念与优势2. 弹性网卡的配置一、ECS 专有网络 VPC 阿里云在早期使用的是一种传统的网络模式,将所有的 ECS 云服务直接建立在传统网络层之上&#xff0…

【有营养的算法笔记】归并排序

👑作者主页:进击的安度因 🏠学习社区:进击的安度因(个人社区) 📖专栏链接:有营养的算法笔记 文章目录一、思路二、模板讲解三、模板测试四、加练 —— 逆序对的数量今天讲解的内容是…

[附源码]Python计算机毕业设计SSM加油站管理信息系统(程序+LW)

项目运行 环境配置: Jdk1.8 Tomcat7.0 Mysql HBuilderX(Webstorm也行) Eclispe(IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持)。 项目技术: SSM mybatis Maven Vue 等等组成,B/S模式 M…

【论文笔记】InverseForm: A Loss Function for Structured Boundary-Aware Segmentation

论文 标题:InverseForm: A Loss Function for Structured Boundary-Aware Segmentation 收录于:CVPR 2021 论文:[2104.02745] InverseForm: A Loss Function for Structured Boundary-Aware Segmentation (arxiv.org) 代码:Git…

大数据都应用在哪些领域?

大数据被应用较多的领域有哪些?疫情期间大数据技术对于疫情的防控发挥了巨大的作用,抗疫期间多家互联网企业纷纷加强大数据在疫情防控中的应用。小到社区大到部委相关部门都将大数据作为不可或缺的防疫工具,生活中很多方面涉及到大数据由此可…