Opencv进阶操作:图像拼接

文章目录

  • 前言
  • 一、图像拼接的原理
    • 1. 特征提取与匹配
    • 2. 图像配准
    • 3. 图像变换与投影
    • 4. 图像融合
    • 5. 优化与后处理
  • 二、图像拼接的简单实现(案例实现)
    • 1.引入库
    • 2.定义cv_show()函数
    • 3.创建特征检测函数detectAndDescribe()
    • 4.读取拼接图片
    • 5.计算图片特征点及描述符
    • 6.建立暴力匹配BFMatcher并使用drawMatchesKnn()绘制关键点之间的连线
    • 7.透视变换
    • 8.将图片A填充到指定位置(左)
    • 9.完整代码:
  • 总结


前言

在数字图像处理领域,图像拼接(Image Stitching)是一项将多张重叠图像无缝合成广角视图的关键技术。这项技术被广泛应用于全景照片生成、卫星地图制作、医学影像分析等领域。本文将使用OpenCV库,结合Python示例代码,深入解析图像拼接的核心实现流程。


一、图像拼接的原理

常用算法

  • SIFT(尺度不变特征变换):对旋转、尺度、光照变化具有鲁棒性。

  • SURF(加速版SIFT):计算速度更快。

  • ORB(Oriented FAST and Rotated BRIEF):轻量级,适合实时应用。
    在这里插入图片描述
    代码处理后:
    在这里插入图片描述

1. 特征提取与匹配

目的:找到不同图像之间的对应点,建立空间关联。

  • 关键点检测:
    使用特征检测算法(如SIFT、SURF、ORB)在每张图像中提取显著的特征点(角点、边缘等)。这些关键点对旋转、缩放和光照变化具有鲁棒性。

  • 描述子生成:
    为每个关键点生成一个特征向量(描述子),用于描述该点周围像素的分布特性。例如,SIFT描述子通过梯度方向直方图表示局部特征。

  • 特征匹配:
    使用相似性度量(如欧氏距离)在不同图像的特征描述子之间进行匹配,找到对应的关键点对。常用方法包括暴力匹配(Brute-Force)或快速近似最近邻(FLANN)。

2. 图像配准

目的:计算图像之间的几何变换关系,对齐重叠区域。

3. 图像变换与投影

目的:将图像映射到同一坐标系下,准备拼接。

  • 透视变换(Warping):
    利用单应性矩阵 H对源图像进行透视变换,使其与目标图像的视角对齐。OpenCV中的 cv2.warpPerspective 函数实现此功能。

  • 拼接画布计算:
    根据变换后的图像角点坐标,计算最终拼接图的尺寸,确保所有图像内容都能包含在内。例如,将多张图像的角点坐标极值(最大/最小x和y值)作为画布边界。

4. 图像融合

目的:消除拼接处的接缝和曝光差异,实现平滑过渡。

5. 优化与后处理

  • 曝光补偿:
    若图像间亮度差异较大,需对重叠区域的像素值进行直方图匹配,调整曝光一致性。

  • 接缝优化:
    使用动态规划或图割(Graph Cut)算法寻找最佳拼接路径,避开运动物体或高对比度区域。

  • 重投影校正:
    对广角拼接结果进行球形或圆柱形投影,消除透视畸变(适用于全景图)。

二、图像拼接的简单实现(案例实现)

在这里插入图片描述

1.引入库

import cv2
import numpy as np
import sys

2.定义cv_show()函数

def cv_show(name,img):cv2.imshow(name,img)cv2.waitKey(0)

3.创建特征检测函数detectAndDescribe()

def detectAndDescribe(image):gray =cv2.cvtColor(image,cv2.COLOR_BGR2GRAY)#灰度图descriptor = cv2.SIFT_create()#建立sift生成器#检测sift特征点,计算描述符,第二个参数为掩模(kps,des) = descriptor.detectAndCompute(gray,None)# 将结果转换为numpy数组kps_float = np.float32([kp.pt for kp in kps])return (kps,kps_float,des)

4.读取拼接图片

imageA = cv2.imread('1.jpg')
imageB = cv2.imread('2.jpg')
cv_show('imgA',imageA)
cv_show('imgB',imageB)

5.计算图片特征点及描述符

(kpsA,kps_floatA,desA) = detectAndDescribe(imageA)
(kpsB,kps_floatB,desB) = detectAndDescribe(imageB)

6.建立暴力匹配BFMatcher并使用drawMatchesKnn()绘制关键点之间的连线

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].queryIdx,m[0].trainIdx))
print(len(good))
print(matches)vis = cv2.drawMatchesKnn(imageB,kpsB,imageA,kpsA,good,None,flags=cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS)
cv_show('vis',vis)

在这里插入图片描述

7.透视变换

if len(matches)>4: #筛选后的匹配对大于4时,计算视角变换矩阵ptsB = np.float32([kps_floatB[i] for (i, _) in matches])ptsA = np.float32([kps_floatA[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)

在这里插入图片描述

8.将图片A填充到指定位置(左)

result[0:imageA.shape[0], 0:imageA.shape[1]] = imageA
cv_show('result',result)

在这里插入图片描述

9.完整代码:

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()#建立sift生成器#检测sift特征点,计算描述符,第二个参数为掩模(kps,des) = descriptor.detectAndCompute(gray,None)# 将结果转换为numpy数组kps_float = np.float32([kp.pt for kp in kps])return (kps,kps_float,des)
'''----------读取拼接图片----------'''
imageA = cv2.imread('1.jpg')
imageB = cv2.imread('2.jpg')
cv_show('imgA',imageA)
cv_show('imgB',imageB)
'''计算图片特征点及描述符'''
(kpsA,kps_floatA,desA) = detectAndDescribe(imageA)
(kpsB,kps_floatB,desB) = detectAndDescribe(imageB)
'''-------建立暴力匹配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].queryIdx,m[0].trainIdx))
print(len(good))
print(matches)vis = cv2.drawMatchesKnn(imageB,kpsB,imageA,kpsA,good,None,flags=cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS)
cv_show('vis',vis)
'''透视变换'''
if len(matches)>4: #筛选后的匹配对大于4时,计算视角变换矩阵ptsB = np.float32([kps_floatB[i] for (i, _) in matches])ptsA = np.float32([kps_floatA[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图片最左端
result[0:imageA.shape[0], 0:imageA.shape[1]] = imageA
cv_show('result',result)

总结

图像拼接的本质是通过特征匹配建立图像间的几何对应关系,利用投影变换对齐视角,最后通过融合技术消除拼接痕迹。其核心原理结合了特征匹配、几何变换和图像融合三大技术模块,是计算机视觉领域的基础应用之一。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/78957.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

LLM 论文精读(三)Demystifying Long Chain-of-Thought Reasoning in LLMs

这是一篇2025年发表在arxiv中的LLM领域论文&#xff0c;主要描述了长思维链 Long Chain-of-Thought 对LLM的影响&#xff0c;以及其可能的生成机制。通过大量的消融实验证明了以下几点&#xff1a; 与shot CoT 相比&#xff0c;long CoT 的 SFT 可以扩展到更高的性能上限&…

计算机网络常识:缓存、长短连接 网络初探、URL、客户端与服务端、域名操作 tcp 三次握手 四次挥手

缓存&#xff1a; 缓存是对cpu&#xff0c;内存的一个节约&#xff1a;节约的是网络带宽资源 节约服务器的性能 资源的每次下载和请求都会造成服务器的一个压力 减少网络对资源拉取的延迟 这个就是浏览器缓存的一个好处 表示这个html页面的返回是不要缓存的 忽略缓存 需要每次…

《构建社交应用用户激励引擎:React Native与Flutter实战解析》

React Native凭借其与JavaScript和React的紧密联系&#xff0c;为开发者提供了一个熟悉且灵活的开发环境。在构建用户等级体系时&#xff0c;它能够充分利用现有的前端开发知识和工具。通过将用户在社交应用中的各种行为进行量化&#xff0c;比如发布动态的数量、点赞评论的次数…

接口自动化测试框架详解(pytest+allure+aiohttp+ 用例自动生成)

&#x1f345; 点击文末小卡片&#xff0c;免费获取软件测试全套资料&#xff0c;资料在手&#xff0c;涨薪更快 近期准备优先做接口测试的覆盖&#xff0c;为此需要开发一个测试框架&#xff0c;经过思考&#xff0c;这次依然想做点儿不一样的东西。 接口测试是比较讲究效…

Linux-----文件系统

文件大家都知道&#xff0c;前面的我的博客课程也为大家解释了关于文件的打开等&#xff0c;今天我们要谈论的是 文件在没被打开的时候在磁盘中的位置和找到它的方式。 画图为大家展示&#xff1a; 方便理解 我们从下面几个方面入手&#xff1a; 1. 看看物理磁盘 2. 了解一…

C++ set替换vector进行优化

文章目录 demo代码解释&#xff1a; 底层原理1. 二叉搜索树基础2. 红黑树的特性3. std::set 基于红黑树的实现优势4. 插入操作5. 删除操作6. 查找操作 demo #include <iostream> #include <set>int main() {// 创建一个存储整数的std::setstd::set<int> myS…

如何巧妙解决 Too many connections 报错?

1. 背景 在日常的 MySQL 运维中&#xff0c;难免会出现参数设置不合理&#xff0c;导致 MySQL 在使用过程中出现各种各样的问题。 今天&#xff0c;我们就来讲解一下 MySQL 运维中一种常见的问题&#xff1a;最大连接数设置不合理&#xff0c;一旦到了业务高峰期就会出现连接…

QT的布局和弹簧及其代码解读

this指的是真正的当前正在显示的窗口 main函数&#xff1a; Widget w是生成了一个主窗口&#xff0c;QT Designer是在这个主窗口里塞组件 w.show()用来展示这个主窗口 头文件&#xff1a; namespace Ui{class Widget;}中的class Widget和下面的class Widget不是一个东西 Ui…

《AI大模型应知应会100篇》第52篇:OpenAI API 使用指南与最佳实践

第52篇&#xff1a;OpenAI API 使用指南与最佳实践 &#x1f4cc; 摘要 本文将带你从零开始掌握 OpenAI API 的核心使用方法&#xff0c;涵盖从基础调用到高级功能的完整实战路径。通过详细的代码示例、图文解析和可运行的 Python 脚本&#xff0c;帮助你快速上手 GPT-3.5、GP…

C#学习7_面向对象:类、方法、修饰符

一、类 1class 1)定义类 访问修饰符class 类名{ 字段 构造函数&#xff1a;特殊的方法&#xff08;用于初始化对象&#xff09; 属性 方法... } eg: public class Person { // 字段 private string name; private int a…

湖北理元理律师事务所:债务优化中的“生活保障”方法论

债务危机往往伴随生活质量骤降&#xff0c;如何在还款与生存间找到平衡点&#xff0c;成为债务优化的核心挑战。湖北理元理律师事务所基于多年实务经验&#xff0c;提出“双轨并行”策略&#xff1a;法律减负与生活保障同步推进。 债务优化的“温度法则” 1.生存资金预留机制…

Jetpack Compose与Kotlin UI开发革命

Jetpack Compose + Kotlin:Android UI 开发的革命 简介 Jetpack Compose 是 Google 推出的现代 Android UI 工具包,结合 Kotlin 语言,彻底改变了传统 Android 开发的模式。过去,开发者依赖 XML 布局和命令式编程(如 findViewById 和手动更新视图),导致代码冗长且易出错…

基于pyqt的上位机开发

目录 安装依赖 功能包含 运行结果 安装依赖 pip install pyqt5 pyqtgraph pyserial 功能包含 自动检测串口设备&#xff0c;波特率选择/连接断开控制&#xff0c;数据发送/接收基础框架&#xff0c;实时绘图区域&#xff08;需配合数据解析&#xff09; ""&q…

QT人工智能篇-opencv

第一章 认识opencv 1. 简单概述 OpenCV是一个跨平台的开源的计算机视觉库&#xff0c;主要用于实时图像处理和计算机视觉应用‌。它提供了丰富的函数和算法&#xff0c;用于图像和视频的采集、处理、分析和显示。OpenCV支持多种编程语言&#xff0c;包括C、Python、Java等&…

Python自学第5天:字符串相关操作

1.字符串运算符 作符描述字符串连接*重复输出字符串[]通过索引获取字符串中字符[ : ]截取字符串中的一部分&#xff0c;遵循左闭右开原则&#xff0c;str[0:2] 是不包含第 3 个字符的。in成员运算符 - 如果字符串中包含给定的字符返回 Truenot in成员运算符 - 如果字符串中不包…

RabbitMq(尚硅谷)

RabbitMq 1.RabbitMq异步调用 2.work模型 3.Fanout交换机&#xff08;广播模式&#xff09; 4.Diret交换机&#xff08;直连&#xff09; 5.Topic交换机&#xff08;主题交换机&#xff0c;通过路由匹配&#xff09; 6.Headers交换机&#xff08;头交换机&#xff09; 6…

分库分表后复杂查询的应对之道:基于DTS实时性ES宽表构建技术实践

1 问题域 业务发展的初期&#xff0c;我们的数据库架构往往是单库单表&#xff0c;外加读写分离来快速的支撑业务&#xff0c;随着用户量和订单量的增加&#xff0c;数据库的计算和存储往往会成为我们系统的瓶颈&#xff0c;业界的实践多数采用分而治之的思想&#xff1a;分库…

CVE-2024-4577:Windows 编码错误

CVE-2024-4577是一个 PHP-CGI 漏洞,就是其中一种情况:虽然有这个版本,但由于 PHP 经常被反向移植,因此无法可靠地使用。 这篇博文详细介绍了如何研究 CVE-2024-4577 以及当前用于检测它的方法。 CVE-2024-4577 CVE-2024-4577 是 Windows 版 PHP 安装中的一个高危漏洞,会…

NetBox Docker 全功能部署方案(Ubuntu 22.04 + Docker)

环境准备 检查操作系统版本&#xff1a; 本方案使用 Ubuntu 22.04&#xff0c;并在 VMware 虚拟机中运行。通过以下命令检查系统版本&#xff1a; lsb_release -a 如果未安装 Ubuntu 22.04&#xff0c;请下载并安装一个全新的系统。 更新系统软件源&#xff1a; 更新软件包列表…

DeepSeek Copilot idea插件推荐

&#x1f30c; DeepSeek Copilot for IntelliJ IDEA 让 AI 成为你的编程副驾驶&#xff0c;极速生成单元测试 & 代码注释驱动开发&#xff01; &#x1f680; 简介 DeepSeek Copilot 是一款为 IntelliJ IDEA 打造的 AI 编程助手插件&#xff0c;它能够智能分析你的代码逻辑…