【论文复现】进行不同视角图像的拼接

在这里插入图片描述

📝个人主页🌹:Eternity._
🌹🌹期待您的关注 🌹🌹

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

❀ 进行不同视角图像的拼接

  • 背景描述
  • 算法简介
  • SIFT算法原理
  • 代码原理
  • 代码部署
  • 核心代码
  • 拼接结果
  • 其他的图片如何进行拼接?

修改内容:
1、将附件中的“数据集”选项进行了删除;
2、对代码的原理进行更加详细的说明,修改步骤(1)和(2),对表意不明“组件”一词进行了更正,原理描述更加清晰。


本文所涉及的所有资源的获取方式:这里

背景描述


首先来看这样两幅图:
在这里插入图片描述
图1 一栋大楼的左半部分
在这里插入图片描述
图2 一栋大楼的右半部分

在很多情况下,我们往往会拍摄一些有重叠但是并不完整的图片。

无论对于日常的娱乐需求还是一些专业性的测绘工作,都需要我们基于这些“残缺”的图片来构建出完整的图像。

因此,本人根据先前图像处理的经验,使用一种基于SIFT特征匹配的算法来实现此任务。

算法简介


SIFT(Scale Invariant Feature Transform,尺度不变特征变换匹配算法),是由David G. Lowe在《Object Recognition from Local Scale-Invariant Features》提出的高效区域检测算法,在2004年的《Distinctive Image Features from Scale-Invariant Keypoints》中得以完善。
其主要特点如下:

(1)尺度不变性:SIFT算法可以在不同尺度的图像上检测和描述特征。这使得它对于图像中存在不同尺度的物体或图像的缩放变换具有鲁棒性。

(2)旋转不变性:SIFT算法可以检测和描述在不同旋转角度下的特征。这使得它对于图像中存在旋转变换的物体具有鲁棒性。

(3)对光照变化和视角变化具有一定的鲁棒性。

(4)提取特征:SIFT算法通过在图像中检测局部特征点(例如边缘、角点等)来提取特征。它使用一种称为DoG(Difference of Gaussian)的算法来检测图像中的特征点。

(5)描述特征:对于每个检测到的特征点,SIFT算法计算其周围区域的特征描述符,该描述符是一种对特征点的局部图像区域进行编码的向量。这些描述符对于不同的特征点具有唯一性,可以用于特征匹配和识别。

(6)特征匹配和识别:通过比较不同图像中的特征点的描述符,可以进行特征匹配和识别。SIFT算法使用一种称为RANSAC(Random Sample Consensus)的算法来寻找在多个图像中匹配的特征点,从而可以进行目标跟踪和图像配准等任务。

总而言之,SIFT算法是一种强大的图像特征提取算法,它可以在不同尺度和旋转角度下提取具有尺度不变性和旋转不变性的局部特征,并用于图像匹配、目标跟踪、图像配准等计算机视觉任务。

SIFT算法原理


这一部分简要介绍SIFT算法的执行流程。

  1. 检测尺度空间极值

在这里插入图片描述
图3 DOG算法示意图

  1. 关键点的精确定位
    以上方法检测到的极值点是离散空间的极值点,以下通过拟合三维二次函数来精确确定关键点的位置和尺度,同时去除低对比度的关键点和不稳定的边缘响应点(因为DOG算子会产生较强的边缘响应),以增强匹配稳定性、提高抗噪声能力。

  2. 方向匹配
    通过根据局部图像属性为每个关键点分配一致的方向,可以相对于该方向表示关键点描述符,从而实现图像旋转的不变性。

  3. 局部图像描述
    之前的操作已经为每个关键点分配了图像位置、比例和方向。这些参数强加了一个可重复的局部 2D 坐标系,在其中描述局部图像区域,因此为这些参数提供了不变性。下一步是计算局部图像区域的描述符,该描述符具有高度独特性,对剩余变化(例如照明或 3D 视点的变化)尽可能保持不变

代码原理


为实现SIFT特征检测,主要使用到了以下的两个工具包:OpenCV,numpy。其中OpenCV是一个非常知名且受欢迎的跨平台计算机视觉库,它不仅包含常用的图像读取、显示、颜色变换,还包含一些为人熟知的经典特征检测算法,其中就包括SIFT,所以本文使用OpenCV进行读取和SIFT特征检测。numpy是一个非常优秀的数值计算库,也常用于图像的处理,这里使用numpy主要用于图像的拼接和显示。
代码的具体实现逻辑如下:
(1)首先先读入待拼接的图像,例如下述代码示例中的’hanying1.jpg’和’hanying2.jpg’,然后使用opencv自带的cv2.SIFT_create()创建SIFT对象,用于计算每幅图像的特征点和特征描述符。

(2)然后对各幅图像生成的特征描述符使用Flann算法进行匹配,并筛选出匹配结果较好的特征点用于下述单应性矩阵的计算。

(3)单应矩阵估计:通过至少4对匹配的关键点对,可以使用RANSAC(随机抽样一致性)算法估计出单应矩阵H。RANSAC算法通过随机选择一部分关键点对来估计H,并通过计算其他关键点对与估计的H之间的误差,筛选出符合约束条件的关键点对,并最终得到较好的单应矩阵估计。

(4)图像视点变换:对于每个视点的图像,使用估计得到的单应矩阵H进行变换。对于输出图像的每个像素点,通过逆变换将其映射回到原始视点的坐标系中。具体来说,对于输出图像中的每个像素点(x, y),通过矩阵乘法运算得到变换后的坐标。然后,根据相应的像素值进行插值,得到变换后的像素值。

(5)图像拼接:将变换后的图像按照一定的拼接规则进行拼接,以生成最终的全景图像或多视点切换图像。拼接规则可以根据具体需求来确定,常见的方法包括:重叠区域的像素平均值、像素最大值、图像融合等。

代码部署


需要导入的核心类库为opencv和numpy

import cv2
import numpy as np

核心代码


首先使用cv2.SIFT_create()创建SIFT特征检测器对象,然后就需要将图片输入到特征描述对象中,用于检测相应的特征点和计算相应的特征描述符,具体代码如下:

# 在每个图像中检测特征点和计算描述符
keypoints = []
descriptors = []
for image in images:
    gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
    kp, des = sift.detectAndCompute(gray, None)
    keypoints.append(kp)
    descriptors.append(des)
# 特征点匹配
matcher = cv2.FlannBasedMatcher()
matches = []
for i in range(len(descriptors)-1):
    matches.append(matcher.knnMatch(descriptors[i], descriptors[i+1], k=2))
# 筛选匹配点
good_matches = []
for match in matches:
    good = []
    for m, n in match:
        if m.distance < 0.7 * n.distance:
            good.append(m)
    good_matches.append(good)
# 计算单应矩阵
homographies = []
for i, match in enumerate(good_matches):
    if len(match) >= 4:
        src_pts = np.float32([keypoints[i][m.queryIdx].pt for m in match]).reshape(-1, 1, 2)
        dst_pts = np.float32([keypoints[i+1][m.trainIdx].pt for m in match]).reshape(-1, 1, 2)
        H, _ = cv2.findHomography(src_pts, dst_pts, cv2.RANSAC, 2.0)
        homographies.append(H)
# 拼接图像
result = images[0]
for i in range(len(images)-1):
    result = cv2.warpPerspective(result, homographies[i], (result.shape[1]+images[i+1].shape[1], result.shape[0]))
    result[0:images[i+1].shape[0], 0:images[i+1].shape[1]] = images[i+1]

拼接结果


在这里插入图片描述
图4 最终拼接结果(由于拍摄时间原因,亮度存在一定差异)

其他的图片如何进行拼接?


本博客提供的两张图片为作者自行拍摄,如果读者想要拼接自己拍摄的图片,只需将代码里相应的图片路径和名称更换为自己本地的图片路径和名称即可。如果不愿添加路径信息,仅需将自己的图片放置在代码工程下,修改为图片的名称即可。
例如我重新对如下两幅图进行拼接:

在这里插入图片描述
在这里插入图片描述
只需将其放入代码工程后,在下图相应位置改为图片名即可。

在这里插入图片描述
拼接结果如下图:
在这里插入图片描述


编程未来,从这里启航!解锁无限创意,让每一行代码都成为你通往成功的阶梯,帮助更多人欣赏与学习!

更多内容详见:这里

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

xxl-job 简单的入门到实战

本文是参考官方文档自己实践一次&#xff0c;纯享版&#xff0c;大致也是作者边写博客边去跟着官方文档实现 一、前期准备 1、官网地址 GitHub地址&#xff1a; GitHub - xuxueli/xxl-job: A distributed task scheduling framework.&#xff08;分布式任务调度平台XXL-JOB&…

数字后端培训项目Floorplan常见问题系列专题续集1

今天继续给大家分享下数字IC后端设计实现floorplan阶段常见问题系列专题。这些问题都是来自于咱们社区IC后端训练营学员提问的问题库。目前这部分问题库已经积累了4年了&#xff0c;后面会陆续分享这方面的问题。 希望对大家的数字后端学习和工作有所帮助。 数字后端项目Floor…

江苏捷科云:可视化平台助力制造企业智能化管理

公司简介 江苏捷科云信息科技有限公司&#xff08;以下简称“捷科”&#xff09;是一家专注于云平台、云储存、云管理等产品领域的创新型企业&#xff0c;集研发、生产和销售于一体&#xff0c;致力于在网络技术领域打造尖端品牌。在推动制造业企业数字化转型的进程中&#xf…

【视觉惯性SLAM:对极几何】

对极几何&#xff08;Epipolar Geometry&#xff09;介绍 对极几何是立体视觉中的核心内容之一&#xff0c;它描述了两个相机在观察同一个三维场景时&#xff0c;成像平面之间的几何关系。对极几何能够约束图像中对应点的位置关系&#xff0c;是双目立体匹配、三维重建、以及位…

从Condition开始,回顾AQS

Synchronized和Reentrantlock的挂起逻辑 synchronized中有两个核心的结构 EntryList cxq&#xff1a;等待拿锁的线程存储位置Waitset&#xff1a;被执行wait方法的线程存储位置 流转&#xff1a; 线程获取锁资源失败&#xff0c;扔到EntryList cxq线程持有锁资源&#x…

umi : 无法加载文件 D:\software\nodejs\node_global\umi.ps1,因为在此系统上禁止运行脚本。

问题详情 2、解决方法 1.使用命令 get-ExecutionPolicy查看 显示Restricted&#xff1a;限制 所以要给权限 2. 使用命令&#xff1a;Set-ExecutionPolicy -Scope CurrentUser 3. 会提示为参数提供值 4. 输入&#xff1a; RemoteSigned 具体如下图所示&#xff0c;成功解决。 报…

Redis篇--常见问题篇4--大Key(Big Key,什么是大Key,影响及使用建议)

1、概述 大Key&#xff1a;通常是指值&#xff08;Value&#xff09;的长度非常大&#xff0c;实际上键&#xff08;Key&#xff09;长度很大也算。通常来说&#xff0c;键本身不会很长&#xff0c;占用的内存较少&#xff0c;因此判断一个键是否为bigKey主要看它对应的值的大…

02、并发编程的三大特性

并发编程有三大特性分别是&#xff0c;原子性&#xff0c;可见性&#xff0c;有序性。会产生这些特性的根本原因是现在的服务器都是多CPU多核心数的&#xff0c;每个CPU都有自己单独的一套缓存和pc系统&#xff0c;而且程序在运行时按照JMM的规范&#xff0c;它们是需要先把数据…

基于Java+Jsp Servlet Mysql实现的Java Web在线商城项目系统设计与实现

一、前言介绍&#xff1a; 1.1 项目摘要 随着互联网技术的飞速发展&#xff0c;电子商务已成为现代商业活动的重要组成部分。在线商城作为电子商务的一种重要形式&#xff0c;以其便捷性、高效性和广泛覆盖性&#xff0c;受到了越来越多消费者的青睐。同时&#xff0c;随着消…

【安全测试相关知识】

安全测试介绍 背景 在当前信息技术快速发展的背景下&#xff0c;网络安全问题日益严峻&#xff0c;数据泄露、黑客攻击、病毒传播等安全事件层出不穷&#xff0c;给个人、企业乃至国家带来严重威胁。所以安全测试已成为企业和国家关注的重心 作用 安全测试是确保软件系统安…

WPS如何快速将数字金额批量转换成中文大写金额,其实非常简单

大家好&#xff0c;我是小鱼。 在日常的工作中经常会遇到需要使用金额大写的情况&#xff0c;比如说签订业务合同时一般都会标注大写金额&#xff0c;这样是为了安全和防止串改。但是很多人也许不太熟悉金额大写的方法和习惯&#xff0c;其它没有关系&#xff0c;我们在用WPS制…

Element-ui的使用教程 基于HBuilder X

文章目录 1.Element-ui简介2.使用HBuilderX 创建一个基于Vue3的项目 &#xff08;由于是使用的基于Vue3的Element-ui&#xff09;3.安装element-ui4.在项目里完全引用element-ui5.引用组件6.运行项目 1.Element-ui简介 Element&#xff0c;一套为开发者、设计师和产品经理准备…

MySQL的架构设计和设计模式

1. 数据库设计模式与范式 数据库设计模式是解决数据库设计中常见问题的一种思维方式&#xff0c;它提供了一套解决方案。以下是一些常见的数据库设计模式和范式&#xff1a; 实体-关系模型&#xff08;Entity-Relationship Model&#xff09;&#xff1a;通过实体和实体之间的…

【MySQL】十三,关于MySQL的全文索引

MySQL的全文索引用于搜索文本中的关键字&#xff0c;类似于like查询。 演示 建表 CREATE TABLE demo (id INT(11) NOT NULL,name CHAR(30) NOT NULL,age INT(11) NOT NULL,info VARCHAR(255),primary key(id),fulltext index futxt_idx_info(info) );此表的默认存储引擎为In…

Aloudata 入选 IDC「GenAI+Data」中国市场代表厂商

近期&#xff0c;国际知名技术研究与咨询机构 IDC 发布了《GenAIData 市场趋势分析及最佳实践案例》报告&#xff0c;总结了当前主要市场特点和数据变化影响&#xff0c;并给出技术布局建议&#xff0c;以供市场参考。报告中还绘制了 GenAIData 发展趋势图&#xff0c;从市场需…

NCR+可变电荷块3——NCB/cell绘图1

文献method参考&#xff1a; 蛋白质序列数据从uniprot中获取 https://www.uniprot.org/uniprotkb/P46013/entry https://www.uniprot.org/uniprotkb/P06748/entry、 1&#xff0c;电荷分布计算&#xff1a; Charge distribution was calculated as the sum of the charges …

单片机锂电池电量电压检测

一、引言 &#xff08;一&#xff09;锂电池电量检测的重要性简述 在如今这个科技飞速发展的时代&#xff0c;众多电子设备都依赖锂电池来供电&#xff0c;像我们日常使用的智能手机、平板电脑、笔记本电脑&#xff0c;还有出行必备的电动自行车、电动汽车等等&#xff0c;锂…

支付宝订单码支付

1.订单码支付&#xff0c;首先下载官方网站提供的sdk包到你的项目中。 2.选择控制器复制官方文档的获取二维码相关的代码示例。打开sdk包中v2的index.php文件&#xff0c;这个才是你选择语言的具体代码。 3.引用里面所需要的类文件&#xff0c;文件下载到你的项目中后&#xf…

【HarmonyOS 5.0】第十二篇-ArkUI公共属性(一)

一、公共样式类属性 ArkUI框架提供的基础组件直接或者间接的继承自 CommonMethod &#xff0c; CommonMethod 中定义的属性样式属于公共样式。下面就来学习这些样式 1.1.尺寸设置 宽高设置 设置组件的宽高&#xff0c;缺省时使用组件自身内容的宽高&#xff0c;比如充满父布…

VTK知识学习(27)- 图像基本操作(二)

1、图像类型转换 1&#xff09;vtkImageCast 图像数据类型转换在数字图像处理中会频繁用到。一些常用的图像算子(例如梯度算子)在计算时出于精度的考虑&#xff0c;会将结果存储为float或double类型&#xff0c;但在图像显示时&#xff0c;一般要求图像为 unsigned char 类型,…