OpenCV-图像拼接
文章目录
- 一、基本原理
- 二、步骤
- 三、代码实现
- 1.定义函数
- 2.读取图像
- 3.图像配准
- (1).特征点检测
- (2).特征匹配
- 4.透视变换
- 5.图像拼接
- 四、图像拼接的注意事项
图像拼接是一种将多张有重叠部分的图像合并成一张无缝的全景图或高分辨率图像的技术。它在许多领域都有广泛的应用,如摄影、虚拟现实、医学成像等。
一、基本原理
图像拼接的基本原理是通过找到不同图像之间的相似性或重叠区域,利用这些区域将图像无缝地融合在一起,形成一幅更大的图像。这个过程通常包括图像预处理、图像配准、建立变换模型、统一坐标变换以及融合重构等步骤。
二、步骤
- 图像预处理
- 去噪:去除图像中的噪声,提高图像质量。
- 边缘提取:提取图像的边缘信息,有助于后续的配准和融合。
- 直方图处理:调整图像的亮度、对比度等,使不同图像在视觉上更加一致。
- 图像配准
- 特征点检测:使用算法(如SIFT、SURF、ORB等)检测图像中的特征点。
- 特征匹配:根据特征点的描述符进行匹配,找到不同图像之间的对应点。
- 变换关系计算:根据匹配点计算图像之间的变换关系,如单应性矩阵或仿射变换矩阵。
- 建立变换模型
- 根据匹配点之间的对应关系,建立数学模型,描述图像之间的变换关系。
- 统一坐标变换
- 将待拼接图像根据变换模型转换到同一坐标系中,使图像在空间位置上对齐。
- 图像融合
- 在图像的重叠区域进行融合处理,消除拼接痕迹,使拼接后的图像看起来自然无缝。
- 融合方法包括多带混合、泊松图像编辑等。
三、代码实现
在OpenCV中,图像拼接通常涉及到特征检测、特征匹配、计算变换矩阵(如单应性矩阵或仿射变换矩阵)以及使用这些矩阵将图像变换到统一坐标系下,最后进行图像拼接的过程。
1.定义函数
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)kps_float = np.float32([kp.pt for kp in kps])return (kps, kps_float, des)
- 首先我们定义了两个函数,cv_show用来展示图像,detectAndDescribe使用了 OpenCV 的
SIFT(尺度不变特征变换)算法来检测图像中的关键点和计算这些关键点的描述符。
2.读取图像
"""读取图片"""
imageA = cv2.imread('xiangjiA.jpg')
cv_show('A', imageA)
imageB = cv2.imread('xiangjiB.jpg')
# imageB = cv2.resize(imageB,(662, 604))
cv_show('B', imageB)
- 使用cv2.imread()读取图片。
- 使用cv_show()函数显示图片。

3.图像配准
(1).特征点检测
"""计算图片特征点及描述符"""
(kpsA, kps_floatA, desA) = detectAndDescribe(imageA)
(kpsB, kps_floatB, desB) = detectAndDescribe(imageB)
- 调用定义的函数detectAndDescribe
- 将图片转换为灰度图。
- 使用SIFT算法(cv2.SIFT_create())检测特征点和计算描述符。
(2).特征匹配
"""建立暴力匹配器BFMatcher,在匹配大型训练集合时使用FlannBaesdMatcher速度快"""
matcher = cv2.BFMatcher()
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:goodB.append(m)matchesB.append((m[0].trainIdx, m[0].queryIdx))
rawMatchesA = matcher.knnMatch(desA, desB, 2)
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 Maxtchs', vis)
- 使用BFMatcher(暴力匹配器)进行特征点匹配,并应用Lowe’s ratio test来筛选好的匹配点。
- 分别计算从imageB到imageA的匹配点。

4.透视变换
"""透视变换"""
if len(matches) > 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]))
- 如果匹配点数量超过4个,则使用cv2.findHomography()计算单应性矩阵。
- 使用单应性矩阵和cv2.warpPerspective()进行透视变换。
5.图像拼接
cv_show('result', result)
result[0:imageA.shape[0], 0:imageA.shape[1]] = imageA
cv_show('resultB', result)
- 将变换后的图片与另一张图片合并,并显示结果。这里我们是从图像左上角位置开始合并。


以上是一个基本的图像拼接流程。在实际应用中,可能需要调整特征检测器的参数、匹配阈值以及RANSAC的阈值,以获得最佳结果。此外,对于复杂场景或大规模数据集,可能还需要考虑并行处理和优化内存使用等问题。
四、图像拼接的注意事项
- 确保图像有重叠部分:图像拼接依赖于图像之间的重叠区域,因此确保待拼接图像有足够的重叠是非常重要的。
- 选择合适的拼接方法:不同的拼接方法适用于不同的场景和需求,选择合适的拼接方法可以获得更好的效果。
- 调整参数:在拼接过程中,可能需要调整一些参数(如特征点检测器的阈值、匹配阈值等),以获得最佳的拼接效果。
- 检查拼接效果:拼接完成后,仔细检查拼接效果,确保没有明显的拼接痕迹或失真现象。
通过以上步骤和注意事项,可以实现高质量的图像拼接,满足各种应用需求。
相关文章:
OpenCV-图像拼接
文章目录 一、基本原理二、步骤三、代码实现1.定义函数2.读取图像3.图像配准(1).特征点检测(2).特征匹配 4.透视变换5.图像拼接 四、图像拼接的注意事项 图像拼接是一种将多张有重叠部分的图像合并成一张无缝的全景图或高分辨率图…...
C++【类和对象】(取地址运算符重载与实现Date类)
文章目录 取地址运算符重载const成员函数取地址运算符重载 Date类的实现Date.hDate.cpp1.检查日期合法性2. 构造函数/赋值运算符重载3.得到某月的天数4. Date类 - 天数的操作4.1 日期 天数4.2 日期 天数4.3 日期 - 天数4.4 日期 - 天数 5. Date的前后置/--5.1 前置5.2 后置5.…...
oracle 数据库中的异常和游标管理
异常和游标管理 游标: 用来查询数据库,获取记录集合(结果集)的指针,可以让开发者一次访问一行结果集,在每条结果集上作操作。 分类: 静态游标: 分为显式游标和隐式游标。 REF游标&…...
关于python 日志设定为INFO 但是DEBUG仍旧写入的问题
问题:将logging设定为了INFO级别,但是在打印的时候发现jieba包中的DEBUG级别的信息还是出现了。 原因:在我引用的包中,一些python文件也使用了logging,我设定的INFO级别只能设定我当前使用的文件,而调用的包…...
TypeScript 语法基础 第一部分 类型
【视频链接】尚硅谷TypeScript教程(李立超老师TS新课) TypeScript TypeScript 语法基础 第二部分 类、接口、泛型1. 类型1.1 | 联合类型1.2 字面量类型1.3 any 任意类型1.4 unkown 类型1.5 as 类型断言1.6 object 对象类型1.7 { } 对象类型1.8 ÿ…...
GO Serial 学习与使用
文章目录 主要特性安装基本用法配置选项错误处理其他功能 github.com/goburrow/serial 是一个 Go 包,提供了一种简单的方式来与串口进行交互。以下是该包的主要特性和用法的简要概述: 主要特性 跨平台支持:支持 Windows、macOS 和 Linux。简…...
安卓app开发系列之-常用工具与库
✨ 关于我 ✨ 👨💻 Hi there! 我是 [Jamson],一名热爱编程与技术的狂热者,致力于前后端的全栈独立软件系统开发。通过不断学习和实践,我希望将知识分享给更多的朋友们,和大家一起成长。 💡 &…...
视频汇聚EasyCVR视频监控平台调取接口提示“认证过期”是什么原因?
视频汇聚EasyCVR视频监控平台,作为一款智能视频监控综合管理平台,凭借其强大的视频融合汇聚能力和灵活的视频能力,在各行各业的应用中发挥着越来越重要的作用。EasyCVR平台具备强大的拓展性和灵活性,支持多种视频流的外部分发&…...
uniapp视频禁止用户推拽进度条并保留进度条显示的解决方法——方案二
在uniapp项目中,使用<video>组件播放视频非常方便。默认情况下,视频组件会显示进度条,用户可以随意拖动进度条来控制视频播放进度。然而,在某些特定场景,如在线教育、广告宣传等,我们希望禁止用户拖动…...
mysql复合查询 -- 多表查询(介绍,笛卡尔积,使用),自连接(介绍,使用)
目录 多表查询 介绍 使用 表数据 显示雇员名,雇员工资,以及所在部门名 显示部门号为10的部门名,员工名,工资 自连接 介绍 场景 表数据 题目 子查询 自连接 多表查询 介绍 实际开发中往往数据来自不同的表,所以需要多表查询 语法: from 表1,表2 (笛卡…...
【个人笔记】数据一致性的解决方案
保证数据一致性:指保证redis里的数据和mysql的数据是一致的,不能说mysql更新了,但redis里面的还是旧的数据,反之亦然 先说结论:增删改的时候,把Redis中的缓存删了 为什么不先更新数据库,再更新…...
【WPF】多屏幕展示
使用环境为.Net Framework,如果有.Net 6的解决方案,欢迎交流。 话不多说,先上代码! /// <summary>/// Window窗口展示设置/// </summary>/// <param name"monitor"></param>/// <param nam…...
vue admin 若依框架 解决无权限时进入死循环的问题 auths
核心原因: if (auths && auths.length > 0) { // like12 find bug,数组为空[]时依然会进入死循环 原来为:if (auths) // 获取用户信息getInfo({ commit, state }) {return new Promise((resolve, reject) > {getInfo(state.token).then(…...
kubernetes存储入门(kubernetes)
实验环境依旧是三个节点拉取镜像,然后在master节点拉取资源清单: 然后同步会话,导入镜像; 存储入门 ConfigMap volume卷--》volumemount(挂载卷) Glusterfs NFS ISCSI HostPath ConfigMap Secret E…...
局部代理有什么好处?为什么不使用全局代理?
1. 什么是局部代理与全局代理? 局部代理:局部代理只会对特定应用程序或特定的网络流量进行代理,而不会影响其他网络流量。例如,你可以设置浏览器使用代理,而其他应用程序如邮件客户端或游戏仍然使用本地网络连接。 全…...
ssm模糊知识点整合
一、参数绑定常用注解 RequestParam:用于将请求参数绑定到你的方法参数上。 PathVariable:用于将路径变量绑定到你的方法参数上。 RequestBody:用于将请求主体绑定到你的方法参数上,通常用于绑定POST请求的JSON或XML数据。 Req…...
2、Spring Boot 3.x 集成 Feign
一、前言 本篇主要是围绕着两个点,1、集成 Feign,2、分离feign接口层,独立服务; 还有一点就是上篇文章的服务 iot-channel、system-server 服务名称调整成为了 chain-iot-channel、chain-system二、搭建 chain-common 服务 pom.…...
深度学习-图像处理篇-5ResNet和ResNeXt
解决问题: 梯度消失或梯度爆炸 退化问题(degradation problem) 迁移学习 ResNeXt...
类的关联、依赖、聚合和组合关系的思考(一)
最近在看《设计模式》这本书,发现对类之间的关系还没搞的很明白,而类之间的关系对读书、阅读代码和代码设计都非常重要,因此边看书边查阅了一些资料,感觉有些理解了。下面是我的一些思考,分享一下。 查阅了很多博客&a…...
云舟观测:集成开源Grafana Faro构建前端页面性能监控平台
在当今互联网时代,面对纷乱繁杂的网上资源,用户的耐心和注意力是极为宝贵的资源,当用户访问一个网站或应用时,他们期望的是快速且无缝的体验,任何加载延迟或功能故障都可能导致用户流失,影响品牌体验。因此…...
手把手教你用LTspice仿真DAB双有源桥DC-DC变换器(单移相SPS控制篇)
从零开始用LTspice仿真DAB变换器:单移相控制实战指南 在电力电子领域,双有源桥(DAB)DC-DC变换器因其高效率、双向功率流和电气隔离特性,成为新能源系统、电动汽车充电和直流微电网中的关键组件。但对于初学者来说&…...
nli-distilroberta-base保姆级教学:从镜像拉取→端口映射→API测试全流程
nli-distilroberta-base保姆级教学:从镜像拉取→端口映射→API测试全流程 1. 项目概述 nli-distilroberta-base是一个基于DistilRoBERTa模型的自然语言推理(NLI)Web服务,专门用于判断两个句子之间的逻辑关系。这个轻量级模型能够快速准确地分析句子对&…...
OpenClaw 采用分层解耦的架构设计,请详细说明其核心架构分层(至少 4 层)及各层的核心职责,并描述一条自然语言指令从输入到任务完成的完整执行闭环流程。
一、核心架构分层(四层/五层模型) OpenClaw 采用 分层解耦的模块化架构,主流技术文档将其划分为 四层核心架构,部分资料扩展为五层。以下是整合后的完整架构: 层级名称核心职责关键技术组件第一层交互接入层(Interfa…...
DanKoe 视频笔记:生产力提升:专注工作的力量 [特殊字符]
在本节课中,我们将要学习如何通过每天仅 4 小时的专注工作,来显著改变你的生活轨迹。我们将探讨注意力的价值、识别高回报机会的方法,并掌握一套进入并保持深度专注状态的实用技巧。 能够有意识地引导你的注意力,不仅能节省时间&a…...
NaViL-9B效果惊艳:复杂背景证件照文字识别+人像属性分析展示
NaViL-9B效果惊艳:复杂背景证件照文字识别人像属性分析展示 1. 模型能力概览 NaViL-9B作为原生多模态大语言模型,在证件照处理领域展现出惊人的能力。它不仅能够准确识别复杂背景下的文字信息,还能对人像属性进行智能分析,为证件…...
Ostrakon-VL-8B模型压缩实践:在有限显存下的部署与推理
Ostrakon-VL-8B模型压缩实践:在有限显存下的部署与推理 你是不是也遇到过这样的情况:好不容易找到一个功能强大的视觉语言大模型,比如最近挺火的Ostrakon-VL-8B,结果一看显存要求,直接傻眼了——动辄需要几十个G的显存…...
快速部署:在星图AI平台训练PETRV2-BEV模型,支持NuScenes数据集
快速部署:在星图AI平台训练PETRV2-BEV模型,支持NuScenes数据集 1. 环境准备与快速部署 1.1 激活Paddle3D环境 首先需要确保已经创建并激活了Paddle3D的conda环境: conda activate paddle3d_env如果尚未创建该环境,建议先安装M…...
LightOnOCR-2-1B GPU优化实践:vLLM推理引擎配置与显存占用压测报告
LightOnOCR-2-1B GPU优化实践:vLLM推理引擎配置与显存占用压测报告 你是不是也遇到过这样的烦恼?部署一个OCR模型,明明看着参数不大,但一跑起来,显存就蹭蹭往上涨,甚至直接爆掉。或者,服务启动…...
GIS工作者必看:如何用SimpleGIS插件解决遥感影像配准难题(含Bing/天地图无偏移地图技巧)
GIS工程师实战指南:SimpleGIS插件在遥感影像配准中的高阶应用 遥感影像配准是GIS工作中的基础操作,却也是最容易出错的环节之一。作为一名长期与影像数据打交道的GIS工程师,我深知配准偏差带来的困扰——从项目返工到数据可信度质疑ÿ…...
10分钟搭建FunASR智能语音点餐系统:餐饮服务革命性升级指南
10分钟搭建FunASR智能语音点餐系统:餐饮服务革命性升级指南 FunASR是一个开源的端到端语音识别工具包,提供了SOTA预训练模型,能够帮助开发者快速构建语音交互应用。本文将详细介绍如何在10分钟内利用FunASR搭建智能语音点餐系统,…...
