基于OpenCv的图像SIFT特征点检测和特征匹配

2024-05-05 02:36

本文主要是介绍基于OpenCv的图像SIFT特征点检测和特征匹配,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

⚠申明: 未经许可,禁止以任何形式转载,若要引用,请标注链接地址。 全文共计3077字,阅读大概需要3分钟
🌈更多学习内容, 欢迎👏关注👀【文末】我的个人微信公众号:不懂开发的程序猿
个人网站:https://jerry-jy.co/

❗❗❗知识付费,🈲止白嫖,有需要请后台私信或【文末】个人微信公众号联系我

基于OpenCv的图像SIFT特征点检测和特征匹配

  • 基于OpenCv的图像SIFT特征点检测和特征匹配
    • 任务需求
    • 任务目标
      • 1、掌握SIFT特征点检测的简单步骤
      • 2、掌握基于OpenCv进行SIFT特征点检测
      • 3、掌握使用SIFT描述子进行蛮力匹配
    • 任务环境
      • 1、jupyter开发环境
      • 2、OpenCv
      • 3、python3.6
    • 任务实施过程
      • 一、SIFT特征点检测
        • 1.导入所需要的工具包和图像
        • 2.SIFT特征点检测
      • 二、特征匹配
        • 1.读入图像
        • 2.Brute-Force蛮力匹配
      • 三、任务小结
  • 说明

基于OpenCv的图像SIFT特征点检测和特征匹配

任务需求

SIFT是一种基于尺度空间的,对图像缩放、旋转甚至仿射变换保持不变性的图像局部特征描述算子。SIFT是迄今使用最为广泛的一种特征提取方法。
图像点特征能够代表图像的内容,所以在运动目标跟踪、物体识别、图像配准、全景图像的拼接、三维重建等方向中,图像特征点的提取都至关重要,特征点提取的好坏将直接决定目标跟踪、物体识别、图像匹配、图像拼接、三维重建的准确度。
例如下图为基于SIFT特征的全景图像拼接。

在这里插入图片描述

在这里插入图片描述

任务目标

1、掌握SIFT特征点检测的简单步骤

2、掌握基于OpenCv进行SIFT特征点检测

3、掌握使用SIFT描述子进行蛮力匹配

任务环境

1、jupyter开发环境

2、OpenCv

3、python3.6

任务实施过程

一、SIFT特征点检测

SIFT是一种基于尺度空间的,对图像缩放、旋转甚至仿射变换保持不变性的图像局部特征描述算子。

SIFT算法主要分为四个步骤:

  • 1.多尺度空间极值点检测:通过高斯金字塔构建高斯差分尺度空间(DOG),寻找尺度空间的极值点,中间的检测点要和其所在图像的上下两层和本层的3×3邻域26个像素点进行比较。
  • 2.特征点精确定位:对尺度空间DoG函数进行曲线拟合,计算其极值点,从而实现关键点的精确定位。
  • 3.特征点的主方向计算:使用直方图统计邻域内像素的梯度和方向,极值点周围区域方向梯度直方图的主峰值也就是特征点的主方向。
  • 4.生成特征点描述:对每个关键点使用16×16的窗口,4×4共16个种子点来描述,这样一个关键点就可以产生128维的SIFT特征向量。

在这里插入图片描述

1.导入所需要的工具包和图像
import cv2 # 导入opencv
import matplotlib.pyplot as plt # 导入绘图模块
import numpy as np # 导入numpy库
from utils import im_show # 导入显示图像函数
# 绘制图像直接展示,不用调用plt.show()
%matplotlib inline 
# 用来正常显示中文标签
plt.rc('font',family="SimHei")
# 读取图像
img = cv2.imread(r'./experiment/data/home.jpg')
# 设置画布大小
plt.figure(figsize=(6,6))
# 显示图像
im_show('原图像',img)

在这里插入图片描述

2.SIFT特征点检测

OpenCV获取SIFT特征点
sift = cv2.SIFT_create()/cv2.xfeatures2d.SIFT_create() 实例化

  • sift:实例化的sift函数

kp = sift.detect(gray, None) 找出图像中的关键点

  • kp:生成的关键点
  • gray:输入的灰度图

ret = cv2.drawKeypoints(gray, kp, img) 在图中画出关键点

  • gray:输入图片
  • kp:SIFT关键点
  • img:返回的图像

kp, dst = sift.compute(kp) 计算关键点对应的sift特征向量(128维)

  • kp:输入的关键点
  • dst:输出的sift特征向量,通常是128维的
# 先将图像转换为灰度图
gray= cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
# 创建SIFT特征点检测器
# 如果opencv版本号以4.4开头使用sift = cv2.SIFT_create()实例化
# 如果opencv版本号以4.3开头使用sift = cv2.xfeatures2d.SIFT_create()实例化
sift = cv2.SIFT_create()
# 找出关键点,放入灰度图gray
kp = sift.detect(gray, None)
# 这里得到的关键点不是坐标,默认情况下使封装好的类型,没办法直接从图上显示
# 使用drawKeypoints()函数绘制关键点
img1 = img.copy()
img1=cv2.drawKeypoints(gray,kp,img1)
img2 = img.copy()
# 设置drawKeypoints()函数中特征点的绘制模式
# flags=cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS表示它将绘制一个具有关键点大小的圆,并显示其方向。
img2=cv2.drawKeypoints(gray,kp,img2,flags=cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS)
plt.figure(figsize=(12,12))
# 显示SIFT检测的特征点和每一个特征点的坐标,size和方向
im_show('SIFT特征点检测',np.hstack((img1,img2)))

在这里插入图片描述

# 求得关键点对应的128个特征向量
kp, des = sift.compute(gray, kp)
print(np.shape(kp))
print(np.shape(des))

图像中提取到了3661个关键点。

在这里插入图片描述

二、特征匹配

原图像与目标图像通过SIFT特征提取生成特征描述子,然后将两图中各个尺度的描述子进行匹配。
依次找出两图中相似度最高的两个特征向量,完成对特征点的连线匹配。

1.读入图像
# 读取图像
ayst1 = cv2.imread(r'./experiment/data/ayst1.jpg')
ayst2 = cv2.imread(r'./experiment/data/ayst2.jpg')
# 设置画布大小
plt.figure(figsize=(12,12))
# 显示图像
plt.subplot(121)
im_show('待匹配图像1',ayst1)
plt.subplot(122)
im_show('待匹配图像1',ayst2)

在这里插入图片描述

2.Brute-Force蛮力匹配

蛮力匹配器:采用第一个特征一些距离计算与第二特征中的所有其它特征匹配,将最近的一个返回。

实现原理:

  • 两幅图片分别提取出来N,M个特征向量
  • 然对N和M的特征向量进行匹配,找到最佳匹配
  • 画出匹配的特征显示出来

OpenCV进行Brute-Force蛮力匹配
bf = cv2.BFMatcher(normType, crossCheck=False)创建BFMatcher对象,有两个可选参数:

  • normType:指定要使用的距离测量,默认情况下为cv.NORM_L2。对于SIFT,SURF等(也有cv.NORM_L1)很有用,对于基于二进制字符串的描述符,例如ORB,BRIEF,BRISK等,应使用cv.NORM_HAMMING,该函数使用汉明距离作为度量。如果ORB使用WTA_K == 3或4,则应使用cv.NORM_HAMMING2。
  • crossCheck:默认值为False,如果设置为True,匹配条件就会更加严格,只有到A中的第i个特征点与B中的第j个特征点距离最近,并且B中的第j个特征点到A中的第i个特征点也是最近时才会返回最佳匹配,即这两个特征点要互相匹配才行。

bf.match(queryDescriptors, trainDescriptors,…)/knnMatch(queryDescriptors, trainDescriptors,k,…)第一个返回最佳匹配, 第二种方法返回k个最佳匹配,其中k由用户指定。

  • queryDescriptors:特征描述子1
  • trainDescriptors:特征描述子2

cv2.drawMatchsKnn(img1,keypoints1,img2,keypoints2,matches1to2,…)如果前面使用的bf.knnMatch(),则可以使用函数cv2.drawMatchsKnn为每个关键点和它的个最佳匹配点绘制匹配线。

  • img1 :源图像1
  • keypoints1:源图像1的特征点.
  • img2:源图像2.
  • keypoints2:源图像2的特征点
  • matches1to2:源图像1的特征点匹配源图像2的特征点
# 初始化SIFT检测器
sift = cv2.SIFT_create()
# 使用SIFT寻找关键点和描述子
kp1, des1 = sift.detectAndCompute(ayst1,None)
kp2, des2 = sift.detectAndCompute(ayst2,None)
print('两个图像提取的SIFT关键点个数分别为:',len(kp1),len(kp2))
# 创建BFMatcher对象,使用默认参数做蛮力匹配
bf = cv2.BFMatcher()
# 进行匹配,放入两个图像的描述向量,设置k=2,一个特征点对应与它最佳匹配的2个特征点
matches = bf.knnMatch(des1,des2,k=2)
# 应用比率测试
good = []
# 使用for循环,设一个特征点对应的两个特征点的距离m和n
# 如果m<0.75n(m和n表示距离)表示距离相对较近,将满足条件的匹配保留下来
for m,n in matches:if m.distance < 0.75*n.distance:good.append([m])
# 使用KNN方法绘制匹配点,flags=0表示画特征点和连线,flags=2表示不画特征点。
img3 = cv2.drawMatchesKnn(ayst1,kp1,ayst2,kp2,good,None,flags=2)
# 设置画布大小
plt.figure(figsize=(12,12))
im_show('使用SIFT描述子的蛮力匹配',img3)

在这里插入图片描述

三、任务小结

本次实验主要完成基于OpenCv的SIFT特征点检测和使用SIFT描述子进行蛮力匹配。注意SIFT特征点检测的步骤和不同OpenCv版本号使用不同的代码创建SIFT特征点检测器。

通过本次实验需要掌握以下内容:

  • 1.掌握基于OpenCv进行SIFT特征点检测
  • 2.掌握使用SIFT描述子进行蛮力匹配
  • 3.掌握使用knnMatch()进行匹配

–end–

说明

本实验(项目)/论文若有需要,请后台私信或【文末】个人微信公众号联系我

这篇关于基于OpenCv的图像SIFT特征点检测和特征匹配的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/960637

相关文章

SpringBoot3匹配Mybatis3的错误与解决方案

《SpringBoot3匹配Mybatis3的错误与解决方案》文章指出SpringBoot3与MyBatis3兼容性问题,因未更新MyBatis-Plus依赖至SpringBoot3专用坐标,导致类冲... 目录SpringBoot3匹配MyBATis3的错误与解决mybatis在SpringBoot3如果

Python脚本轻松实现检测麦克风功能

《Python脚本轻松实现检测麦克风功能》在进行音频处理或开发需要使用麦克风的应用程序时,确保麦克风功能正常是非常重要的,本文将介绍一个简单的Python脚本,能够帮助我们检测本地麦克风的功能,需要的... 目录轻松检测麦克风功能脚本介绍一、python环境准备二、代码解析三、使用方法四、知识扩展轻松检测麦

OpenCV在Java中的完整集成指南分享

《OpenCV在Java中的完整集成指南分享》本文详解了在Java中集成OpenCV的方法,涵盖jar包导入、dll配置、JNI路径设置及跨平台兼容性处理,提供了图像处理、特征检测、实时视频分析等应用... 目录1. OpenCV简介与应用领域1.1 OpenCV的诞生与发展1.2 OpenCV的应用领域2

在Java中使用OpenCV实践

《在Java中使用OpenCV实践》用户分享了在Java项目中集成OpenCV4.10.0的实践经验,涵盖库简介、Windows安装、依赖配置及灰度图测试,强调其在图像处理领域的多功能性,并计划后续探... 目录前言一 、OpenCV1.简介2.下载与安装3.目录说明二、在Java项目中使用三 、测试1.测

基于Python开发一个图像水印批量添加工具

《基于Python开发一个图像水印批量添加工具》在当今数字化内容爆炸式增长的时代,图像版权保护已成为创作者和企业的核心需求,本方案将详细介绍一个基于PythonPIL库的工业级图像水印解决方案,有需要... 目录一、系统架构设计1.1 整体处理流程1.2 类结构设计(扩展版本)二、核心算法深入解析2.1 自

Linux系统性能检测命令详解

《Linux系统性能检测命令详解》本文介绍了Linux系统常用的监控命令(如top、vmstat、iostat、htop等)及其参数功能,涵盖进程状态、内存使用、磁盘I/O、系统负载等多维度资源监控,... 目录toppsuptimevmstatIOStatiotopslabtophtopdstatnmon

Python使用OpenCV实现获取视频时长的小工具

《Python使用OpenCV实现获取视频时长的小工具》在处理视频数据时,获取视频的时长是一项常见且基础的需求,本文将详细介绍如何使用Python和OpenCV获取视频时长,并对每一行代码进行深入解析... 目录一、代码实现二、代码解析1. 导入 OpenCV 库2. 定义获取视频时长的函数3. 打开视频文

C++ 检测文件大小和文件传输的方法示例详解

《C++检测文件大小和文件传输的方法示例详解》文章介绍了在C/C++中获取文件大小的三种方法,推荐使用stat()函数,并详细说明了如何设计一次性发送压缩包的结构体及传输流程,包含CRC校验和自动解... 目录检测文件的大小✅ 方法一:使用 stat() 函数(推荐)✅ 用法示例:✅ 方法二:使用 fsee

Python如何将OpenCV摄像头视频流通过浏览器播放

《Python如何将OpenCV摄像头视频流通过浏览器播放》:本文主要介绍Python如何将OpenCV摄像头视频流通过浏览器播放的问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完... 目录方法1:使用Flask + MJPEG流实现代码使用方法优点缺点方法2:使用WebSocket传输视

HTML5 中的<button>标签用法和特征

《HTML5中的<button>标签用法和特征》在HTML5中,button标签用于定义一个可点击的按钮,它是创建交互式网页的重要元素之一,本文将深入解析HTML5中的button标签,详细介绍其属... 目录引言<button> 标签的基本用法<button> 标签的属性typevaluedisabled