使用OpenCV实现图像拼接

server/2024/11/28 4:53:12/
摘要

图像拼接技术在计算机视觉领域有着广泛的应用,如全景图生成、卫星影像拼接等。本文将详细介绍如何使用OpenCV库实现图像拼接,包括特征点检测、描述符提取、特征匹配、透视变换等关键步骤。通过一个实际的代码示例,我们将逐步展示如何将两张图片拼接成一张全景图。

1. 引言

图像拼接的基本思想是从多张图片中提取特征点,并通过匹配这些特征点来估计图像之间的几何变换关系,最终将这些图像合成一张全景图。OpenCV 提供了丰富的工具和算法来支持这一过程,包括 SIFT 特征检测、BFMatcher 特征匹配以及透视变换等。

2. 环境准备

在开始之前,请确保已经安装了 OpenCV 库。如果没有安装,可以通过以下命令安装:

pip install opencv-python
pip install opencv-contrib-python
3. 代码实现
3.1 导入必要的库
import cv2
import numpy as np
import sys
3.2 定义辅助函数

为了方便显示图像,定义一个简单的显示函数 cv_show

def cv_show(name, img):cv2.imshow(name, img)cv2.waitKey(0)
3.3 特征点检测与描述符提取

定义一个函数 detectAndDescribe,用于检测图像中的特征点并计算描述符:

def detectAndDescribe(image):gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)   # 将彩色图像转换成灰度图descriptor = cv2.SIFT_create()   # 建立SIFT生成器(kps, des) = descriptor.detectAndCompute(gray, None)  # 检测SIFT特征点,并计算描述符kps_float = np.float32([kp.pt for kp in kps])  # 将结果转换成NumPy数组return (kps, kps_float, des)   # 返回特征点集,及对应的描述特征
3.4 读取并显示图像

读取两张待拼接的图像,并显示它们:

imageA = cv2.imread(r'picture_video\1.jpg')
cv_show('imageA', imageA)
imageB = cv2.imread(r'picture_video\2.jpg')
cv_show('imageB', imageB)
3.5 计算图像特征点及描述符

对两张图像分别进行特征点检测和描述符提取:

(kpsA, kps_floatA, desA) = detectAndDescribe(imageA)
(kpsB, kps_floatB, desB) = detectAndDescribe(imageB)
3.6 特征匹配

使用 BFMatcher 进行特征匹配,筛选出高质量的匹配对:

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:good.append(m)matches.append((m[0].trainIdx, m[0].queryIdx))print(f"Number of good matches: {len(good)}")
print(f"Matches: {matches}")
3.7 绘制匹配结果

将匹配结果可视化,以便观察匹配效果:

vis = cv2.drawMatchesKnn(imageB, kpsB, imageA, kpsA, good, None, flags=cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS)
cv_show('keypoint matches', vis)
3.8 透视变换

如果匹配对的数量大于4,计算透视变换矩阵并进行图像拼接:

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)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]] = imageAcv_show('result', result)
else:print('图片未找到4个以上的匹配点')sys.exit()
4. 结果展示

通过上述步骤,我们可以成功地将两张图像拼接成一张全景图。最终的拼接结果如下所示:

5. 总结

本文详细介绍了如何使用 OpenCV 实现图像拼接,包括特征点检测、描述符提取、特征匹配、透视变换等关键步骤。通过一个实际的代码示例,展示了如何将两张图像拼接成一张全景图。希望本文能为读者在计算机视觉领域的学习和研究提供帮助。


http://www.ppmy.cn/server/145531.html

相关文章

音视频技术扫盲之预测编码的基本原理探究

预测编码是一种数据压缩技术&#xff0c;广泛应用于图像、视频和音频编码等领域。其基本原理是利用数据的相关性&#xff0c;通过对当前数据的预测和实际值与预测值之间的差值进行编码&#xff0c;从而实现数据压缩的目的。 一、预测编码的基本概念 预测编码主要包括预测器和…

35 基于单片机的精确电压表DA-AD转换

目录 一、主要功能 二、硬件资源 三、程序编程 四、实现现象 一、主要功能 基于51单片机&#xff0c;采用DAC0832和ADC0832检测电压&#xff0c;0到8.5V&#xff0c;设计复位电路 LED管显示实际稳压值&#xff0c;初始电压0 二、硬件资源 基于KEIL5编写C代码&#xff0c…

钉钉数据如何高效集成到金蝶云星空系统

钉钉数据集成到金蝶云星空的技术案例分享 在企业日常运营中&#xff0c;办公用品采购流程的高效管理至关重要。为了实现这一目标&#xff0c;我们采用了轻易云数据集成平台&#xff0c;将钉钉中的采购申请单数据无缝对接到金蝶云星空系统中。本次案例将详细解析【办公用品采购…

LeetCode—704. 二分查找(简单)

仅供个人学习使用 题目描述&#xff1a; 给定一个 n 个元素有序的&#xff08;升序&#xff09;整型数组 nums 和一个目标值 target &#xff0c;写一个函数搜索 nums 中的 target&#xff0c;如果目标值存在返回下标&#xff0c;否则返回 -1。 示例 1: 输入: nums [-1,0,3…

SCAU软件体系结构实验四 组合模式

目录 一、题目 二、源码 一、题目 个人(Person)与团队(Team)可以形成一个组织(Organization)&#xff1a;组织有两种&#xff1a;个人组织和团队组织&#xff0c;多个个人可以组合成一个团队&#xff0c;不同的个人与团队可以组合成一个更大的团队。 使用控制台或者JavaFx界面…

两个docker之间的服务相互访问

背景 测试阶段, 两个模型分别封装了两个docker环境, 都是封装成了接口形式, 比如dockerA 和dockerB环境. Docker环境联通 创建自定义的bridge网络 docker network create testnet(自定义名称)查询到新创建的bridge testnet docker network ls运行容器连接到testnet网络 d…

centos 服务器 docker 使用代理

宿主机使用代理 在宿主机的全局配置文件中添加代理信息 vim /etc/profile export http_proxyhttp://127.0.0.1:7897 export https_proxyhttp://127.0.0.1:7897 export no_proxy"localhost,127.0.0.1,::1,172.171.0.0" docker 命令使用代理 例如我想在使用使用 do…

RabbitMQ原理架构解析:消息传递的核心机制

文章目录 一、RabbitMQ简介1.1、概述1.2、特性 二、RabbitMQ原理架构三、RabbitMQ应用场景3.1、简单模式3.2、工作模式3.3、发布订阅3.4、路由模式3.5 主题订阅模式 四、同类中间件对比五、RabbitMQ部署5.1、单机部署5.2、集群部署&#xff08;镜像模式&#xff09;5.3、K8s部署…