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

【进阶OpenCV】 (4)--图像拼接

文章目录

  • 图像拼接
    • 1. 读取图片
    • 2. 计算图片特征点及描述符
    • 3. 建立暴力匹配器
    • 4. 特征匹配
    • 5. 透视变换
    • 6. 图像拼接
  • 总结

图像拼接

图像拼接是一项将多张有重叠部分的图像(这些图像可能是不同时间、不同视角或者不同传感器获得的)拼成一幅无缝的全景图或高分辨率图像的技术。

主要过程:找到特征匹配点,然后进行透视变换操作,模拟了人眼或相机镜头观看三维空间物体时的透视效果,从而能够改变图像的视角和形状,使得两个图片可以完全拼接在一起。

1. 读取图片

在这里插入图片描述

在这里插入图片描述

def cv_show(name,img):cv2.imshow(name,img)cv2.waitKey(0)
"""-----读取拼接图片-----"""
imageA = cv2.imread("t1.jpg")
cv_show('imageA',imageA)
imageB = cv2.imread("t2.jpg")
cv_show('imageB',imageB)

2. 计算图片特征点及描述符

def detectAndDescribe(image):gray = cv2.cvtColor(image,cv2.COLOR_RGB2GRAY) # 将彩色图片转化为灰度图descriptor = cv2.SIFT_create() # 建立SIFT生成器# 检测SIFT特征点,并计算描述符,第二个参数为掩膜(kps,des) = descriptor.detectAndCompute(gray,None)# 将结果转化成Numoy数组kps_float = np.float32([kp.pt for kp in kps])# kp.pt包含两个值,分别是关键点在图像中的x和y坐标,这些坐标通常时浮点数,可以精确地描述关键点在图像中的位置return (kps,kps_float,des) # 返回特征点集,及对应的描述特征"""-----计算图片特征点及描述符-----"""
(kpsA,kps_floatA,desA) = detectAndDescribe(imageA)
(kpsB,kps_floatB,desB) = detectAndDescribe(imageB)

3. 建立暴力匹配器

"""-----建立暴力匹配器BFMatcher,在匹配大型训练集合时使用FlannBasedMatcher速度更快-----"""
matcher = cv2.BFMatcher()

4. 特征匹配

方法:关键点A与找到的两个关键点 X、Y的欧氏距离分别 d1、d2,且d1<d2。

欧氏距离(关键点A,关键点X)=d1。欧氏距离(关键点A,关键点Y)=d2。

(1)d1<d2,比值较大:可能不是匹配点,通常是由噪声引起的。

(2)d1<d2,比值较小:是匹配点。

在这里插入图片描述

  • 函数
--knnMatch(queryDescriptors,trainDescriptors,k,mask=None,compactResult = None)
使用KNN检测来自A、B图的SIFT特征匹配对,参数说明:
queryDescriptors:匹配图像A的描述符
trainDescriptors:匹配图像B的描述符
k:最佳匹配的描述符个数,一般k=2
  • 返回值
--返回的数据结构描述:
distance:匹配的特征点描述符的欧氏距离,数值越小也就说明两个特征点越相近。
queryIdx:测试图像的特征点描述符的下标(第几个特征点描述符),同时也是描述符对应特征点的下表
trainIdx:样本图像的特征点描述符下标,同时也是描述符对应特征点的下标。
  • 代码应用:
rawMatches = matcher.knnMatch(desB,desA,2)
good = []
matches = []
for m in rawMatches:# 当最近距离跟次近距离的比值小于0.65时,保留此对匹配if len(m) == 2 and m[0].distance < 0.65 * m[1].distance:good.append(m)# 存储两个点在featureA,featureB中的索引值matches.append((m[0].trainIdx,m[0].queryIdx))
print(len(good))
print(matches)vis = cv2.drawMatchesKnn(imageB,kpsB,imageA,kpsA,good,None,flags=cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS)
cv_show("keypoint Matchs",vis)

在这里插入图片描述

5. 透视变换

透视变换是指利用透视中心、像点、目标点三点共线的条件,按透视旋转定律使承影面(透视面)绕迹线(透视轴)旋转某一角度,破坏原有的投影光线束,但仍能保持承影面上投影几何图形不变的变换。它是中心投影的射影变换,在用非齐次射影坐标表达时是平面的分式线性变换。

  • 函数
-- 计算透视变换矩阵
findHomography(srcPoints,disPoints,method=None,ransacReprojThreshold=None,mask=None,maxIters=None,confidence=None)
计算视角变换矩阵,透视变换函数,与cv2.getPerspectiveTransform()的区别在于可多个数据点变换
参数:
-- srcPoints:图片A的匹配点坐标
-- disPoints:图片B的匹配点坐标
-- method:计算变换矩阵的方法0 - 使用所有的点,最小二乘RANSAC - 基于随机样本一致性LMEDS - 最小中值RHO - 基于渐进样本一致性
-- ransacReprojThreshold:最大允许重投影错误阈值,该参数只有在method参数为RANSAC与RHO的时候启用,默认为3
返回值:H为变换矩阵,mask时掩膜标志,指示哪些点对时内点,哪些是外点.内点:指那些与估计的模型非常接近的数据点,通常是正确匹配或真实数据
  • 代码应用
if len(matches) > 4: # 当筛选后的匹配对大于4时,计算视角变换矩阵# 获取匹配对的点坐标ptsA = np.float32([kps_floatA[i] for (i, _) in matches]) # matches是通过阈值筛选之后的特征点对象ptsB = np.float32([kps_floatB[i] for (_, i) in matches]) # kps_floatA是图片A中的全部特征点坐标(H,mask) = cv2.findHomography(ptsB,ptsA,cv2.RANSAC,10)
else:print("图片未找到4个以上的匹配点")sys.exit()
result = cv2.warpPerspective(imageB,H,(imageB.shape[1] + imageA.shape[1],imageB.shape[0]))
cv_show('resultB',result)

在这里插入图片描述

6. 图像拼接

# 将图片A传入result图片最左端
result[0:imageA.shape[0],0:imageA.shape[1]] = imageA
cv_show("result",result)

在这里插入图片描述

总结

本篇介绍了:

如何通过计算关键点以及透视变换的矩阵将两个不同视角的图片进行拼接,使得它们能够完整协和的展示出来。

相关文章:

【进阶OpenCV】 (4)--图像拼接

文章目录 图像拼接1. 读取图片2. 计算图片特征点及描述符3. 建立暴力匹配器4. 特征匹配5. 透视变换6. 图像拼接 总结 图像拼接 图像拼接是一项将多张有重叠部分的图像&#xff08;这些图像可能是不同时间、不同视角或者不同传感器获得的&#xff09;拼成一幅无缝的全景图或高分…...

pg if条件语句

1.语法&#xff1a; 2.区别 IF 语句&#xff1a; 只能在 PL/pgSQL 中使用&#xff0c;不适合在直接的 SQL 查询中使用。没有返回值&#xff0c;仅仅是控制逻辑流程。适合用在存储过程、函数和触发器中。 CASE 语句&#xff08;在 PL/pgSQL 中&#xff09;&#xff1a; 可以在 P…...

Pikachu-unsafe upfileupload-getimagesize

什么是getimagesize()&#xff1f; getimagesize()是PHP中用于获取图像的大小和格式的函数。它可以返回一个包含图像的宽度、高度、类型和MIME类型的数组。 由于返回的这个类型可以被伪造&#xff0c;如果用这个函数来获取图片类型&#xff0c;从而判断是否时图片的话&#xff…...

SOA是什么

SOA SOA 即 Service-Oriented Architecture&#xff08;面向服务的架构&#xff09;。 一、定义 SOA 是一种软件设计方法和架构理念&#xff0c;它将应用程序的不同功能单元&#xff08;称为服务&#xff09;通过定义良好的接口和契约联系起来。这些服务可以独立部署、独立运…...

构建高效团队,内部CRM系统的益处详解

内部CRM系统的最大优势之一是它能够集中并系统化客户信息&#xff0c;包括联系方式、购买历史、偏好设置、服务记录等。这种集中式的数据管理使企业能够快速响应客户需求&#xff0c;预测客户行为&#xff0c;提供个性化的服务或产品。更重要的是&#xff0c;它有助于建立一个统…...

Linux文件属性

Linux 文件基本属性 为了保护系统的安全性&#xff0c;Linux 系统对不同的用户访问同一文件&#xff08;包括目录文件&#xff09;的权限做了不同的规定。 在 Linux 中我们通常使用以下两个命令来修改文件或目录的所属用户与权限&#xff1a; - chown (change owner) &#…...

什么是Anaconda

目录 1. [什么是Anaconda](#什么是Anaconda) 2. [安装Anaconda](#安装Anaconda) - [检查系统](#检查系统) - [下载Anaconda](#下载Anaconda) - [安装Anaconda](#安装Anaconda) 3. [启动Anaconda Navigator](#启动Anaconda-Navigator) 4. [创建与管理环境](#创建与管理环…...

ubuntu24开启启动脚本

因为我是在之前装的是windows和ubuntu双系统,所以想在ubuntu中自动挂载和开启时做些自己的脚本处理开发环境。 我的脚本如下: truedei@truedei-code:~$ cat mount.shsudo umount /media/truedei/*#sudo ntfsfix /dev/sda3 #sudo ntfsfix /dev/sda4 #sudo ntfsfix /dev/sda5…...

流浪地球行星发动机

随着电影《流浪地球2》的热播&#xff0c;影片中的行星发动机构想激发了社会各界对科幻与未来科技的广泛讨论。本文深入剖析了行星发动机的科学原理&#xff0c;包括重力助推、行星转移轨道以及重核聚变等核心技术&#xff0c;揭示了其在推动地球逃离太阳系过程中的关键作用。通…...

云岚到家,使用Elasticsearch实现服务的搜索功能,使用Canal+MQ完成服务信息与ES索引同步。MQ

为什么使用elasticsearch?数据很多么&#xff1f; 项目使用Elasticsearch是实现了门户上对服务的搜索。 平台上的服务数据是并不是很多&#xff0c;全国所有区域下的服务信息加一起几千条&#xff0c;之所以使用Elasticsearch是因为&#xff1a; 1、公司架构师在系统架构时…...

【图论】迪杰特斯拉算法

文章目录 迪杰特斯拉算法主要特点基本思想算法步骤示例 实现迪杰斯特拉算法基本步骤算法思路 总结 迪杰特斯拉算法 迪杰特斯拉算法是由荷兰计算机科学家艾兹赫尔迪杰特斯拉&#xff08;Edsger W. Dijkstra&#xff09;在1956年提出的&#xff0c;用于解决单源最短路径问题的经…...

四、Python基础语法(数据类型转换)

数据类型转换就是将一种类型的数据转换为另外一种类型的数据&#xff0c;数据类型转换不会改变原数据&#xff0c;是产生一个新的数据。 变量 要转换为的类型(原数据) -> num int(28) 一.int()将其他类型转换为整型 1.整数类型的字符串转换为整型 num1 28 print(type…...

工业物联网的安全与隐私保护—SunIOT

【大家好&#xff0c;我是唐Sun&#xff0c;唐Sun的唐&#xff0c;唐Sun的Sun。一站式数智工厂解决方案服务商】 在当今数字化的时代&#xff0c;工业物联网&#xff08;IIoT&#xff09;正以前所未有的速度改变着工业生产的模式和效率。然而&#xff0c;随着工业物联网的广泛…...

二层网络和三层网络的理解与区别(包含通俗理解和归纳总结)

二层网络和三层网络是计算机网络中的两个不同层次&#xff0c;主要区别在于它们所处的OSI参考模型中的层次及其功能。 二层网络 (Layer 2 Network) 1.定义&#xff1a; 二层网络主要涉及数据链路层&#xff08;Layer 2&#xff09;&#xff0c;这是OSI模型中的第二层。 它负…...

【C++】:lambda表达式的高级应用

欢迎来到 破晓的历程的 博客 ⛺️不负时光&#xff0c;不负己✈️ 引言 今天 我们来见见lambda表达式的高级用法 用法1&#xff1a;自定义删除器 有些类型的delete方法并不符合自身的析构方法&#xff0c;这时我们就需要自定义删除器。 unique_ptr<FILE> ptr1(fopen…...

详解正确创建好SpringBoot项目后但是找不到Maven的问题

目录 问题 解决步骤&#xff1a; 找到File->Project Structure... 设置SDK 设置SDKs 问题 刚刚在使用IDEA专业版创建好SpringBoot项目后&#xff0c;发现上方导航栏的运行按钮是灰色的&#xff0c;而且左侧导航栏的pom.xml的图标颜色也不是正常的&#xff0c;与此同时我…...

力扣203.移除链表元素

题目链接&#xff1a;203. 移除链表元素 - 力扣&#xff08;LeetCode&#xff09; 给你一个链表的头节点 head 和一个整数 val &#xff0c;请你删除链表中所有满足 Node.val val 的节点&#xff0c;并返回 新的头节点 。 示例 1&#xff1a; 输入&#xff1a;head [1,2,6…...

UE4 材质学习笔记05(凹凸偏移和视差映射/扭曲着色器)

一.凹凸偏移和视差映射 1.偏移映射 这需要一个高度图并且它的分辨率很低&#xff0c;只有256*256&#xff0c;事实上&#xff0c;如果高度图的分辨率比较低并且有点模糊&#xff0c;效果反而会更好 然后将高度图输出到BumpOffset节点的height插槽中&#xff0c; 之后利用得到…...

网约班车升级手机端退票

背景 作为老古董程序员&#xff0c;不&#xff0c;应该叫互联网人员&#xff0c;因为我现在做的所有的事情&#xff0c;都是处于爱好&#xff0c;更多的时间是在和各行各业的朋友聊市场&#xff0c;聊需求&#xff0c;聊怎么通过IT互联网 改变实体行业的现状&#xff0c;准确的…...

【Vue】Vue 快速教程

Vue tutorial 参考&#xff1a;教程 | Vue.js (vuejs.org) 该教程需要前置知识&#xff1a;HTML, CSS, JavaScript 学习前置知识&#xff0c;你可以去 MDN Vue framework 是一个 JavaScript framework&#xff0c;以下简称 Vue&#xff0c;下面是它的特点 声明式渲染&#xff…...

3.3.1_1 检错编码(奇偶校验码)

从这节课开始&#xff0c;我们会探讨数据链路层的差错控制功能&#xff0c;差错控制功能的主要目标是要发现并且解决一个帧内部的位错误&#xff0c;我们需要使用特殊的编码技术去发现帧内部的位错误&#xff0c;当我们发现位错误之后&#xff0c;通常来说有两种解决方案。第一…...

多模态商品数据接口:融合图像、语音与文字的下一代商品详情体验

一、多模态商品数据接口的技术架构 &#xff08;一&#xff09;多模态数据融合引擎 跨模态语义对齐 通过Transformer架构实现图像、语音、文字的语义关联。例如&#xff0c;当用户上传一张“蓝色连衣裙”的图片时&#xff0c;接口可自动提取图像中的颜色&#xff08;RGB值&…...

WordPress插件:AI多语言写作与智能配图、免费AI模型、SEO文章生成

厌倦手动写WordPress文章&#xff1f;AI自动生成&#xff0c;效率提升10倍&#xff01; 支持多语言、自动配图、定时发布&#xff0c;让内容创作更轻松&#xff01; AI内容生成 → 不想每天写文章&#xff1f;AI一键生成高质量内容&#xff01;多语言支持 → 跨境电商必备&am…...

【RockeMQ】第2节|RocketMQ快速实战以及核⼼概念详解(二)

升级Dledger高可用集群 一、主从架构的不足与Dledger的定位 主从架构缺陷 数据备份依赖Slave节点&#xff0c;但无自动故障转移能力&#xff0c;Master宕机后需人工切换&#xff0c;期间消息可能无法读取。Slave仅存储数据&#xff0c;无法主动升级为Master响应请求&#xff…...

Redis数据倾斜问题解决

Redis 数据倾斜问题解析与解决方案 什么是 Redis 数据倾斜 Redis 数据倾斜指的是在 Redis 集群中&#xff0c;部分节点存储的数据量或访问量远高于其他节点&#xff0c;导致这些节点负载过高&#xff0c;影响整体性能。 数据倾斜的主要表现 部分节点内存使用率远高于其他节…...

面向无人机海岸带生态系统监测的语义分割基准数据集

描述&#xff1a;海岸带生态系统的监测是维护生态平衡和可持续发展的重要任务。语义分割技术在遥感影像中的应用为海岸带生态系统的精准监测提供了有效手段。然而&#xff0c;目前该领域仍面临一个挑战&#xff0c;即缺乏公开的专门面向海岸带生态系统的语义分割基准数据集。受…...

Go 并发编程基础:通道(Channel)的使用

在 Go 中&#xff0c;Channel 是 Goroutine 之间通信的核心机制。它提供了一个线程安全的通信方式&#xff0c;用于在多个 Goroutine 之间传递数据&#xff0c;从而实现高效的并发编程。 本章将介绍 Channel 的基本概念、用法、缓冲、关闭机制以及 select 的使用。 一、Channel…...

苹果AI眼镜:从“工具”到“社交姿态”的范式革命——重新定义AI交互入口的未来机会

在2025年的AI硬件浪潮中,苹果AI眼镜(Apple Glasses)正在引发一场关于“人机交互形态”的深度思考。它并非简单地替代AirPods或Apple Watch,而是开辟了一个全新的、日常可接受的AI入口。其核心价值不在于功能的堆叠,而在于如何通过形态设计打破社交壁垒,成为用户“全天佩戴…...

【Linux】自动化构建-Make/Makefile

前言 上文我们讲到了Linux中的编译器gcc/g 【Linux】编译器gcc/g及其库的详细介绍-CSDN博客 本来我们将一个对于编译来说很重要的工具&#xff1a;make/makfile 1.背景 在一个工程中源文件不计其数&#xff0c;其按类型、功能、模块分别放在若干个目录中&#xff0c;mak…...

【堆垛策略】设计方法

堆垛策略的设计是积木堆叠系统的核心&#xff0c;直接影响堆叠的稳定性、效率和容错能力。以下是分层次的堆垛策略设计方法&#xff0c;涵盖基础规则、优化算法和容错机制&#xff1a; 1. 基础堆垛规则 (1) 物理稳定性优先 重心原则&#xff1a; 大尺寸/重量积木在下&#xf…...