当前位置: 首页 > news >正文

计算机视觉与模式识别实验2-2 SIFT特征提取与匹配

文章目录

    • 🧡🧡实验流程🧡🧡
      • SIFT算法原理总结:
      • 实现SIFT特征检测和匹配
      • 通过RANSAC 实现图片拼接
      • 更换其他图片再次测试效果(依次进行SIFT特征提取、RANSAC 拼接)
    • 🧡🧡全部代码🧡🧡

🧡🧡实验流程🧡🧡

SIFT算法原理总结:

1.创建尺度空间:
高斯模糊去除噪声,强调了图像的重要特征
在这里插入图片描述
根据原图创建不同比例的新图像
在这里插入图片描述

2.采用高斯差异DOG增强特征
在这里插入图片描述
如下,对于某一比例的5张不同模糊程度的图像,进行差分
在这里插入图片描述

3.关键点定位(尺度不变性)
找出局部最大值和最小值(这里“局部”的含义:它不仅包括该图像的周围像素(像素所在的像素),还包括八度中上一张和下一张图像的九个像素)
这意味着将每个像素值与其他26个像素值进行比较,以确定是否为局部最大值/最小值。例如,在下图中,从第一个八度获得了三个图像。将标记为x的像素与相邻像素(绿色)进行比较,如果它是相邻像素中最高或最低的像素,则将其选择为关键点:
在这里插入图片描述
关键点的筛选
消除对比度低或非常靠近边缘的关键点:
采用二阶泰勒展开消除对比度低或非常靠近边缘的关键点、采用二阶Hessian矩阵来识别具有高边缘度但对少量噪点无鲁棒性的关键点

4.关键点方向分配(旋转不变性)
对于每个关键点和其周围的像素,都执行如下操作:
根据梯度计算幅度和方向,如下Gx=9,Gy=14则
在这里插入图片描述
在这里插入图片描述
随后创建大小和方向的柱状图
在这里插入图片描述

5.生成描述符
已经通过3、4生成了具有尺度不变性和旋转不变性的关键点,对于每个关键点,使用相邻像素,它们的方向和大小为该关键点生成一个唯一的指纹,称为“描述符”。

6.关键点匹配
使用描述子之间的距离或相似度度量来匹配不同图像中的关键点,通常采用最近邻或 k近邻方法来进行匹配。
(在opencv中,BFMatcher.match() 和BFMatcher.knnMatch(),第一个返回最佳匹配,第二个返回前k个最佳的匹配,k值由用户指定。)




实现SIFT特征检测和匹配

原始图像如下:
在这里插入图片描述

截出两个图像(分别截取前宽度的4/5和后4/5部分)
在这里插入图片描述

画出关键点
在这里插入图片描述

SIFT匹配(总共529个匹配,按连线长度升序,画出全部线)
在这里插入图片描述

为方便观察,画出按连线长度前100匹配的连线
在这里插入图片描述

将右侧图片旋转90度,重复上述步骤
在这里插入图片描述
在这里插入图片描述

将右侧图片旋转15度,并缩放到原图0.8倍,重复上述步骤
在这里插入图片描述
在这里插入图片描述




通过RANSAC 实现图片拼接

右侧图片正放
在这里插入图片描述
拼接结果:
在这里插入图片描述


右侧图片旋转90度
在这里插入图片描述
拼接结果:
在这里插入图片描述


右侧图片旋转15度并缩放到0.8倍
在这里插入图片描述
拼接结果:
在这里插入图片描述




更换其他图片再次测试效果(依次进行SIFT特征提取、RANSAC 拼接)

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

🧡🧡全部代码🧡🧡

import numpy as np
import cv2
from matplotlib import pyplot as plt
def cv_show(title,img):cv2.imshow(title, img)cv2.waitKey(0)cv2.destroyAllWindows()
"""SIFT 图像特征连接+ RANSAC拼接
"""def check_and_draw_KeyPoint(img1,img2):img1 = cv2.cvtColor(img1, cv2.COLOR_BGR2GRAY)img2 = cv2.cvtColor(img2, cv2.COLOR_BGR2GRAY)# Siftsift = cv2.SIFT_create()kp1, des1 = sift.detectAndCompute(img1,None)kp2, des2 = sift.detectAndCompute(img2,None)# len(kp1), len(kp2)# Draw KeyPointimgShow1 = cv2.drawKeypoints(img1,kp1,None,color=(255,0,255)) #画出特征点,并显示为红色圆圈imgShow2 = cv2.drawKeypoints(img2,kp2,None,color=(255,0,255)) #画出特征点,并显示为红色圆圈cv_show("KeyPoint", np.hstack((imgShow1, imgShow2)))return img1,img2,kp1,kp2,des1,des2def match_KeyPoint(img1,img2,kp1,kp2,des1,des2,show_line_num=100):# Feature Matchingbf = cv2.BFMatcher(cv2.NORM_L1, crossCheck=True)matches = bf.match(des1,des2)matches =sorted(matches, key=lambda x:x.distance)# print(len(matches))imgShow = cv2.drawMatches(img1, kp1, img2, kp2, matches[0:show_line_num], None, flags=2)cv_show("Match",imgShow)def concat_Image(img1,img2,kp1,kp2,des1,des2):# 匹配特征,并返回透视变换矩阵matcher = cv2.BFMatcher()rawMatches = matcher.knnMatch(des2, des1, 2)matches = []for m in rawMatches:if len(m) == 2 and m[0].distance < m[1].distance * 0.75:matches.append((m[0].trainIdx, m[0].queryIdx))kp1 = np.float32([kp.pt for kp in kp1])kp2 = np.float32([kp.pt for kp in kp2])if len(matches) > 4:ptsA = np.float32([kp2[i] for (_, i) in matches])ptsB = np.float32([kp1[i] for (i, _) in matches])(H, status) = cv2.findHomography(ptsA, ptsB, cv2.RANSAC, 4.0)result = cv2.warpPerspective(img2, H, (img2.shape[1] + img1.shape[1], img2.shape[0]))result[0:img1.shape[0], 0:img1.shape[1]] = img1cv_show("Concat Image",result)if __name__=="__main__":# Read Original Imageimage = cv2.imread('img/test2_Sift.jpg')height, width, _ = image.shapeimage = cv2.resize(image,(int(width*4/6),int(height*4/6))) # 图片有点宽,缩放一下height, width, _ = image.shape# 截取前4/5部分和后4/5部分img1 = image[:, 0 : int(width * 4 / 5)]img2 = image[:, int(width / 5) : width]img1 = cv2.imread("img/test2_river1.png")img2 = cv2.imread("img/test2_river2.png")# 可注释)图像转变2:img2旋转90度
#     img2 = cv2.rotate(img2, cv2.ROTATE_90_CLOCKWISE) # 旋转90度
#     img2 = cv2.resize(img2,(img2.shape[1], img1.shape[0]))# 可注释)图像转变3:img2旋转15度,并且缩放到0.9倍,同时img1设置跟img2同样高度,并且宽度按比例变换
#     center=(width/2,height/2)
#     angle=15
#     scale=0.8
#     M=cv2.getRotationMatrix2D(center,angle,scale)
#     img2=cv2.warpAffine(img2,M,(int(width),int(1.1*height)))
#     img1=cv2.resize(img1,(int(img1.shape[1]*img2.shape[0]/img1.shape[0]), img2.shape[0]))cv_show("spilt", np.hstack((img1, img2))) #拼接显示原图# 调用自定义函数img1,img2,kp1,kp2,des1,des2=check_and_draw_KeyPoint(img1,img2) # 检测并画出关键点match_KeyPoint(img1,img2,kp1,kp2,des1,des2, show_line_num=100) # 连接关键点concat_Image(img1,img2,kp1,kp2,des1,des2) # 拼接图像

相关文章:

计算机视觉与模式识别实验2-2 SIFT特征提取与匹配

文章目录 &#x1f9e1;&#x1f9e1;实验流程&#x1f9e1;&#x1f9e1;SIFT算法原理总结&#xff1a;实现SIFT特征检测和匹配通过RANSAC 实现图片拼接更换其他图片再次测试效果&#xff08;依次进行SIFT特征提取、RANSAC 拼接&#xff09; &#x1f9e1;&#x1f9e1;全部代…...

kerberos: Clock skew too great (37) - PROCESS_TGS

kerberos认证失败错误信息&#xff1a; Caused by: org.ietf.jgss.GSSException: No valid credentials provided (Mechanism level: Clock skew too great (37) - PROCESS_TGS)at sun.security.jgss.krb5.Krb5Context.initSecContext(Krb5Context.java:772)at sun.security.j…...

【MATLAB高级编程】入门篇 | 向量化编程

【入门篇】向量化编程 1. 什么是向量?2. 向量的创建2.1 行向量2.2 列向量2.3 使用冒号运算符2.4 使用`linspace`和`logspace`3. 向量的基本操作3.1 向量元素访问3.2 向量的长度3.3 向量的加法和减法3.4 向量的点乘和叉乘3.5 向量的元素乘法和除法4. 向量的高级操作4.1 逻辑索引…...

Debezium日常分享系列之:Debezium 2.7.0.Beta1发布

Debezium日常分享系列之&#xff1a;Debezium 2.7.0.Beta1发布 一、重大变化1.快照工件2.Oracle 二、新功能和改进1.在 z/OS 上支持 Db22.NATS JetStream 接收器身份验证改进3.JDBC 接收器 MariaDB 方言支持4.JMX 导出器添加到 Debezium 服务器5.使用 Debezium Operator 启用 J…...

eNSP学习——RIP的水平分割和触发更新

目录 主要命令 原理概述 实验目的 实验内容 实验拓扑 实验编址 实验步骤 1、基本配置 2、搭建RIP网络 3、验证触发更新 4&#xff0e;验证水平分割 5、验证毒性逆转 需要eNSP各种配置命令的点击链接自取&#xff1a;华为&#xff45;NSP各种设备配置命令大全PDF版_…...

华为面经整理

文章目录 实习第一面准备提问相关算法相关 第一面结果提问环节 总结 实习 第一面准备 提问相关 操作系统有哪些功能 进程管理&#xff1a; 进程调度、进程同步和通信、多任务处理 内存管理&#xff1a; 内存分配、虚拟内存技术、内存保护 文件系统管理&#xff1a; 文件存储…...

数据恢复工具推荐:电脑回收站删除的文件怎么恢复?8个回收站恢复软件,收藏!

当文件从电脑的回收站被删除后&#xff0c;许多用户可能认为这些文件已永久丢失。然而&#xff0c;实际上&#xff0c;在数据被新数据覆盖之前&#xff0c;这些删除的文件仍然可以通过使用专门的数据恢复软件来恢复。本文将介绍8款顶级的文件恢复软件&#xff0c;恢复电脑回收站…...

Java 执行字符串 GroovyShell

1...

前端之npm运行时配置文件.npmrc(可用于配置npm淘宝源)

文章目录 前端之npm运行时配置文件.npmrc什么是.npmrc设置项目配置文件设置用户配置文件设置全局配置文件给npm 命令添加注册源选项 前端之npm运行时配置文件.npmrc 什么是.npmrc 官网&#xff1a;https://nodejs.cn/npm/cli/v7/configuring-npm/npmrc/ .npmrc&#xff0c;可…...

如何充分利用代理IP扩大网络接触面

目录 前言 第一部分&#xff1a;什么是代理IP&#xff1f; 第二部分&#xff1a;如何获取代理IP&#xff1f; 1. IP质量 2. 匿名性 3. 限制 第三部分&#xff1a;如何使用代理IP&#xff1f; 第四部分&#xff1a;如何充分利用代理IP&#xff1f; 总结&#xff1a; 前…...

StableDiffusion Windows本地部署

检查电脑环境 启动CMD命令窗。 如上图&#xff0c;在CMD窗口输入python命令&#xff0c;可查看本地安装的python版本信息等。输入exit()退出python命令行 执行where命令&#xff0c;可查看python安装目录。 必须安装Python3.10.x&#xff0c;因为stable-diffusion-webui的一…...

OpenCV学习(4.5) 图像的形态转换

1.目标 在本教程中&#xff1a; 我们将学习不同的形态操作&#xff0c;如腐蚀、膨胀、开、闭等。我们将看到不同的函数&#xff0c;如&#xff1a; cv.erode()**、 **cv.dilate()**、 **cv.morphologyEx() 等。 理论&#xff1a; 图像的形态转换是图像处理中的一个重要领域…...

MFC设置窗口在Z轴上的位置

函数原型&#xff1a; BOOL CWnd::SetWindowPos(const CWnd* pWndInsertAfter, int x, int y, int cx, int cy, UINT nFlags);返回值&#xff1a; 如果函数成功&#xff0c;则返回非零值&#xff1b;否则返回0。 参数&#xff1a; pWndInsertAfter&#xff1a;标识了在Z轴次…...

STM32项目分享:智能门禁锁系统

目录 一、前言 二、项目简介 1.功能详解 2.主要器件 三、原理图设计 四、PCB硬件设计 1.PCB图 2.PCB板及元器件图 五、程序设计 六、实验效果 七、资料内容 项目分享 一、前言 项目成品图片&#xff1a; 哔哩哔哩视频链接&#xff1a; https://www.bilibili.c…...

PostgreSQL中有没有类似Oracle的dba_objects系统视图

PostgreSQL中有没有类似Oracle的dba_objects系统视图 在PostgreSQL中&#xff0c;没有一个完全集成了所有对象信息的视图&#xff08;类似于Oracle中的DBA_OBJECTS&#xff09;。但是&#xff0c;PostgreSQL提供了一些系统目录表和视图&#xff0c;可以用来获取数据库对象的信…...

【kubernetes】探索k8s集群的配置资源(secret和configma)

目录 一、Secret 1.1Secret 有四种类型 1.2Pod 有 3 种方式来使用 secret 1.3应用场景&#xff1a;凭据 1.4创建 Secret 1.4.1用kubectl create secret命令创建Secret 1.4.2内容用 base64 编码&#xff0c;创建Secret 1.4.2.1Base64编码 1.4.2.2创建YAML文件 1.4.2.3…...

基于springboot实现社区养老服务系统项目【项目源码+论文说明】计算机毕业设计

基于springboot实现社区养老服务系统演示 摘要 现代经济快节奏发展以及不断完善升级的信息化技术&#xff0c;让传统数据信息的管理升级为软件存储&#xff0c;归纳&#xff0c;集中处理数据信息的管理方式。本社区养老服务系统就是在这样的大环境下诞生&#xff0c;其可以帮助…...

用linux 1分钟部署一台文件上传/下载的http/https服务器

安装包官网&#xff1a;GitHub - codeskyblue/gohttpserver: The best HTTP Static File Server, write with golangvue 1、官网下载或本文章的资源链接下载gohttpserver&#xff1b; 2、将gohttpserver、cacert.pem、cakey.pem三个文件放在linux一个目录下 启动gohttpserver服…...

机器学习ML.NET

适用于 .NET 的机器学习 ML.NET 是用于 .NET 的跨平台开源机器学习 (ML) 框架。 ML.NET 允许开发人员在其 .NET 应用程序中轻松构建、训练、部署和使用自定义模型,而无需开发机器学习模型的专业知识或使用 Python 或 R 等其他编程语言的经验。该框架提供从文件和数据库加载…...

爬取基金收盘价并用pyecharts进行展现

爬取基金收盘价并用pyecharts进行展现 一、用到的第三方包 因为使用到了一些第三方的包&#xff0c;包还是比较大的如果直接从社区下载比较费劲&#xff0c;所以建议配置国内镜像源&#xff0c;这里以清华的镜像源为例。 pip config set global.index-url https://pypi.tuna…...

Python爬虫实战:研究feedparser库相关技术

1. 引言 1.1 研究背景与意义 在当今信息爆炸的时代,互联网上存在着海量的信息资源。RSS(Really Simple Syndication)作为一种标准化的信息聚合技术,被广泛用于网站内容的发布和订阅。通过 RSS,用户可以方便地获取网站更新的内容,而无需频繁访问各个网站。 然而,互联网…...

Java多线程实现之Callable接口深度解析

Java多线程实现之Callable接口深度解析 一、Callable接口概述1.1 接口定义1.2 与Runnable接口的对比1.3 Future接口与FutureTask类 二、Callable接口的基本使用方法2.1 传统方式实现Callable接口2.2 使用Lambda表达式简化Callable实现2.3 使用FutureTask类执行Callable任务 三、…...

Java 加密常用的各种算法及其选择

在数字化时代&#xff0c;数据安全至关重要&#xff0c;Java 作为广泛应用的编程语言&#xff0c;提供了丰富的加密算法来保障数据的保密性、完整性和真实性。了解这些常用加密算法及其适用场景&#xff0c;有助于开发者在不同的业务需求中做出正确的选择。​ 一、对称加密算法…...

SpringCloudGateway 自定义局部过滤器

场景&#xff1a; 将所有请求转化为同一路径请求&#xff08;方便穿网配置&#xff09;在请求头内标识原来路径&#xff0c;然后在将请求分发给不同服务 AllToOneGatewayFilterFactory import lombok.Getter; import lombok.Setter; import lombok.extern.slf4j.Slf4j; impor…...

图表类系列各种样式PPT模版分享

图标图表系列PPT模版&#xff0c;柱状图PPT模版&#xff0c;线状图PPT模版&#xff0c;折线图PPT模版&#xff0c;饼状图PPT模版&#xff0c;雷达图PPT模版&#xff0c;树状图PPT模版 图表类系列各种样式PPT模版分享&#xff1a;图表系列PPT模板https://pan.quark.cn/s/20d40aa…...

OD 算法题 B卷【正整数到Excel编号之间的转换】

文章目录 正整数到Excel编号之间的转换 正整数到Excel编号之间的转换 excel的列编号是这样的&#xff1a;a b c … z aa ab ac… az ba bb bc…yz za zb zc …zz aaa aab aac…; 分别代表以下的编号1 2 3 … 26 27 28 29… 52 53 54 55… 676 677 678 679 … 702 703 704 705;…...

学习一下用鸿蒙​​DevEco Studio HarmonyOS5实现百度地图

在鸿蒙&#xff08;HarmonyOS5&#xff09;中集成百度地图&#xff0c;可以通过以下步骤和技术方案实现。结合鸿蒙的分布式能力和百度地图的API&#xff0c;可以构建跨设备的定位、导航和地图展示功能。 ​​1. 鸿蒙环境准备​​ ​​开发工具​​&#xff1a;下载安装 ​​De…...

GAN模式奔溃的探讨论文综述(一)

简介 简介:今天带来一篇关于GAN的,对于模式奔溃的一个探讨的一个问题,帮助大家更好的解决训练中遇到的一个难题。 论文题目:An in-depth review and analysis of mode collapse in GAN 期刊:Machine Learning 链接:...

Element-Plus:popconfirm与tooltip一起使用不生效?

你们好&#xff0c;我是金金金。 场景 我正在使用Element-plus组件库当中的el-popconfirm和el-tooltip&#xff0c;产品要求是两个需要结合一起使用&#xff0c;也就是鼠标悬浮上去有提示文字&#xff0c;并且点击之后需要出现气泡确认框 代码 <el-popconfirm title"是…...

生产管理系统开发:专业软件开发公司的实践与思考

生产管理系统开发的关键点 在当前制造业智能化升级的转型背景下&#xff0c;生产管理系统开发正逐步成为企业优化生产流程的重要技术手段。不同行业、不同规模的企业在推进生产管理数字化转型过程中&#xff0c;面临的挑战存在显著差异。本文结合具体实践案例&#xff0c;分析…...