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

[Computer Vision]实验三:图像拼接

目录

一、实验内容

二、实验过程及结果

2.1 单应性变换

 2.2 RANSAC算法

三、实验小结


一、实验内容

  1. 理解单应性变换中各种变换的原理(自由度),并实现图像平移、旋转、仿射变换等操作,输出对应的单应性矩阵。
  2. 利用RANSAC算法优化关键点匹配,比较优化前后图像拼接和所生成全景图的差别,输出RANSAC前后匹配点数量、单应性矩阵。

二、实验过程及结果

2.1 单应性变换

(1)实验代码

import cv2
from networkx import center
import numpy as np
from scipy.fft import dst
import matplotlib.pyplot as plt
img=cv2.imread("D:/Computer vision/test1 picture/picture3.png")x=100
y=50
M0=np.float32([[1,0,x],[0,1,y]])
translated=cv2.warpAffine(img,M0,(img.shape[1],img.shape[0]))
print("平移变换单应性矩阵:\n",M0)img_center=(img.shape[1]/2,img.shape[0]/2)
M1=cv2.getRotationMatrix2D(img_center,45,1)
rotated=cv2.warpAffine(img,M1,(img.shape[1],img.shape[0]))
print("旋转变换单应性矩阵:\n",M1)M2=cv2.getRotationMatrix2D(img_center,0,0.5)
scaled=cv2.warpAffine(img,M2,(img.shape[1],img.shape[0]))
print("缩放变换单应性矩阵:\n",M2)rows,cols,ch=img.shape
src_points=np.float32([[0,0],[cols-1,0],[0,rows-1]])
dst_points=np.float32([[0,rows*0.33],[cols*0.85,rows*0.25],[cols*0.15,rows*0.7]])
M3=cv2.getAffineTransform(src_points,dst_points)
warped=cv2.warpAffine(img,M3,(cols,rows))
print("扭曲变换单应性矩阵:\n",M3)rows,cols=img.shape[:2]
pts1=np.float32([[150,50],[400,50],[60,450],[310,450]])
pts2=np.float32([[50,50],[rows-50,50],[50,cols-50],[rows-50,cols-50]])
M4=cv2.getPerspectiveTransform(pts1,pts2)
img_dst=cv2.warpPerspective(img,M4,(cols,rows))
print("透视变换单应性矩阵:\n",M4)plt.figure("Processed Images")
plt.subplot(2,3,1)
plt.imshow(img)
plt.title("Original Image")
plt.subplot(2,3,2)
plt.imshow(translated)
plt.title("Translated Image")
plt.subplot(2,3,3)
plt.imshow(rotated)
plt.title("Rotated Image")
plt.subplot(2,3,4)
plt.imshow(scaled)
plt.title("Scaled Image")
plt.subplot(2,3,5)
plt.imshow(warped)
plt.title("Warped Image")
plt.subplot(2,3,6)
plt.imshow(img_dst)
plt.title("Dst Image")
plt.show()
plt.savefig("D:/Computer vision/ransac_picture/processed_images.png")
plt.show()

(2)实验结果截图

图1为输出的单应性矩阵结果截图:

平移变换:两个自由度(两个平移参数),单应性矩阵为2*3的矩阵

旋转变换:一个自由度(一个旋转角度参数),单应性矩阵为2*3的矩阵

缩放变换:一个自由度(一个缩放因子),单应性矩阵为2*3的矩阵

扭曲变换有六个自由度(两个旋转参数 一个缩放因子),单应性矩阵为2*3的矩阵

透视变换有八个自由度(5个是仿射变换参数,3个是透视变换参数),单应性矩阵为3*3的矩阵

图1

图2为输出的单应性变换的结果图:

可以看到,平移变换的图像在x方向上平移100个像素,在y方向上平移50个像素。旋转变换的图像绕图像中心旋转45度。缩放变换的图像在x方向上缩小到原来的一半,在y方向上缩小到原来的一半。扭曲变换的图像进行仿射变换,包括旋转、缩放、平移和剪切。透视变换的图像进行了透视变换,包括旋转、缩放、平移和透视变形。

图2
 2.2 RANSAC算法

(1)实验代码

import cv2
import numpy as npdef detectAndCompute(image):gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)sift = cv2.SIFT_create()keypoints, descriptors = sift.detectAndCompute(gray, None)return keypoints, descriptorsdef matchKeyPoints(kpsA, kpsB, featuresA, featuresB, ratio=0.75, reprojThresh=4.0):matcher = cv2.BFMatcher()rawMatches = matcher.knnMatch(featuresA, featuresB, 2)matches = []for m in rawMatches:if len(m) == 2 and m[0].distance < ratio * m[1].distance:matches.append((m[0].queryIdx, m[0].trainIdx))ptsA = np.float32([kpsA[i].pt for (i, _) in matches])ptsB = np.float32([kpsB[i].pt for (_, i) in matches])(M, status) = cv2.findHomography(ptsA, ptsB, cv2.RANSAC, reprojThresh)return (M, matches, status)def drawMatches(imgA, imgB, kpsA, kpsB, matches, status):(hA, wA) = imgA.shape[:2](hB, wB) = imgB.shape[:2]result = np.zeros((max(hA, hB), wA + wB, 3), dtype="uint8")result[0:hA, 0:wA] = imgAresult[0:hB, wA:] = imgBfor ((trainIdx, queryIdx), s) in zip(matches, status):if s == 1:ptA = (int(kpsA[queryIdx].pt[0]), int(kpsA[queryIdx].pt[1]))ptB = (int(kpsB[trainIdx].pt[0]) + wA, int(kpsB[trainIdx].pt[1]))cv2.line(result, ptA, ptB, (0, 255, 0), 1)return resultdef stitchImages(imageA, imageB, M):(hA, wA) = imageA.shape[:2](hB, wB) = imageB.shape[:2]result = cv2.warpPerspective(imageA, M, (wA + wB, hA))result[0:hB, 0:wB] = imageBreturn resultif __name__ == '__main__':imageA = cv2.imread("D:\Computer vision/ransac_picture/ransac1.jpg")imageB = cv2.imread("D:/Computer vision/ransac_picture/ransac2.jpg")kpsA, featuresA = detectAndCompute(imageA)kpsB, featuresB = detectAndCompute(imageB)M, matches, status = matchKeyPoints(kpsA, kpsB, featuresA, featuresB)initial_matches = sum(status)final_matches = len(matches)print(f"RANSAC前匹配点数量: {initial_matches}")print(f"RANSAC后匹配点数量: {final_matches}")print("单应性矩阵为:\n", M)drawImgBeforeRANSAC = drawMatches(imageA, imageB, kpsA, kpsB, matches, status)cv2.imshow("drawMatches Before RANSAC", drawImgBeforeRANSAC)cv2.waitKey()cv2.destroyAllWindows()stitchedImage = stitchImages(imageA, imageB, M)cv2.imshow("Stitched Image", stitchedImage)cv2.waitKey()cv2.destroyAllWindows()cv2.imwrite("D:/Computer vision/ransac_picture/stitched_image.jpg", stitchedImage)
cv2.imwrite("D:/Computer vision/ransac_picture/drawMatchesBeforeRANSAC.jpg", drawImgBeforeRANSAC)

(2)数据集(待拼接)

(3)实验结果截图

图3为输出的单应性矩阵结果截图:

如图所示,在运行SIFT特征检测和描述符提取后,通过BFMatcher进行特征匹配,初始匹配点的数量是198对。经过RANSAC算法去除错误匹配后,剩余的匹配点数量为1074对。这表明RANSAC算法有效地保留了正确的匹配点并去除了错误的匹配点。

图3

图4为在应用RANSAC算法之前绘制的匹配结果图像:

如图所示,绘制两幅图像的匹配结果并显示特征点之间的匹配关系。通过可视化匹配结果,可以直观地看到哪些特征点被成功匹配。

图4

图5为最终拼接后的图像:

图5

三、实验小结

图像拼接是计算机视觉领域的一个重要研究方向,通过将多张重叠的图像拼接在一起,实现更大、更全面的图像展示。实验中通过使用opencv中的相关函数实现图像的单应性变换,并使用BFMatcher和RANSAC算法进行了特征点匹配以及图像拼接。使用RANSAC算法后拼接效果良好,没有出现明显的错位或重叠问题。

相关文章:

[Computer Vision]实验三:图像拼接

目录 一、实验内容 二、实验过程及结果 2.1 单应性变换 2.2 RANSAC算法 三、实验小结 一、实验内容 理解单应性变换中各种变换的原理&#xff08;自由度&#xff09;&#xff0c;并实现图像平移、旋转、仿射变换等操作&#xff0c;输出对应的单应性矩阵。利用RANSAC算法优…...

【Vim Masterclass 笔记22】S09L40 + L41:同步练习11:Vim 的配置与 vimrc 文件的相关操作(含点评课内容)

文章目录 S09L40 Exercise 11 - Vim Settings and the Vimrc File1 训练目标2 操作指令2.1. 打开 vimrc-sample 文件2.2. 尝试各种选项与设置2.3. 将更改内容保存到 vimrc-sample 文件2.4. 将文件 vimrc-sample 的内容复制到寄存器2.5. 创建专属 vimrc 文件2.6. 对于 Mac、Linu…...

5.9 洞察 OpenAI - Translator:日志(Logger)模块的 “时光记录仪”

洞察 OpenAI - Translator:日志(Logger)模块的 “时光记录仪” 在开发和生产环境中,日志记录是确保应用程序正常运行和快速调试的核心机制之一。日志模块(Logger)用于记录应用程序的运行信息,包括错误、警告、调试信息、信息性事件等。通过日志,开发者可以实时监控程序…...

客户案例:电商平台对帐-账单管理(亚马逊amazon)

账单管理&#xff1a; 功能定义&#xff1a; 账单管理用于上传亚马逊&#xff08;amazon&#xff09;平台下载的原始账单数据&#xff0c;美国站、日本站、墨西哥站等账单模板直接进行数据上传&#xff0c;做到0调整&#xff0c;下载下来的账单数据无缝上传至对账平台-账单管…...

IP协议特性

在网络层中&#xff0c;最重要的协议就是IP协议&#xff0c;IP协议也有两个特性&#xff0c;即地址管理和路由选择。 1、地址管理 由于IPv4地址为4个字节&#xff0c;所以最多可以支持42亿个地址&#xff0c;但在现在&#xff0c;42亿明显不够用了。这就衍生出下面几个机制。…...

Kubernetes入门学习

kubernetes技术架构模型 一、kubernetes的Label标签 1.标签是以keyvalue的格式通过用户自定义指定&#xff0c;目的是将其加入到各种资源对象上来实现多维度的资源分组管理使其更方便的进行资源分配、调度、配置和部署管理工作。 2.标签可以结合Label Selector(标签选择器)查询…...

支持向量机SVM的应用案例

支持向量机&#xff08;Support Vector Machine,SVM&#xff09;是一种强大的监督学习算法&#xff0c;广泛应用于分类和回归任务。 基本原理 SVM的主要目标是周到一个最优的超平面&#xff0c;该超平面能够将不同类别的数据点尽可能分开&#xff0c;并且使离该超平面最近的数…...

Chrome 132 版本新特性

Chrome 132 版本新特性 一、Chrome 132 版本浏览器更新 1. 在 iOS 上使用 Google Lens 搜索 在 Chrome 132 版本中&#xff0c;开始在所有平台上推出这一功能。 1.1. 更新版本&#xff1a; Chrome 126 在 ChromeOS、Linux、Mac、Windows 上&#xff1a;在 1% 的稳定版用户…...

(5)STM32 USB设备开发-USB键盘

讲解视频&#xff1a;2、USB键盘-下_哔哩哔哩_bilibili 例程&#xff1a;STM32USBdevice: 基于STM32的USB设备例子程序 - Gitee.com 本篇为使用使用STM32模拟USB键盘的例程&#xff0c;没有知识&#xff0c;全是实操&#xff0c;按照步骤就能获得一个STM32的USB键盘。本例子是…...

Linux 系统服务开机自启动指导手册

一、引言 在 Linux 系统中&#xff0c;设置服务开机自启动是常见的系统配置任务。本文档详细介绍了多种实现服务开机自启动的方法&#xff0c;包括 systemctl 方式、通用脚本方式、crontab 方案等&#xff0c;并提供了生产环境下的方案建议和开机启动脚本示例。 二、systemct…...

分布式多卡训练(DDP)踩坑

多卡训练最近在跑yolov10版本的RT-DETR&#xff0c;用来进行目标检测。 单卡训练语句&#xff08;正常运行&#xff09;&#xff1a; python main.py多卡训练语句&#xff1a; 需要通过torch.distributed.launch来启动&#xff0c;一般是单节点&#xff0c;其中CUDA_VISIBLE…...

Codeforces Round 1000 (Div. 2)-C题(树上两个节点不同边数最大值)

https://codeforces.com/contest/2063/problem/C 牢记一棵树上两个节点如果相邻,它们有一条边会重叠,两个节点延伸出去的所有不同边是两个节点入度之和-1而不是入度之和,那么如果这棵树上有三个节点它们的入度都相同,那么优先选择非相邻的两个节点才能使所有不同边的数量最大!!…...

C++17 新特性解析:Lambda 捕获 this

C17 引入了许多改进和新特性&#xff0c;其中之一是对 lambda 表达式的增强。在这篇文章中&#xff0c;我们将深入探讨 lambda 表达式中的一个特别有用的新特性&#xff1a;通过 *this 捕获当前对象的副本。这个特性不仅提高了代码的安全性&#xff0c;还极大地简化了某些场景下…...

Spring Boot 使用 Micrometer 集成 Prometheus 监控 Java 应用性能

在Spring Boot中使用Micrometer集成Prometheus来监控Java应用性能是一种常见的做法。 一、Micrometer简介 Micrometer是一个开源的Java项目&#xff0c;主要用于为JVM应用程序提供监控和度量功能。以下是对Micrometer的详细介绍&#xff1a; 定义与功能 Micrometer是一个针…...

Spring Boot 事件驱动:构建灵活可扩展的应用

在 Spring Boot 应用中&#xff0c;事件发布和监听机制是一种强大的工具&#xff0c;它允许不同的组件之间以松耦合的方式进行通信。这种机制不仅可以提高代码的可维护性和可扩展性&#xff0c;还能帮助我们构建更加灵活、响应式的应用。本文将深入探讨 Spring Boot 的事件发布…...

IM系统设计

读多写少&#xff0c;一般采用写扩散成timeline来做 写扩散模式 利用last message id作为这个作为最后一个消息体 timeline和批量未读和ack 利用ZSET来维护连接的定时心跳&#xff0c;来续约运营商的连接不断开...

华为EC6110T-海思Hi3798MV310_安卓9.0_通刷-强刷固件包

华为EC6110T-海思Hi3798MV310_安卓9.0_通刷-强刷固件包 刷机教程说明&#xff1a; 适用机型&#xff1a;华为EC6110-T、华为EC6110-U、华为EC6110-M 破解总分为两个部分&#xff1a;拆机短接破解&#xff08;保留IPTV&#xff09;和OTT卡刷&#xff08;不保留IPTV&#xff09…...

ASP.NET Blazor托管模型有哪些?

今天我们来说说Blazor的三种部署方式&#xff0c;如果大家还不了解Blazor&#xff0c;那么我先简单介绍下Blazor Blazor 是一种 .NET 前端 Web 框架&#xff0c;在单个编程模型中同时支持服务器端呈现和客户端交互性&#xff1a; ● 使用 C# 创建丰富的交互式 UI。 ● 共享使用…...

PyTorch广告点击率预测(CTR)利用深度学习提升广告效果

目录 广告点击率预测问题数据集结构广告点击率预测模型的构建1. 数据集准备2. 构建数据加载器3. 构建深度学习模型4. 训练与评估 总结 广告点击率预测&#xff08;CTR&#xff0c;Click-Through Rate Prediction&#xff09;是在线广告领域中的重要任务&#xff0c;它帮助广告平…...

PAT甲级-1017 Queueing at Bank

题目 题目大意 银行有k个窗口&#xff0c;每个窗口只能服务1个人。如果3个窗口已满&#xff0c;就需要等待。给出n个人到达银行的时间和服务时间&#xff0c;要求计算每个人的平均等待时间。如果某个人的到达时间超过17:00:00&#xff0c;则不被服务&#xff0c;等待时间也不计…...

地震勘探——干扰波识别、井中地震时距曲线特点

目录 干扰波识别反射波地震勘探的干扰波 井中地震时距曲线特点 干扰波识别 有效波&#xff1a;可以用来解决所提出的地质任务的波&#xff1b;干扰波&#xff1a;所有妨碍辨认、追踪有效波的其他波。 地震勘探中&#xff0c;有效波和干扰波是相对的。例如&#xff0c;在反射波…...

【第二十一章 SDIO接口(SDIO)】

第二十一章 SDIO接口 目录 第二十一章 SDIO接口(SDIO) 1 SDIO 主要功能 2 SDIO 总线拓扑 3 SDIO 功能描述 3.1 SDIO 适配器 3.2 SDIOAHB 接口 4 卡功能描述 4.1 卡识别模式 4.2 卡复位 4.3 操作电压范围确认 4.4 卡识别过程 4.5 写数据块 4.6 读数据块 4.7 数据流…...

回溯算法学习

一、电话号码的字母组合 import java.util.ArrayList; import java.util.List;import javax.management.loading.PrivateClassLoader;public class letterCombinations {private static final String[] KEYPAD {"", //0"", //1"abc", //2"…...

基于Java+MySQL实现(GUI)客户管理系统

客户资料管理系统的设计与实现 第一章 需求分析 1.1 需求总体介绍 本项目为了方便维护客户信息为了方便维护客户信息&#xff0c;对客户进行统一管理&#xff0c;可以把所有客户信息录入系统&#xff0c;进行维护和统计功能。可通过文件的方式保存相关录入数据&#xff0c;对…...

GruntJS-前端自动化任务运行器从入门到实战

Grunt 完全指南&#xff1a;从入门到实战 一、Grunt 是什么&#xff1f; Grunt是一个基于 Node.js 的前端自动化任务运行器&#xff0c;主要用于自动化执行项目开发中重复性高的任务&#xff0c;例如文件压缩、代码编译、语法检查、单元测试、文件合并等。通过配置简洁的任务…...

【SpringBoot自动化部署】

SpringBoot自动化部署方法 使用Jenkins进行持续集成与部署 Jenkins是最常用的自动化部署工具之一&#xff0c;能够实现代码拉取、构建、测试和部署的全流程自动化。 配置Jenkins任务时&#xff0c;需要添加Git仓库地址和凭证&#xff0c;设置构建触发器&#xff08;如GitHub…...

DBLP数据库是什么?

DBLP&#xff08;Digital Bibliography & Library Project&#xff09;Computer Science Bibliography是全球著名的计算机科学出版物的开放书目数据库。DBLP所收录的期刊和会议论文质量较高&#xff0c;数据库文献更新速度很快&#xff0c;很好地反映了国际计算机科学学术研…...

数据结构:递归的种类(Types of Recursion)

目录 尾递归&#xff08;Tail Recursion&#xff09; 什么是 Loop&#xff08;循环&#xff09;&#xff1f; 复杂度分析 头递归&#xff08;Head Recursion&#xff09; 树形递归&#xff08;Tree Recursion&#xff09; 线性递归&#xff08;Linear Recursion&#xff09;…...

怎么开发一个网络协议模块(C语言框架)之(六) ——通用对象池总结(核心)

+---------------------------+ | operEntryTbl[] | ← 操作对象池 (对象数组) +---------------------------+ | 0 | 1 | 2 | ... | N-1 | +---------------------------+↓ 初始化时全部加入 +------------------------+ +-------------------------+ | …...

rm视觉学习1-自瞄部分

首先先感谢中南大学的开源&#xff0c;提供了很全面的思路&#xff0c;减少了很多基础性的开发研究 我看的阅读的是中南大学FYT战队开源视觉代码 链接&#xff1a;https://github.com/CSU-FYT-Vision/FYT2024_vision.git 1.框架&#xff1a; 代码框架结构&#xff1a;readme有…...