《深度学习》OpenCV 图像拼接 原理、参数解析、案例实现
目录
一、图像拼接
1、直接看案例
图1与图2展示:
合并完结果:
2、什么是图像拼接
3、图像拼接步骤
1)加载图像
2)特征点检测与描述
3)特征点匹配
4)图像配准
5)图像变换和拼接
6)图像调整
二、案例实现
1、定义函数返回图像的关键点和描述符
2、定义展示图像函数
3、计算读入图像的特征点和描述符
调试模式状态下:
kps对应值:
des对应值:
4、建立暴力匹配器和K近邻算法
1)关于BFMatcher暴力匹配
2)暴力匹配的K近邻
用法:
参数解析:
返回值:
3)续接上文代码
运行结果:
调试模式rawMatches内容:
5、绘制匹配结果
运行结果:
6、计算视角变换矩阵
调试模式下
kps_floatA与kps_floatB状态
matches状态
7、透视变换后拼接
运行结果:
8、完整代码:
一、图像拼接
1、直接看案例
图1与图2展示:

合并完结果:

2、什么是图像拼接
图像拼接是指将多个图像拼接成一个大图像。在计算机视觉和图像处理领域,图像拼接常用于创建全景图像、创建大幅面照片、图像拼接等应用。
3、图像拼接步骤

1)加载图像
使用OpenCV的cv::imread函数加载需要拼接的多个图像。
2)特征点检测与描述
使用特征提取算法(如SIFT、ORB等)检测图像中的特征点,并计算每个特征点的描述符。
3)特征点匹配
使用特征匹配算法(如KNN匹配)来找到两个图像间的对应关系。常见的方法有基于距离的匹配(如欧氏距离、汉明距离等)和基于相似性度量的匹配(如比率测试)。
4)图像配准
根据特征点的匹配结果,使用配准算法(如RANSAC)估计两个图像间的变换矩阵。常见的变换矩阵包括仿射变换、透视变换等。
5)图像变换和拼接
使用估计得到的变换矩阵,将需要拼接的图像进行变换,并将它们拼接在一起。可以使用OpenCV的cv::warpPerspective函数或cv::warpAffine函数来实现变换和拼接。
6)图像调整
对拼接后的图像进行调整,使得拼接边缘平滑过渡,消除拼接处的不连续性。常见的方法包括图像融合、图像平滑等。
二、案例实现
1、定义函数返回图像的关键点和描述符
import cv2
import numpy as np
import sysdef detectAndDescribe(image): # 函数用于gray = cv2.cvtColor(image,cv2.COLOR_BGR2GRAY) # 将影色园片转换成死没图descriptor = cv2.SIFT_create() # 建立SIFT生成器(kps,des) = descriptor.detectAndCompute(gray,None) # 读入参数为灰度图和可选参数掩膜,检测关键点及描述符,返回关键点列表和关键点对应的描述符列表,每个描述符都是一个向量,描述关键点周围图像内容# 此处kps是元组类型,des是ndarry矩阵类型# 将关键点列表的结果转换战NumPy数组kps_float = np.float32([kp.pt for kp in kps])# kp.pt 包含两个值,分别是关键点在图像中的 x 和 y 坐标。这些坐标通常是浮点数,可以精确的捕述关键点在图像中的位置return (kps,kps_float,des) # 返回特征点集,及对应的描述特征
2、定义展示图像函数
def cv_show(name,img): # 函数用于展示图片cv2.imshow(name,img)cv2.waitKey(0)
3、计算读入图像的特征点和描述符
"""读取拼接图片"""
imageA = cv2.imread("1.jpg")
cv_show('imageA',imageA)
imageB = cv2.imread("2.jpg")
cv_show("imageB",imageB)"""计算图片特征点及描述符"""
(kpsA,kps_floatA,desA) = detectAndDescribe(imageA)
(kpsB,kps_floatB,desB) = detectAndDescribe(imageB)
调试模式状态下:
kps对应值:

des对应值:

4、建立暴力匹配器和K近邻算法
1)关于BFMatcher暴力匹配
在图像处理中,特征点匹配是指在不同图像中找到对应的特征点。BFMatcher可用于在两个特征向量集合中计算最佳匹配。它通过计算两个特征向量的相似度(如欧氏距离、汉明距离等),并选择最近邻的特征点作为匹配点。
2)暴力匹配的K近邻
用法:
使用KNN检测来自A、B图的SIFT特征匹配对
# knnMatch(gueryDescriptors, trainDescriptors, k, mask=None, compactResult=None)
参数解析:
queryDescriptors:匹配图像A的描述符
trainDescriptors:匹配图像B的描述符
K:最佳匹配的描述符个数,一般K=2
mask 可选参数:一个掩码数组,用于过滤不需要匹配的特征点。默认为None,表示不使用掩码。
compactResult 可选参数:一个布尔值,指定是否返回紧凑的匹配结果。默认为None,表示根据特征描述符的类型自动选择。
返回值:
distance:匹配的特征点描述符的欧式距离,数值越小也就说明俩个特征点越相近
queryIdx:测试图像的特征点描述符的下标(第几个特征点描述符),同时也是描述符对应特征点的下标。
trainIdx:样本图像的特征点描述符下标,同时也是描述符对应特征点的下标。
3)续接上文代码
matcher = cv2.BFMatcher()
rawMatches = matcher.knnMatch(desB,desA,2) # 对desB中的每个描述符在desA中查找两个最近邻
good = [] # 设置空列表用于存放匹配成功的特征点
matches =[] # 用于存放匹配成功的两个点的索引值
for m in rawMatches:# 当最近距离跟次近距离的比值小于0.65值时,保留此匹配对if len(m) == 2 and m[0].distance < 0.65 * m[1].distance: # len(m) == 2 表示检查是否有两个匹配项# m[0].distance < 0.65 * m[1].distance表示判断匹配的两个点最近邻和次近邻的比值是否小于0.65good.append(m)# 存储两个点在featuresA,featuresB中的索引值matches.append((m[0].trainIdx, m[0].queryIdx))
print(len(good)) # 返回匹配成功的特征点个数
print(matches) # 打印匹配成功点的索引
运行结果:

调试模式rawMatches内容:

5、绘制匹配结果
# 绘制两组关键点的匹配结果,输入参数为B图原图,B图的关键点列表,A图原图,A图的关键点列表,匹配成功的点的坐标,掩码图像默认为None
# flag 表示绘制的标志,cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS表示在关键点周围绘制圆圈,圆圈大小与关键点尺度成比例
vis = cv2.drawMatchesKnn(imageB,kpsB,imageA,kpsA,good,None,flags = cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS)
cv_show('keypoint matches',vis)
运行结果:

6、计算视角变换矩阵
"""透视变换"""
if len(matches) > 4 : # 当前筛选后的匹配对大于4.计算视角变换矩阵# 分别获取匹配成功的A图中点的坐标与B图中点的坐标ptsA = np.float32([kps_floatA[i] for (i,_) in matches]) # kps_floatA是匹配成功点的坐标,matches是通过阈值筛选之后的特征点对象,其中存放匹配成功点的索引,ptsB = np.float32([kps_floatB[i] for (_,i) in matches]) # kps_floatB是图片B中的全就特征点坐标(H, mask) = cv2.findHomography(ptsB, ptsA, cv2.RANSAC, 10)
else:print('图片未找到4个以上的匹配点')sys.exit()
调试模式下
kps_floatA与kps_floatB状态

matches状态
![]()
7、透视变换后拼接
# 根据视角变换矩阵H将原图B进行透视变换,然后将变换后的图片与A进行拼接
result = cv2.warpPerspective(imageB,H,(imageB.shape[1] + imageA.shape[1],imageB.shape[0]))
cv_show('resultB',result)
# 将图片A传入result图片最左端
result[0:imageA.shape[0],0:imageA.shape[1]] = imageA
cv_show('result',result)
运行结果:


8、完整代码:
import cv2
import numpy as np
import sys
def cv_show(name,img): cv2.imshow(name,img)cv2.waitKey(0)def detectAndDescribe(image): gray = cv2.cvtColor(image,cv2.COLOR_BGR2GRAY) descriptor = cv2.SIFT_create() (kps,des) = descriptor.detectAndCompute(gray,None) return (kps,kps_float,des) imageA = cv2.imread("1.jpg")
cv_show('imageA',imageA)
imageB = cv2.imread("2.jpg")
cv_show("imageB",imageB)(kpsA,kps_floatA,desA) = detectAndDescribe(imageA)
(kpsB,kps_floatB,desB) = detectAndDescribe(imageB)rawMatches = matcher.knnMatch(desB,desA,2)
good = []
matches =[]
for m in rawMatches:if len(m) == 2 and m[0].distance < 0.65 * m[1].distance: good.append(m)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 matches',vis)if len(matches) > 4 : ptsA = np.float32([kps_floatA[i] for (i,_) in matches]) ptsB = np.float32([kps_floatB[i] for (_,i) in matches]) (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)
result[0:imageA.shape[0],0:imageA.shape[1]] = imageA
cv_show('result',result)
相关文章:
《深度学习》OpenCV 图像拼接 原理、参数解析、案例实现
目录 一、图像拼接 1、直接看案例 图1与图2展示: 合并完结果: 2、什么是图像拼接 3、图像拼接步骤 1)加载图像 2)特征点检测与描述 3)特征点匹配 4)图像配准 5)图像变换和拼接 6&am…...
Hive数仓操作(三)
一、Hive 数据库操作 1. 创建数据库 基本创建数据库命令: CREATE DATABASE bigdata;说明: 数据库会在 HDFS 中以目录的形式创建和保存,数据库名称会存储在 Hive 的元数据中。如果不指定目录,数据库将在 /user/hive/warehouse 下…...
TDSQL-C电商可视化,重塑电商决策新纪元
前言: 在数字化浪潮席卷全球的今天,电子商务行业以其独特的魅力和无限潜力,成为了推动全球经济增长的重要引擎。然而,随着业务规模的急剧扩张,海量数据的涌现给电商企业带来了前所未有的挑战与机遇。如何高效地处理、…...
翔云 OCR:发票识别与验真
在数字化时代,高效处理大量文档和数据成为企业和个人的迫切需求。翔云 OCR 作为一款强大的光学字符识别工具,在发票识别及验真方面表现出色,为我们带来了极大的便利。 一、翔云 OCR 简介 翔云 OCR 是一款基于先进的人工智能技术开发的文字识别…...
HTML ASCII:Web 开发中的字符编码基础
HTML ASCII:Web 开发中的字符编码基础 ASCII,全称为美国信息交换标准代码(American Standard Code for Information Interchange),是一种用于电子通信的字符编码标准。它最初于1963年提出,用于在不同的计算…...
Meta 首个多模态大模型一键启动!首个多针刺绣数据集上线,含超 30k 张图片
小扎在 Meta Connect 2024 主题演讲中宣布推出首个多模态大模型 Llama 3.2 vision!该模型有 11B 和 90B 两个版本,成为首批支持多模态任务的 Llama 系列模型,根据官方数据,这两个开原模型的性能已超越闭源模型。 小编已经迫不及待…...
阿里云ECS服务器仿真
1.首先使用qemu-img对RAW镜像进行转换,qemu-img convert -O vmdk 1.raw 2.vmdk 2.使用WinHex对镜像的root密码进行删除 3.由于这次阿里云ECS使用了CONFIG_SYSTEM_TRUSTED_KEYS验证,无法直接仿真,需使用live系统对内核进行修改。分为以下几步&…...
如何为树莓派安装操作系统,以及远程操控树莓派的两种方法,无线操控和插网线操控
文章目录 一、下载树莓派的系统二、将文件下载到SD卡中1.使用官方软件2.其他选择 三、远程连接电脑安装vnc-viewer1.无线操作(配置树莓派,开启VNC)电脑远程配置2.有线连接(需要一根网线) 总结 一、下载树莓派的系统 下…...
【最新华为OD机试E卷-支持在线评测】简单的自动曝光(100分)多语言题解-(Python/C/JavaScript/Java/Cpp)
🍭 大家好这里是春秋招笔试突围 ,一枚热爱算法的程序员 💻 ACM金牌🏅️团队 | 大厂实习经历 | 多年算法竞赛经历 ✨ 本系列打算持续跟新华为OD-E/D卷的多语言AC题解 🧩 大部分包含 Python / C / Javascript / Java / Cpp 多语言代码 👏 感谢大家的订阅➕ 和 喜欢�…...
每日一练:等差数列划分
413. 等差数列划分 - 力扣(LeetCode) 题目要求: 如果一个数列 至少有三个元素 ,并且任意两个相邻元素之差相同,则称该数列为等差数列。 例如,[1,3,5,7,9]、[7,7,7,7] 和 [3,-1,-5,-9] 都是等差数列。 给…...
Kotlin真·全平台——Kotlin Compose Multiplatform Mobile(kotlin跨平台方案、KMP、KMM)
前言 随着kotlin代码跨平台方案的推出,kotlin跨平台一度引起不少波澜。但波澜终归没有掀起太大的风浪,作为一个敏捷型开发的公司,依然少不了Android和iOS的同步开发,实际成本和效益并没有太多变化。所以对于大多数公司来说依然风平…...
unity 默认渲染管线材质球的材质通道,材质球的材质通道
标准渲染管线——材质球的材质通道 文档,与内容无关,是介绍材质球的属性的。 https://docs.unity3d.com/2022.1/Documentation/Manual/StandardShaderMaterialParameters.html游戏资源中常见的贴图类型 https://zhuanlan.zhihu.com/p/260973533 十大贴图…...
PostgreSQL升级:使用pg_upgrade进行大版本(16.3)升级(17.0)
1.pg_upgrade工具介绍 pg_upgrade 会创建新的系统表,并以重用旧的数据文件的方式进行升级。 pg_upgrade 的参数选项如下: -b bindir,--old-bindirbindir:旧的 PostgreSQL 可执行文件目录; -B bindir,--new-…...
userdel命令:删除指定Linux用户
一、命令简介 userdel 命令用于删除 Linux 系统中的用户账号。当您不再需要某个用户账号时,可以使用 userdel 命令将其从系统中删除。 二、命令参数 userdel [选项] 用户名一些常用的选项包括: -r, --remove: 删除用户的家目录及邮件目录。…...
QT系统学习篇(1)
一、什么是Qt、Qt的优势 QT是一个跨平台的C图形用户界面库,目前包括Qt Creator、Qt Designer等等快速开发工具。支持所有Linux/Unix系统,还支持windows平台。Qt很容易扩展,并且允许真正的组件编程。(军工企业项目开发基本离不开Q…...
每日一刷——9.26——ACM训练题——Fibonacci Again
题目描述: There are another kind of Fibonacci numbers: F(0) 7, F(1) 11, F(n) F(n-1) F(n-2) (n>2). Input Input consists of a sequence of lines, each containing an integer n. (n < 1,000,000). Output Print the word "yes" if 3 d…...
代码随想录 | Day28 | 回溯算法:组合组合总和III
代码随想录 | Day28 | 回溯算法:组合&&组合总和III 关于这个章节,大家最好是对递归函数的理解要比较到位,听着b站视频课可能呢才舒服点,可以先去搜一搜关于递归函数的讲解,理解,再开始这个章节会比…...
【重学 MySQL】四十五、数据库的创建、修改与删除
【重学 MySQL】四十五、数据库的创建、修改与删除 一条数据存储的过程数据输入数据验证数据处理数据存储数据持久化反馈与日志注意事项 标识符命名规则基本规则长度限制保留字与特殊字符命名建议示例 MySQL 中的数据类型创建数据库创建数据库时指定字符集和排序规则 查看数据库…...
STM32驱动直流电机
stm32通过PWM控制直流电机的方向和速度。 小直流电机需要几百毫安的电流,单片机只能提供几毫安的电流。电机内线圈转动时切割磁感线以及电机内转子线圈的电感效应都会产生反电动势,损坏芯片。 电机驱动芯片能够作为STM32驱动电机的帮手。 SLEEP暂停工作…...
【C++】二叉搜索树+变身 = AVL树
🚀个人主页:小羊 🚀所属专栏:C 很荣幸您能阅读我的文章,诚请评论指点,欢迎欢迎 ~ 目录 前言一、AVL树二、AVL树的实现2.1 平衡因子2.2 旋转处理2.2.1 左单旋:插入新节点后单纯的右边高2.2.2 …...
设计模式和设计原则回顾
设计模式和设计原则回顾 23种设计模式是设计原则的完美体现,设计原则设计原则是设计模式的理论基石, 设计模式 在经典的设计模式分类中(如《设计模式:可复用面向对象软件的基础》一书中),总共有23种设计模式,分为三大类: 一、创建型模式(5种) 1. 单例模式(Sing…...
【JavaEE】-- HTTP
1. HTTP是什么? HTTP(全称为"超文本传输协议")是一种应用非常广泛的应用层协议,HTTP是基于TCP协议的一种应用层协议。 应用层协议:是计算机网络协议栈中最高层的协议,它定义了运行在不同主机上…...
工业安全零事故的智能守护者:一体化AI智能安防平台
前言: 通过AI视觉技术,为船厂提供全面的安全监控解决方案,涵盖交通违规检测、起重机轨道安全、非法入侵检测、盗窃防范、安全规范执行监控等多个方面,能够实现对应负责人反馈机制,并最终实现数据的统计报表。提升船厂…...
无法与IP建立连接,未能下载VSCode服务器
如题,在远程连接服务器的时候突然遇到了这个提示。 查阅了一圈,发现是VSCode版本自动更新惹的祸!!! 在VSCode的帮助->关于这里发现前几天VSCode自动更新了,我的版本号变成了1.100.3 才导致了远程连接出…...
(二)TensorRT-LLM | 模型导出(v0.20.0rc3)
0. 概述 上一节 对安装和使用有个基本介绍。根据这个 issue 的描述,后续 TensorRT-LLM 团队可能更专注于更新和维护 pytorch backend。但 tensorrt backend 作为先前一直开发的工作,其中包含了大量可以学习的地方。本文主要看看它导出模型的部分&#x…...
【快手拥抱开源】通过快手团队开源的 KwaiCoder-AutoThink-preview 解锁大语言模型的潜力
引言: 在人工智能快速发展的浪潮中,快手Kwaipilot团队推出的 KwaiCoder-AutoThink-preview 具有里程碑意义——这是首个公开的AutoThink大语言模型(LLM)。该模型代表着该领域的重大突破,通过独特方式融合思考与非思考…...
CocosCreator 之 JavaScript/TypeScript和Java的相互交互
引擎版本: 3.8.1 语言: JavaScript/TypeScript、C、Java 环境:Window 参考:Java原生反射机制 您好,我是鹤九日! 回顾 在上篇文章中:CocosCreator Android项目接入UnityAds 广告SDK。 我们简单讲…...
Linux-07 ubuntu 的 chrome 启动不了
文章目录 问题原因解决步骤一、卸载旧版chrome二、重新安装chorme三、启动不了,报错如下四、启动不了,解决如下 总结 问题原因 在应用中可以看到chrome,但是打不开(说明:原来的ubuntu系统出问题了,这个是备用的硬盘&a…...
Swagger和OpenApi的前世今生
Swagger与OpenAPI的关系演进是API标准化进程中的重要篇章,二者共同塑造了现代RESTful API的开发范式。 本期就扒一扒其技术演进的关键节点与核心逻辑: 🔄 一、起源与初创期:Swagger的诞生(2010-2014) 核心…...
人工智能(大型语言模型 LLMs)对不同学科的影响以及由此产生的新学习方式
今天是关于AI如何在教学中增强学生的学习体验,我把重要信息标红了。人文学科的价值被低估了 ⬇️ 转型与必要性 人工智能正在深刻地改变教育,这并非炒作,而是已经发生的巨大变革。教育机构和教育者不能忽视它,试图简单地禁止学生使…...
