[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算法后拼接效果良好,没有出现明显的错位或重叠问题。

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

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

相关文章

在 vscode + cmake + GNU 工具链的基础上配置 JLINK

安装 JLINK JLINK 官网链接 下载安装后找到安装路径下的可执行文件 将此路径添加到环境变量的 Path 中。 创建 JFlash 项目 打开 JFlash&#xff0c;选择新建项目 选择单片机型号 在弹出的窗口中搜索单片机 其他参数根据实际情况填写 新建完成&#xff1a; 接下来设置…

ue5 GAS制作一个技能

新建文件夹 ability 取名BP_BaseAbility 新建一个技能GAB_Melee 上面技能GAB_Melee和技能基类BP_BaseAbility 进入技能GAB_Melee&#xff0c;添加打印火云掌 给这个技能添加标签 点这个号 这样命名&#xff0c;小心这个点&#xff08;.&#xff09;作为分割 ability.ha…

小米Vela操作系统开源:AIoT时代的全新引擎

小米近日正式开源了其物联网嵌入式软件平台——Vela操作系统&#xff0c;并将其命名为OpenVela。这一举动在AIoT&#xff08;人工智能物联网&#xff09;领域掀起了不小的波澜&#xff0c;也为开发者们提供了一个强大的AI代码生成器和开发平台。OpenVela项目源代码已托管至GitH…

opentelemetry-collector docker安装

一、编写配置 nano /root/otelcol-config.yamlreceivers:otlp:protocols:grpc:endpoint: 0.0.0.0:4317http:endpoint: 0.0.0.0:4318 exporters:debug:verbosity: detailed service:pipelines:traces:receivers: [otlp]exporters: [debug]metrics:receivers: [otlp]exporters: …

Arweave的出块原理

一、Arweave 关键技术 1.1数据结构&#xff1a;Blockweave 区块纺 区块坊中包括区块哈希列表和钱包列表。拥有区块哈希列表使旧区块可以被请求/验证&#xff0c;拥有钱包列表可以验证新交易&#xff0c;而无需处理钱包上一次交易所在的区块。区块哈希列表和钱包列表由矿工保持…

寒假刷题记录

4968. 互质数的个数 - AcWing题库 涉及&#xff1a;快速幂&#xff0c;欧拉函数&#xff0c;分解质因数 #include <bits/stdc.h> #define fi first #define se second #define endl \n #define pb push_backusing namespace std; using LL long long;const int mod 9…

免费下载 | 2024中国智算中心产业发展白皮书

以下是《2024中国智算中心产业发展白皮书》的核心内容整理&#xff1a; 一、智算中心产业发展背景及内涵 背景&#xff1a;智算中心作为新型基础设施&#xff0c;是数字经济的重要支撑&#xff0c;随着人工智能技术的快速发展&#xff0c;智算中心的需求日益增长。 内涵&#…

爬虫基础之爬取某站视频

目标网址:为了1/4螺口买小米SU7&#xff0c;开了一个月&#xff0c;它值吗&#xff1f;_哔哩哔哩_bilibili 本案例所使用到的模块 requests (发送HTTP请求)subprocess(执行系统命令)re (正则表达式操作)json (处理JSON数据) 需求分析: 视频的名称 F12 打开开发者工具 or 右击…

软件测试入门—用例设计中的场景图和状态迁移图

在软件测试领域&#xff0c;用例设计是一项至关重要的工作&#xff0c;它直接关系到软件质量的高低。而场景图和状态迁移图作为用例设计中的两种有效工具&#xff0c;能够帮助测试人员更全面、系统地设计测试用例。下面我们就来深入了解一下这两种图。 一、场景图 场景图主要…

Java面试专题——面向对象

面向过程和面向对象的区别 面向过程&#xff1a;当事件比较简单的时候&#xff0c;利用面向过程&#xff0c;注重的是事件的具体的步骤/过程&#xff0c;注重的是过程中的具体的行为&#xff0c;以函数为最小单位&#xff0c;考虑怎么做。 面向对象&#xff1a;注重找“参与者…

软件测试—— 接口测试(HTTP和HTTPS)

软件测试—— 接口测试&#xff08;HTTP和HTTPS&#xff09; HTTP请求方法GET特点使用场景URL结构URL组成部分URL编码总结 POST特点使用场景请求结构示例 请求标头和响应标头请求标头&#xff08;Request Headers&#xff09;示例请求标头 响应标头&#xff08;Response Header…

顺序表和链表(详解)

线性表 线性表&#xff08; linear list&#xff09;是n个具有相同特性的数据元素的有限序列。 线性表是一种在实际中广泛使用的数据结构&#xff0c;常见的线性表&#xff1a;顺序表、链表、栈、队列、字符串... 线性表在逻辑上是线性结构&#xff0c;也就说是连续的一条直线。…

初阶5 排序

本章重点 排序的概念常见排序的算法思想和实现排序算法的复杂度以及稳定性分析 1.排序的概念 排序: 所谓排序&#xff0c;就是使一串记录&#xff0c;按照其中的某个或某些关键字的大小&#xff0c;递增或递减的排列起来的操作。稳定性: 假定在待排序的记录序列中&#xff0…

Flink底层架构与运行流程

这张图展示了Flink程序的架构和运行流程。 主要组件及功能&#xff1a; Flink Program&#xff08;Flink程序&#xff09;&#xff1a; 包含Program code&#xff08;程序代码&#xff09;&#xff0c;这是用户编写的业务逻辑代码。经过Optimizer / Graph Builder&#xff08…

MyBatis和JPA区别详解

文章目录 MyBatis和JPA区别详解一、引言二、设计理念与使用方式1、MyBatis&#xff1a;半自动化的ORM框架1.1、代码示例 2、JPA&#xff1a;全自动的ORM框架2.1、代码示例 三、性能优化与适用场景1、MyBatis&#xff1a;灵活的SQL控制1.1、适用场景 2、JPA&#xff1a;开发效率…

计算机视觉——Intel RealSense D435的使用及python环境下的实现

什么是深度相机&#xff0c;以及深度相机的分类和工作原理 ​ 深度相机是一种能够捕捉场景中物体的深度信息&#xff08;即物体与相机之间的距离&#xff09;的设备。与传统的二维相机不同&#xff0c;深度相机除了拍摄图像的颜色和亮度外&#xff0c;还能生成一个关于场景中每…

Servlet快速入门

Servlet 由于目前主流使用SpringBoot进行开发Servlet可以说是时代的眼泪&#xff0c;这篇文章主要介绍我基于SpringBoot对应Servlet的浅薄认知&#xff0c;有利于更好的理解前端界面和java服务器的数据交换过程 快速入门 我比较推荐这篇文章来对Servlet有一个大概的了解 都2…

windows平台intel-vpl编译

需要先在本机编译好opencl库 git clone --recursive https://github.com/KhronosGroup/OpenCL-SDK.git cmake -A x64 -T v143 -D OPENCL_SDK_BUILD_OPENGL_SAMPLESOFF -B OpenCL-SDK\build -S OpenCL-SDKcmake --build OpenCL-SDK\build --config Releasecmake --install O…

MTK MT6890:LCD ST7789P3驱动移植调试

一、功能简述 LK阶段:开机logo、关机充电动画 Kernel阶段:开机logo、GUI用户交互界面 二、硬件连接及器件选型 ST7789P3 240RGB * 320 dot 262K Color TFT屏 SPI-II型panel ST7789P3接主控MT6890平台的DBI-C接口 SPI-II型读时序: 写时序: GPIO206: DISP_PWM (Func1) …

Vscode配置continue运行ollama部署的Qwen2.5

Vscode配置continue运行ollama部署的Qwen2.5 1.安装Continue插件 离线安装Continue访问下面网址下载插件&#xff1a;continue插件下载地址 将continue窗口迁右边&#xff08;根据个人习惯&#xff0c;可选&#xff09; 点击Continue图标会出CONTINUE窗口&#xff0c;鼠标选…