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

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.图像配准&#xff08;1&#xff09;.特征点检测&#xff08;2&#xff09;.特征匹配 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 数据库中的异常和游标管理

异常和游标管理 游标&#xff1a; 用来查询数据库&#xff0c;获取记录集合&#xff08;结果集&#xff09;的指针&#xff0c;可以让开发者一次访问一行结果集&#xff0c;在每条结果集上作操作。 分类&#xff1a; 静态游标&#xff1a; 分为显式游标和隐式游标。 REF游标&…...

关于python 日志设定为INFO 但是DEBUG仍旧写入的问题

问题&#xff1a;将logging设定为了INFO级别&#xff0c;但是在打印的时候发现jieba包中的DEBUG级别的信息还是出现了。 原因&#xff1a;在我引用的包中&#xff0c;一些python文件也使用了logging&#xff0c;我设定的INFO级别只能设定我当前使用的文件&#xff0c;而调用的包…...

TypeScript 语法基础 第一部分 类型

【视频链接】尚硅谷TypeScript教程&#xff08;李立超老师TS新课&#xff09; TypeScript TypeScript 语法基础 第二部分 类、接口、泛型1. 类型1.1 | 联合类型1.2 字面量类型1.3 any 任意类型1.4 unkown 类型1.5 as 类型断言1.6 object 对象类型1.7 { } 对象类型1.8 &#xff…...

GO Serial 学习与使用

文章目录 主要特性安装基本用法配置选项错误处理其他功能 github.com/goburrow/serial 是一个 Go 包&#xff0c;提供了一种简单的方式来与串口进行交互。以下是该包的主要特性和用法的简要概述&#xff1a; 主要特性 跨平台支持&#xff1a;支持 Windows、macOS 和 Linux。简…...

安卓app开发系列之-常用工具与库

✨ 关于我 ✨ &#x1f468;‍&#x1f4bb; Hi there! 我是 [Jamson]&#xff0c;一名热爱编程与技术的狂热者&#xff0c;致力于前后端的全栈独立软件系统开发。通过不断学习和实践&#xff0c;我希望将知识分享给更多的朋友们&#xff0c;和大家一起成长。 &#x1f4a1; &…...

视频汇聚EasyCVR视频监控平台调取接口提示“认证过期”是什么原因?

视频汇聚EasyCVR视频监控平台&#xff0c;作为一款智能视频监控综合管理平台&#xff0c;凭借其强大的视频融合汇聚能力和灵活的视频能力&#xff0c;在各行各业的应用中发挥着越来越重要的作用。EasyCVR平台具备强大的拓展性和灵活性&#xff0c;支持多种视频流的外部分发&…...

uniapp视频禁止用户推拽进度条并保留进度条显示的解决方法——方案二

在uniapp项目中&#xff0c;使用<video>组件播放视频非常方便。默认情况下&#xff0c;视频组件会显示进度条&#xff0c;用户可以随意拖动进度条来控制视频播放进度。然而&#xff0c;在某些特定场景&#xff0c;如在线教育、广告宣传等&#xff0c;我们希望禁止用户拖动…...

mysql复合查询 -- 多表查询(介绍,笛卡尔积,使用),自连接(介绍,使用)

目录 多表查询 介绍 使用 表数据 显示雇员名,雇员工资,以及所在部门名 显示部门号为10的部门名,员工名,工资 自连接 介绍 场景 表数据 题目 子查询 自连接 多表查询 介绍 实际开发中往往数据来自不同的表&#xff0c;所以需要多表查询 语法: from 表1,表2 (笛卡…...

【个人笔记】数据一致性的解决方案

保证数据一致性&#xff1a;指保证redis里的数据和mysql的数据是一致的&#xff0c;不能说mysql更新了&#xff0c;但redis里面的还是旧的数据&#xff0c;反之亦然 先说结论&#xff1a;增删改的时候&#xff0c;把Redis中的缓存删了 为什么不先更新数据库&#xff0c;再更新…...

【WPF】多屏幕展示

使用环境为.Net Framework&#xff0c;如果有.Net 6的解决方案&#xff0c;欢迎交流。 话不多说&#xff0c;先上代码&#xff01; /// <summary>/// Window窗口展示设置/// </summary>/// <param name"monitor"></param>/// <param nam…...

vue admin 若依框架 解决无权限时进入死循环的问题 auths

核心原因&#xff1a; if (auths && auths.length > 0) { // like12 find bug,数组为空[]时依然会进入死循环 原来为&#xff1a;if (auths) // 获取用户信息getInfo({ commit, state }) {return new Promise((resolve, reject) > {getInfo(state.token).then(…...

kubernetes存储入门(kubernetes)

实验环境依旧是三个节点拉取镜像&#xff0c;然后在master节点拉取资源清单&#xff1a; 然后同步会话&#xff0c;导入镜像&#xff1b; 存储入门 ConfigMap volume卷--》volumemount&#xff08;挂载卷&#xff09; Glusterfs NFS ISCSI HostPath ConfigMap Secret E…...

局部代理有什么好处?为什么不使用全局代理?

1. 什么是局部代理与全局代理&#xff1f; 局部代理&#xff1a;局部代理只会对特定应用程序或特定的网络流量进行代理&#xff0c;而不会影响其他网络流量。例如&#xff0c;你可以设置浏览器使用代理&#xff0c;而其他应用程序如邮件客户端或游戏仍然使用本地网络连接。 全…...

ssm模糊知识点整合

一、参数绑定常用注解 RequestParam&#xff1a;用于将请求参数绑定到你的方法参数上。 PathVariable&#xff1a;用于将路径变量绑定到你的方法参数上。 RequestBody&#xff1a;用于将请求主体绑定到你的方法参数上&#xff0c;通常用于绑定POST请求的JSON或XML数据。 Req…...

2、Spring Boot 3.x 集成 Feign

一、前言 本篇主要是围绕着两个点&#xff0c;1、集成 Feign&#xff0c;2、分离feign接口层&#xff0c;独立服务&#xff1b; 还有一点就是上篇文章的服务 iot-channel、system-server 服务名称调整成为了 chain-iot-channel、chain-system二、搭建 chain-common 服务 pom.…...

深度学习-图像处理篇-5ResNet和ResNeXt

解决问题&#xff1a; 梯度消失或梯度爆炸 退化问题(degradation problem) 迁移学习 ResNeXt...

类的关联、依赖、聚合和组合关系的思考(一)

最近在看《设计模式》这本书&#xff0c;发现对类之间的关系还没搞的很明白&#xff0c;而类之间的关系对读书、阅读代码和代码设计都非常重要&#xff0c;因此边看书边查阅了一些资料&#xff0c;感觉有些理解了。下面是我的一些思考&#xff0c;分享一下。 查阅了很多博客&a…...

云舟观测:集成开源Grafana Faro构建前端页面性能监控平台

在当今互联网时代&#xff0c;面对纷乱繁杂的网上资源&#xff0c;用户的耐心和注意力是极为宝贵的资源&#xff0c;当用户访问一个网站或应用时&#xff0c;他们期望的是快速且无缝的体验&#xff0c;任何加载延迟或功能故障都可能导致用户流失&#xff0c;影响品牌体验。因此…...

【SQL学习笔记1】增删改查+多表连接全解析(内附SQL免费在线练习工具)

可以使用Sqliteviz这个网站免费编写sql语句&#xff0c;它能够让用户直接在浏览器内练习SQL的语法&#xff0c;不需要安装任何软件。 链接如下&#xff1a; sqliteviz 注意&#xff1a; 在转写SQL语法时&#xff0c;关键字之间有一个特定的顺序&#xff0c;这个顺序会影响到…...

Nuxt.js 中的路由配置详解

Nuxt.js 通过其内置的路由系统简化了应用的路由配置&#xff0c;使得开发者可以轻松地管理页面导航和 URL 结构。路由配置主要涉及页面组件的组织、动态路由的设置以及路由元信息的配置。 自动路由生成 Nuxt.js 会根据 pages 目录下的文件结构自动生成路由配置。每个文件都会对…...

学习STC51单片机31(芯片为STC89C52RCRC)OLED显示屏1

每日一言 生活的美好&#xff0c;总是藏在那些你咬牙坚持的日子里。 硬件&#xff1a;OLED 以后要用到OLED的时候找到这个文件 OLED的设备地址 SSD1306"SSD" 是品牌缩写&#xff0c;"1306" 是产品编号。 驱动 OLED 屏幕的 IIC 总线数据传输格式 示意图 …...

工业自动化时代的精准装配革新:迁移科技3D视觉系统如何重塑机器人定位装配

AI3D视觉的工业赋能者 迁移科技成立于2017年&#xff0c;作为行业领先的3D工业相机及视觉系统供应商&#xff0c;累计完成数亿元融资。其核心技术覆盖硬件设计、算法优化及软件集成&#xff0c;通过稳定、易用、高回报的AI3D视觉系统&#xff0c;为汽车、新能源、金属制造等行…...

pikachu靶场通关笔记22-1 SQL注入05-1-insert注入(报错法)

目录 一、SQL注入 二、insert注入 三、报错型注入 四、updatexml函数 五、源码审计 六、insert渗透实战 1、渗透准备 2、获取数据库名database 3、获取表名table 4、获取列名column 5、获取字段 本系列为通过《pikachu靶场通关笔记》的SQL注入关卡(共10关&#xff0…...

【生成模型】视频生成论文调研

工作清单 上游应用方向&#xff1a;控制、速度、时长、高动态、多主体驱动 类型工作基础模型WAN / WAN-VACE / HunyuanVideo控制条件轨迹控制ATI~镜头控制ReCamMaster~多主体驱动Phantom~音频驱动Let Them Talk: Audio-Driven Multi-Person Conversational Video Generation速…...

[免费]微信小程序问卷调查系统(SpringBoot后端+Vue管理端)【论文+源码+SQL脚本】

大家好&#xff0c;我是java1234_小锋老师&#xff0c;看到一个不错的微信小程序问卷调查系统(SpringBoot后端Vue管理端)【论文源码SQL脚本】&#xff0c;分享下哈。 项目视频演示 【免费】微信小程序问卷调查系统(SpringBoot后端Vue管理端) Java毕业设计_哔哩哔哩_bilibili 项…...

打手机检测算法AI智能分析网关V4守护公共/工业/医疗等多场景安全应用

一、方案背景​ 在现代生产与生活场景中&#xff0c;如工厂高危作业区、医院手术室、公共场景等&#xff0c;人员违规打手机的行为潜藏着巨大风险。传统依靠人工巡查的监管方式&#xff0c;存在效率低、覆盖面不足、判断主观性强等问题&#xff0c;难以满足对人员打手机行为精…...

通过 Ansible 在 Windows 2022 上安装 IIS Web 服务器

拓扑结构 这是一个用于通过 Ansible 部署 IIS Web 服务器的实验室拓扑。 前提条件&#xff1a; 在被管理的节点上安装WinRm 准备一张自签名的证书 开放防火墙入站tcp 5985 5986端口 准备自签名证书 PS C:\Users\azureuser> $cert New-SelfSignedCertificate -DnsName &…...

LCTF液晶可调谐滤波器在多光谱相机捕捉无人机目标检测中的作用

中达瑞和自2005年成立以来&#xff0c;一直在光谱成像领域深度钻研和发展&#xff0c;始终致力于研发高性能、高可靠性的光谱成像相机&#xff0c;为科研院校提供更优的产品和服务。在《低空背景下无人机目标的光谱特征研究及目标检测应用》这篇论文中提到中达瑞和 LCTF 作为多…...