使用自己训练的superpoint与superglue模型进行图像配准

2024-04-04 21:36

本文主要是介绍使用自己训练的superpoint与superglue模型进行图像配准,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

基于官方团队发布的预训练模型,使用SuperPoint与SuperGlue实现图像配准,可以参考https://blog.csdn.net/a486259/article/details/129093084

基于官方团队发布的代码训练自己的模型,可以参考https://blog.csdn.net/a486259/article/details/135425673进行实现,训练出的模型不能直接参考上述博客进行部署,为此发布使用代码。

本博文实现基于https://github.com/magicleap/SuperGluePretrainedNetwork进行改进。

1、已训练模型提取

1.1 superpoint模型

参考https://blog.csdn.net/a486259/article/details/135425673训练出的superpoint模型可以在logs目录中找到,具体如下所示。
在这里插入图片描述
使用以下代码,可以将训练出的superpoint模型参数提取出,保存为SuperGluePretrainedNetwork所需的格式,模型文件名为superpoint_v1.pth

>>> import torch
>>> m=torch.load("F:\OPEN_PROJECT\pytorch-superpoint-master\logs\superpoint_my_data\checkpoints\superPointNet_1611_checkpoint.pth.tar")    
>>> m_dict=m["model_state_dict"]
>>> torch.save(m_dict,"superpoint_v1.pth")

代码执行效果如下所示
在这里插入图片描述

1.2 superglue模型

参考https://blog.csdn.net/a486259/article/details/135425673训练出的SuperGlue模型存储路径如下所示,将目标模型复制一份,重命名为superglue_outdoor.pth
在这里插入图片描述

2、SuperGluePretrainedNetwork修改

2.1 代码修改

SuperGluePretrainedNetwork代码修改完全参考https://blog.csdn.net/a486259/article/details/129093084?中章节1、前置操作进行修改

2.2 创建SPSG

这个与2.1章节中链接的博客操作是一模一样的。

import torch
from superglue import SuperGlue
from superpoint import SuperPoint
import torch
import torch.nn as nn
import torch.nn.functional as F
class SPSG(nn.Module):#def __init__(self):super(SPSG, self).__init__()self.sp_model = SuperPoint({'max_keypoints':700})self.sg_model = SuperGlue({'weights': 'outdoor'})def forward(self,x1,x2):keypoints1,scores1,descriptors1=self.sp_model(x1)keypoints2,scores2,descriptors2=self.sp_model(x2)#print(scores1.shape,keypoints1.shape,descriptors1.shape)#example=(descriptors1.unsqueeze(0),descriptors2.unsqueeze(0),keypoints1.unsqueeze(0),keypoints2.unsqueeze(0),scores1.unsqueeze(0),scores2.unsqueeze(0))example=(descriptors1,descriptors2,keypoints1,keypoints2,scores1,scores2)indices0,  indices1,  mscores0,  mscores1=self.sg_model(*example)#return indices0,  indices1,  mscores0,  mscores1matches = indices0[0]valid = torch.nonzero(matches > -1).squeeze().detach()mkpts0 = keypoints1[0].index_select(0, valid);mkpts1 = keypoints2[0].index_select(0, matches.index_select(0, valid));confidence = mscores0[0].index_select(0, valid);return mkpts0, mkpts1, confidence

2.3 替换预训练模型

使用章节一种生成的superglue_outdoor.pth与superpoint_v1.pth替换掉原有的模型,具体如下所示
在这里插入图片描述

3、对自己的数据进行配准

使用以下代码,可以基于自行训练的模型对自己的数据进行配准。

进行图像读取、图像显示操作的代码被封装为imgutils库,具体可以查阅https://hpg123.blog.csdn.net/article/details/124824892

from imgutils import *
import torch
from SPSG import SPSG
model=SPSG().to('cuda')
tensor2a,img2a=read_img_as_tensor(r"potato\a (1).jpg",(320,320),device='cuda')
tensor2b,img2b=read_img_as_tensor(r"potato\a (2).jpg",(320,320),device='cuda')
print(tensor2a.shape)
mkpts0, mkpts1, confidence=model(tensor2a,tensor2b)
#myimshows( [img2a,img2b],size=12)import cv2 as cv
pt_num = mkpts0.shape[0]
im_dst,im_res=img2a,img2b
img = np.zeros((max(im_dst.shape[0], im_res.shape[0]), im_dst.shape[1]+im_res.shape[1]+10,3))
img[:,:im_res.shape[0],]=im_dst
img[:,-im_res.shape[0]:]=im_res
img=img.astype(np.uint8)
match_threshold=0.6
for i in range(0, pt_num):if (confidence[i] > match_threshold):pt0 = mkpts0[i].to('cpu').numpy().astype(np.int32)pt1 = mkpts1[i].to('cpu').numpy().astype(np.int32)#cv.circle(img, (pt0[0], pt0[1]), 1, (0, 0, 255), 2)#cv.circle(img, (pt1[0], pt1[1]+650), (0, 0, 255), 2)cv.line(img, pt0, (pt1[0]+im_res.shape[0], pt1[1]), (0, 255, 0), 1)
myimshow( img,size=12)import cv2
def getGoodMatchPoint(mkpts0, mkpts1, confidence,  match_threshold:float=0.5):n = min(mkpts0.size(0), mkpts1.size(0))srcImage1_matchedKPs, srcImage2_matchedKPs=[],[]if (match_threshold > 1 or match_threshold < 0):print("match_threshold error!")for i in range(n):kp0 = mkpts0[i]kp1 = mkpts1[i]pt0=(kp0[0].item(),kp0[1].item());pt1=(kp1[0].item(),kp1[1].item());c = confidence[i].item();if (c > match_threshold):srcImage1_matchedKPs.append(pt0);srcImage2_matchedKPs.append(pt1);return np.array(srcImage1_matchedKPs),np.array(srcImage2_matchedKPs)
pts_src, pts_dst=getGoodMatchPoint(mkpts0, mkpts1, confidence)h1, status = cv2.findHomography(pts_src, pts_dst, cv.RANSAC, 8)
im_out1 = cv2.warpPerspective(im_dst, h1, (im_dst.shape[1],im_dst.shape[0]))
im_out2 = cv2.warpPerspective(im_res, h1, (im_dst.shape[1],im_dst.shape[0]),16)
#这里 im_res和im_out1是严格配准的状态
myimshowsCL([im_dst,im_out1,im_res,im_out2],rows=2,cols=2, size=6)

代码、数据、模型的关系如下所示
在这里插入图片描述
代码运行效果如下所示
在这里插入图片描述
在这里插入图片描述

这篇关于使用自己训练的superpoint与superglue模型进行图像配准的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



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

相关文章

使用Python从PPT文档中提取图片和图片信息(如坐标、宽度和高度等)

《使用Python从PPT文档中提取图片和图片信息(如坐标、宽度和高度等)》PPT是一种高效的信息展示工具,广泛应用于教育、商务和设计等多个领域,PPT文档中常常包含丰富的图片内容,这些图片不仅提升了... 目录一、引言二、环境与工具三、python 提取PPT背景图片3.1 提取幻灯片背景图片3.2 提取

使用Python实现图像LBP特征提取的操作方法

《使用Python实现图像LBP特征提取的操作方法》LBP特征叫做局部二值模式,常用于纹理特征提取,并在纹理分类中具有较强的区分能力,本文给大家介绍了如何使用Python实现图像LBP特征提取的操作方... 目录一、LBP特征介绍二、LBP特征描述三、一些改进版本的LBP1.圆形LBP算子2.旋转不变的LB

Maven的使用和配置国内源的保姆级教程

《Maven的使用和配置国内源的保姆级教程》Maven是⼀个项目管理工具,基于POM(ProjectObjectModel,项目对象模型)的概念,Maven可以通过一小段描述信息来管理项目的构建,报告... 目录1. 什么是Maven?2.创建⼀个Maven项目3.Maven 核心功能4.使用Maven H

Python中__init__方法使用的深度解析

《Python中__init__方法使用的深度解析》在Python的面向对象编程(OOP)体系中,__init__方法如同建造房屋时的奠基仪式——它定义了对象诞生时的初始状态,下面我们就来深入了解下_... 目录一、__init__的基因图谱二、初始化过程的魔法时刻继承链中的初始化顺序self参数的奥秘默认

SpringBoot使用GZIP压缩反回数据问题

《SpringBoot使用GZIP压缩反回数据问题》:本文主要介绍SpringBoot使用GZIP压缩反回数据问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录SpringBoot使用GZIP压缩反回数据1、初识gzip2、gzip是什么,可以干什么?3、Spr

Spring Boot 集成 Quartz并使用Cron 表达式实现定时任务

《SpringBoot集成Quartz并使用Cron表达式实现定时任务》本篇文章介绍了如何在SpringBoot中集成Quartz进行定时任务调度,并通过Cron表达式控制任务... 目录前言1. 添加 Quartz 依赖2. 创建 Quartz 任务3. 配置 Quartz 任务调度4. 启动 Sprin

Linux下如何使用C++获取硬件信息

《Linux下如何使用C++获取硬件信息》这篇文章主要为大家详细介绍了如何使用C++实现获取CPU,主板,磁盘,BIOS信息等硬件信息,文中的示例代码讲解详细,感兴趣的小伙伴可以了解下... 目录方法获取CPU信息:读取"/proc/cpuinfo"文件获取磁盘信息:读取"/proc/diskstats"文

Java使用SLF4J记录不同级别日志的示例详解

《Java使用SLF4J记录不同级别日志的示例详解》SLF4J是一个简单的日志门面,它允许在运行时选择不同的日志实现,这篇文章主要为大家详细介绍了如何使用SLF4J记录不同级别日志,感兴趣的可以了解下... 目录一、SLF4J简介二、添加依赖三、配置Logback四、记录不同级别的日志五、总结一、SLF4J

使用Python实现一个优雅的异步定时器

《使用Python实现一个优雅的异步定时器》在Python中实现定时器功能是一个常见需求,尤其是在需要周期性执行任务的场景下,本文给大家介绍了基于asyncio和threading模块,可扩展的异步定... 目录需求背景代码1. 单例事件循环的实现2. 事件循环的运行与关闭3. 定时器核心逻辑4. 启动与停

如何使用Nginx配置将80端口重定向到443端口

《如何使用Nginx配置将80端口重定向到443端口》这篇文章主要为大家详细介绍了如何将Nginx配置为将HTTP(80端口)请求重定向到HTTPS(443端口),文中的示例代码讲解详细,有需要的小伙... 目录1. 创建或编辑Nginx配置文件2. 配置HTTP重定向到HTTPS3. 配置HTTPS服务器