基于OpenCV中的图像拼接方法详解
文章目录
- 引言
- 一、图像拼接的基本流程
- 二、代码实现详解
- 1. 准备工作
- 2. 特征检测与描述
- detectAndDescribe 函数详解
- (1)函数功能
- (2)代码解析
- (3)为什么需要这个函数?
- (4)输出数据的用途
- 3. 读取图片并提取特征
- 4. 特征点匹配
- 5. 可视化匹配结果
- 6. 计算透视变换矩阵
- 7. 应用变换并拼接图像
- 三、技术要点解析
- 四、改进方向
- 总结
引言
图像拼接是计算机视觉中一项重要的技术,它可以将多张有重叠区域的图片无缝拼接成一张全景图。本文将详细介绍如何使用Python和OpenCV实现基于SIFT特征和透视变换的图像拼接。
一、图像拼接的基本流程
图像拼接主要包含以下几个步骤:
- 读取待拼接的图片
- 检测图片的特征点并计算描述符
- 匹配两张图片的特征点
- 计算透视变换矩阵
- 应用变换并拼接图片
二、代码实现详解
1. 准备工作
首先导入必要的库并定义辅助函数:
import cv2
import numpy as np
import sysdef cv_show(name, img):"""显示图像辅助函数"""cv2.imshow(name, img)cv2.waitKey(0)
2. 特征检测与描述
我们使用SIFT(Scale-Invariant Feature Transform)算法来检测图像的特征点并计算描述符:
def detectAndDescribe(image):"""检测图像特征点并计算描述符"""gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)descriptor = cv2.SIFT_create()# 检测SIFT特征点,并计算描述符(kps, des) = descriptor.detectAndCompute(gray, None)# 将关键点坐标转换为numpy数组kps_float = np.float32([kp.pt for kp in kps])return (kps, kps_float, des)
SIFT算法具有尺度不变性,能够在不同尺度下检测到稳定的特征点,非常适合用于图像拼接。
detectAndDescribe 函数详解
这个函数是图像拼接或特征匹配任务中的关键步骤,主要用于从输入图像中检测关键点 (SIFT特征点) 并计算它们的描述符。下面我将详细解释每一部分的含义和作用:
(1)函数功能
该函数接收一张彩色图像,然后:
- 将图像转换为灰度图
- 使用SIFT算法检测图像中的关键点(特征点)
- 为每个关键点计算描述符(一种数学表示)
- 将关键点坐标转换为NumPy数组格式
- 返回关键点对象、关键点坐标和描述符
(2)代码解析
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
- 将输入的BGR格式彩色图像转换为灰度图像
- 大多数特征检测算法都在灰度图像上工作,因为颜色信息对特征检测通常不是必需的
descriptor = cv2.SIFT_create()
- 创建一个SIFT(Scale-Invariant Feature Transform,尺度不变特征变换)检测器对象
- SIFT是一种经典的特征检测算法,对图像缩放、旋转、亮度变化等具有不变性
(kps, des) = descriptor.detectAndCompute(gray, None)
- 同时检测关键点并计算描述符
- detectAndCompute() 是OpenCV中高效的方法,一步完成检测和计算
- 参数:
- gray: 输入的灰度图像
- None: 可选的掩膜参数,这里不使用
- 返回值:
- kps: 检测到的关键点列表,每个关键点是一个包含多种属性(坐标、尺度、方向等)的对象
- des: 关键点描述符的NumPy数组,每个描述符是一个128维的向量
kps_float = np.float32([kp.pt for kp in kps])
- 将关键点的坐标提取出来并转换为NumPy数组
- kp.pt: 每个关键点的(x, y)坐标属性
- np.float32: 转换为32位浮点数格式,这是许多OpenCV函数要求的输入格式
return (kps, kps_float, des)
- 返回三个值:
- kps: 原始的关键点对象列表(包含完整信息)
- kps_float: 仅包含关键点坐标的NumPy数组
- des: 关键点描述符数组
(3)为什么需要这个函数?
在图像拼接或匹配任务中,我们需要:
- 在两幅图像中找到相同的特征点(关键点)
- 通过这些对应点计算图像间的变换关系
- detectAndDescribe函数封装了第一步的关键操作,为后续的匹配和变换计算提供必要数据
(4)输出数据的用途
- kps: 包含了关键点的完整信息,可用于可视化或进一步分析
- kps_float: 简洁的坐标表示,用于几何变换计算
- des: 用于特征点匹配,通过比较描述符可以找到两幅图像中对应的特征点
这个函数是许多计算机视觉任务(如图像拼接、物体识别、3D重建等)的基础步骤。
3. 读取图片并提取特征
# 读取待拼接图片
imageA = cv2.imread('imageA.jpg')
imageB = cv2.imread('imageB.jpg')# 计算特征点和描述符
(kpsA, kps_floatA, desA) = detectAndDescribe(imageA)
(kpsB, kps_floatB, desB) = detectAndDescribe(imageB)
- imageA 和 imageB 图片如下:
4. 特征点匹配
使用暴力匹配器(BFMatcher)进行特征点匹配:
# 建立暴力匹配器
matcher = cv2.BFMatcher()
rawMatcher = matcher.knnMatch(desB, desA, 2)# 筛选优质匹配点
good = []
matches = []
for m in rawMatcher:# 当最近距离跟次近距离的比值小于0.65时,保留此匹配对if len(m) == 2 and m[0].distance < 0.65 * m[1].distance:good.append(m)matches.append((m[0].queryIdx, m[0].trainIdx))
这里使用了Lowe’s ratio test来筛选优质匹配点,比值阈值设为0.65,可以有效去除错误的匹配。
5. 可视化匹配结果
# 绘制匹配结果
vis = cv2.drawMatchesKnn(imageB, kpsB, imageA, kpsA, good, None, flags=cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS)
cv_show("keypoint matches", vis)
- 显示效果如下:
6. 计算透视变换矩阵
当筛选后的匹配点对大于4个时,可以计算透视变换矩阵:
if len(matches) > 4:# 获取匹配点的坐标ptsB = np.float32([kps_floatB[i] for (i, _) in matches])ptsA = np.float32([kps_floatA[i] for (_, i) in matches])# 使用RANSAC算法计算单应性矩阵(H, mask) = cv2.findHomography(ptsB, ptsA, cv2.RANSAC, 10)
else:print("图片未找到4个以上的匹配点")sys.exit()
findHomography函数使用RANSAC算法来鲁棒地估计变换矩阵,能够有效处理异常值。
7. 应用变换并拼接图像
# 对imageB应用透视变换
result = cv2.warpPerspective(imageB, H, (imageB.shape[1] + imageA.shape[1], imageB.shape[0]))# 将imageA放置在结果图像的左侧
result[0:imageA.shape[0], 0:imageA.shape[1]] = imageA
cv_show('result', result)
- 最终拼接效果图片如下所示:
三、技术要点解析
- SIFT特征:尺度不变特征变换,对旋转、尺度缩放、亮度变化保持不变性
- 特征匹配:使用k近邻算法进行特征匹配,并通过比值测试筛选优质匹配
- RANSAC算法:随机抽样一致算法,用于鲁棒地估计变换矩阵
- 透视变换:通过单应性矩阵将一张图片的视角变换到另一张图片的视角
四、改进方向
- 使用更高效的特征检测算法如ORB
- 添加图像融合技术消除拼接缝
- 优化拼接顺序处理多张图片
- 添加曝光补偿处理不同亮度的图片
总结
通过本文的介绍,相信读者已经对基于特征点的图像拼接技术有了全面的了解。这种技术在计算机视觉领域有着广泛的应用,掌握它将为你的图像处理项目带来更多可能性。
相关文章:

基于OpenCV中的图像拼接方法详解
文章目录 引言一、图像拼接的基本流程二、代码实现详解1. 准备工作2. 特征检测与描述detectAndDescribe 函数详解(1)函数功能(2)代码解析(3)为什么需要这个函数?(4)输出数…...

AI大模型学习二十六、使用 Dify + awesome-digital-human-live2d + ollama + ChatTTS打造数字人
一、说明 数字人(Digital Human) 是指通过人工智能(AI)、计算机图形学、语音合成、动作捕捉等技术创建的虚拟人物。它们具备高度拟人化的外观、语言、表情和动作,能够与人类进行交互,甚至承担特定社会角色。…...

HTML-3.2 表格的跨行跨列(课表制作实例)
本系列可作为前端学习系列的笔记,代码的运行环境是在HBuilder中,小编会将代码复制下来,大家复制下来就可以练习了,方便大家学习。 系列文章目录 HTML-1.1 文本字体样式-字体设置、分割线、段落标签、段内回车以及特殊符号 HTML…...

Spring Cloud Sentinel 快速入门与生产实践指南
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言:流量洪峰下的微服务守卫战 🛡️一、Sentinel 核心架构解析1.1 Sentinel 整体架构1.2 核心处理流程 二、快速入门实战2.1 环境搭建全流程…...
系统架构设计(十):结构化编程
定义 结构化编程是一种遵循清晰逻辑结构、避免使用 goto 的编程方法。它强调使用有限的三种基本控制结构来组织程序,提高程序的可读性、可维护性和可测试性。 它是现代程序设计的基础,被广泛应用于命令式语言(如 C、Pascal、Java࿰…...
标准差和方差是什么
标准差和方差是什么 标准差的简单理解 标准差是衡量一组数据**离散程度(即数据的分散或集中程度 )**的统计量。它表示数据集中每个数值与这组数据平均值的偏离程度。 标准差越大,说明数据越分散,波动越大; 标准差越小,说明数据越集中,波动越小 。 可以把数据想象成一群…...
【周输入】510周阅读推荐-3
前文 【周输入】510周阅读推荐-1-CSDN博客 【周输入】510周阅读推荐-2-CSDN博客 本次推荐 目录 前文 本次推荐 算法技术 模型产品 算法技术 vLLM和DeepSpeed部署模型的优缺点_vllm deepspeed-CSDN博客 优点缺点总结vLLM 适用于推理 优化内存管理 高效并行化 功能单…...

Android平台GB28181设备接入与功能支持详解
GB28181协议作为中国国家标准,广泛应用于安防、智慧城市和交通监控等领域。大牛直播SDK提供了全面支持GB28181设备接入的技术方案,能够有效帮助开发者实现设备的快速接入与管理。在本文中,我们将深入介绍大牛直播SDK在Android平台上对于GB281…...

mvc-ioc实现
IOC 1)耦合/依赖 依赖,是谁离不开谁 就比如上诉的Controller层必须依赖于Service层,Service层依赖于Dao 在软件系统中,层与层之间存在依赖。我们称之为耦合 我们系统架构或者设计的一个原则是ÿ…...

Windows 11 C:\Windows\Web\Wallpaper
Windows 11 C:\Windows\Web\Wallpaper 纯色壁纸自定义 没一个好看的...
医疗信息系统安全防护体系的深度构建与理论实践融合
一、医疗数据访问系统的安全挑战与理论基础 1.1 系统架构安全需求分析 在医疗信息系统中,基于身份标识的信息查询功能通常采用分层架构设计,包括表现层、应用层和数据层。根据ISO/IEC 27001信息安全管理体系要求,此类系统需满足数据保密性…...
Compose笔记(二十五)--Brush
这一节主要了解一下Compose中Brush,在Jetpack Compose里,Brush是一个重要的 API,它用于定义填充图形的颜色渐变或图案,能够为界面元素添加丰富的视觉效果。简单总结如下: 1 常见场景 填充形状(圆形、矩形等) 创建渐变…...

Spring Web MVC————入门(3)
今天我们来一个大练习,我们要实现一个登录界面,登录进去了先获取到登录人信息,可以选择计算器和留言板两个功能,另外我们是学后端的,对于前端我们会些基础的就行了,知道ajax怎么用,知道怎么关联…...
HTML 属性详解
HTML 属性详解 HTML(HyperText Markup Language)是创建网页的标准标记语言。在HTML中,元素可以通过属性来扩展其功能。属性是元素的一个特性,它提供了关于元素的额外信息。本文将详细介绍HTML中的常见属性,帮助您更好地理解和运用HTML。 一、HTML属性的基本概念 HTML属…...

NC61 两数之和【牛客网】
文章目录 零、原题链接一、题目描述二、测试用例三、解题思路3.1 排序双指针3.1 散列 四、参考代码4.1 排序双指针4.2 散列 零、原题链接 NC61 两数之和 一、题目描述 二、测试用例 三、解题思路 3.1 排序双指针 基本思路: 先对序列进行排序,然后…...
Java生成可控的Word表格功能开发
在日常办公自动化与系统集成场景中,生成结构化的Word文档已成为一种刚性需求,尤其是带有格式规范、内容动态填充的Word表格(Table)。本文将围绕如何利用Java开发一个可控的Word表格生成功能模块展开,涵盖技术选型、代码实现、边界控制与常见问题处理等方面,帮助开发者快速…...
Node.js中的洋葱模型
文章目录 前言 前言 Node.js中的洋葱模型是一种中间件执行机制,主要用于处理HTTP请求和响应的流程控制。该模型通过层层包裹的中间件结构,实现请求从外到内穿透、响应从内向外返回的顺序执行。以下从核心概念、实现原理、框架差异及实际应用等方面解析&…...
Spring Boot 中 MyBatis 与 Spring Data JPA 的对比介绍
一、核心概念 MyBatis 定义:基于 SQL 的持久层框架,提供灵活的 SQL 映射和自定义查询能力。 特点: 开发者手动编写 SQL(XML 或注解)。 支持动态 SQL、复杂查询优化。 轻量级,对数据库控制力强。 Spri…...

如何分析动态采样引起的计划不稳定 | OceanBase SQL 调优实践
这篇博客涉及两个知识点,一个是动态采样,另一个是 DAS 执行。 用户的问题和相关结论 我们看看用户在OceanBase 社区论坛发帖中提出的疑问及其所得出的结论。 问题:收集统计信息之前,为什么会出现计划不稳定的情况? …...

如何实现RTSP和RTMP低至100-200ms的延迟:直播SDK的技术突破
在实时音视频传输中,低延迟是直播应用的核心技术要求之一。无论是在线教育、远程医疗,还是实时互动直播,延迟过大会影响用户体验,甚至导致应用无法正常使用。大牛直播SDK(SmartMediaKit)在RTSP和RTMP播放器…...

symfonos: 2靶场
symfonos: 2 来自 <https://www.vulnhub.com/entry/symfonos-2,331/> 1,将两台虚拟机网络连接都改为NAT模式 2,攻击机上做namp局域网扫描发现靶机 nmap -sn 192.168.23.0/24 那么攻击机IP为192.168.23.182,靶场IP192.168.23.253 3&…...

【图像生成大模型】Step-Video-T2V:下一代文本到视频生成技术
Step-Video-T2V:下一代文本到视频生成技术 引言Step-Video-T2V 项目概述核心技术1. 视频变分自编码器(Video-VAE)2. 3D 全注意力扩散 Transformer(DiT w/ 3D Full Attention)3. 视频直接偏好优化(Video-DPO…...
C语言中的指针:从基础到进阶实战
指针是C语言中最具特色且功能强大的特性之一。它们不仅是内存管理的核心工具,还能帮助程序员实现复杂的数据结构和高效算法。本文将从指针的基础知识入手,逐步深入探讨其高级应用,结合实际示例,助你掌握指针的精髓。 一、指针的基…...

深度学习推理引擎---ONNX Runtime
一、基础概念 1. 什么是ONNX Runtime? 定位:由微软开发的跨平台推理引擎,专为优化ONNX(Open Neural Network Exchange)模型的推理性能设计。目标:提供高效、可扩展的推理能力,支持从云到边缘的…...
JAVA Spring MVC+Mybatis Spring MVC的工作流程*,多表连查
目录 注解总结 将传送到客户端的数据转成json数据 **描述一下Spring MVC的工作流程** 1。属性赋值 BeanUtils.copyProperties(addUserDTO,user); 添加依赖: spring web、mybatis framework、mysql driver Controller和ResponseBody优化 直接改成RestControl…...
ctr查看镜像
# 拉取镜像到 k8s.io 命名空间 sudo nerdctl --namespace k8s.io pull nginx:1.23.4 # 验证镜像是否已下载 sudo nerdctl --namespace k8s.io images 下载镜像到k8s.io名称空间下 nerdctl --namespace k8s.io pull zookeeper:3.6.2 sudo ctr image pull --namespace k8s.io …...

VueUse/Core:提升Vue开发效率的实用工具库
文章目录 引言什么是VueUse/Core?为什么选择VueUse/Core?核心功能详解1. 状态管理2. 元素操作3. 实用工具函数4. 浏览器API封装5. 传感器相关 实战示例:构建一个拖拽上传组件性能优化技巧与原生实现对比常见问题解答总结 引言 在现代前端开发…...
数字格式化库 accounting.js的使用说明
accounting.js 是一个用于格式化数字、货币和金额的轻量级库,特别适合财务和会计应用。以下是其详细使用说明: 安装与引入 通过 npm 安装: bash 复制 下载 npm install accounting 引入: javascript 复制 下载 const accounting …...
Docker 网络
目录 前言 1. Docker 网络模式 2. 默认 bridge 网络详解 (1)特点 (2)操作示例 3. host 网络模式 (1)特点 (2)操作示例 4. overlay…...

【论文阅读】A Survey on Multimodal Large Language Models
目录 前言一、 背景与核心概念1-1、多模态大语言模型(MLLMs)的定义 二、MLLMs的架构设计2-1、三大核心模块2-2、架构优化趋势 三、训练策略与数据3-1、 三阶段训练流程 四、 评估方法4-1、 闭集评估(Closed-set)4-2、开集评估&…...