全景拼接python旗舰版
前言
在这个项目中,您将构建一个管道,将几幅图像拼接成一个全景图。您还将捕获一组您自己的图像来报告最终的结果。
步骤1 特征检测与描述
本项目的第一步是对序列中的每幅图像分别进行特征检测。回想一下我们在这个类中介绍过的一些特征探测器:哈里斯角、Blob探测器、SIFT探测器等。与检测步骤相结合,就进行了特征描述。您的特性必须对某些转换是不变的。想想你将收集数据集的方式。你需要什么样的不变性?探索在OpenCV中可用的特性描述符实现: SIFT、SURF、ORB等

1.使用cv2.imread读取输入的图像。
2.将图像转换为灰度(例如,使用cv2.cvtColor)以进行特征提取。您也可以通过cv2.resize调整图像的大小(例如,在参考约塞米蒂序列中那样的480像素的高度),以使以下步骤运行得更快。
3.选择您的特征检测器。cv2是一个很好的开始。SIFT_creve(或cv2.xfeatures2d。SIFT_Creve在旧的OpenCV版本中)。
4.使用检测和计算方法提取关键点和关键点特征。
5.图1使用cv2.drawKeypoints可视化了检测到的关键点:
def flt_show(image, title='sift detects'):plt.figure(figsize=(10,10)) # Canvas 10x magnificationplt.title(title,fontsize=20) # titleplt.axis('off') # Hidden axisplt.imshow(cv2.cvtColor(image,cv2.COLOR_BGR2RGB)) # print imageplt.show() # Display canvas# 1. Read the input images using cv2.imread.
def feature_detection_and_description(image_path):image = cv2.imread(image_path)# RGB to Grayimage = cv2.cvtColor(image,cv2.COLOR_BGR2GRAY)# Create detectorsift_detecter = sift = cv2.SIFT_create()# Detection picturekp,des = sift.detectAndCompute(image,None) # Keypoints and descriptors# Plot key pointsimg2 = cv2.drawKeypoints(image,kp,None,(255,0,0),4)# showflt_show(img2)# Release resourcescv2.waitKey(0)cv2.destroyAllWindows()feature_detection_and_description('yosemite1.jpg')步骤2 特征匹配和图像对齐
一旦计算出了关键点和特征,代码就需要在连续的图像对之间建立良好的匹配。为此,您需要选择一个距离函数和一个匹配算法。

1.选择一个匹配算法和一个距离函数。强力匹配(cv2。你可以做这个工作,因为你以后会摆脱糟糕的比赛!如果您使用二进制特性,如简短或ORB,看看汉明距离函数(cv2。NORM_HAMMING),否则,只需使用欧几里得距离(cv2。norm_l2 ).
2.使用匹配()方法从一对图像中计算匹配,并提供它们的特征作为输入。选择一对有良好重叠的图像。实际上,按照预定义的顺序(例如从左到右)捕捉图像进行全景拼接是很方便的,这样相邻的图像总是有很好的重叠。
3.使用原始的关键点位置和匹配,以两个m×2数组点1和点2的形式构造对应,这样点1[i]和点2[i]分别在第一和第二幅图像中存储匹配的位置。如果您正在使用建议的OpenCV功能,请查看关键点和DMatch类的接口,以了解如何操作返回对象。
4.现在,从对应关系中估计图像之间的同源性变换。匹配项将会有很多离群值,所以你需要选择一个对离群值很健壮的估计器,比如RANSAC。cv2.findHomography对这一步很有用!
5.最后,用模糊的同源性扭曲其中一幅图像: cv2.warpPerspective。
6.图2显示了在所选对图像之间检测到的1249个匹配中的前10个匹配(基于响应分数)。该图是使用cv2.drawMatches创建的。让我们来看看图3和图4。为什么前者的一致性如此成功?为什么在后一个数字中会有问题?
def detectAndDescribe(image):# convert the image to grayscalegray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)# detect and extract features from the imagedescriptor = cv2.SIFT_create()(kps, features) = descriptor.detectAndCompute(image, None)# convert the keypoints from KeyPoint objects to NumPy# arrays
# kps = np.float32([kp.pt for kp in kps])# return a tuple of keypoints and featuresreturn (kps, features)def matchKeypoints(kpsA, kpsB, featuresA, featuresB, ratio, reprojThresh):# compute the raw matches and initialize the list of actual# matches
# matcher = cv2.DescriptorMatcher_create("BruteForce")
# rawMatches = matcher.knnMatch(featuresA, featuresB, 2)
# matches = []
# # loop over the raw matches
# for m in rawMatches:
# # ensure the distance is within a certain ratio of each
# # other (i.e. Lowe's ratio test)
# if len(m) == 2 and m[0].distance < m[1].distance * ratio:
# matches.append((m[0].trainIdx, m[0].queryIdx))bf = cv2.BFMatcher(cv2.NORM_L2,crossCheck=True)matches = bf.match(featuresA,featuresB)goods = sorted(matches,key = lambda x:x.distance)# computing a homography requires at least 4 matchesif len(matches) > 4:# construct the two sets of points
# ptsA = np.float32([kpsA[i] for (_, i) in matches])
# ptsB = np.float32([kpsB[i] for (i, _) in matches])ptsA = np.float32([ kpsA[m.queryIdx].pt for m in goods ]).reshape(-1,1,2)ptsB = np.float32([ kpsB[m.trainIdx].pt for m in goods ]).reshape(-1,1,2)# compute the homography between the two sets of points(H, status) = cv2.findHomography(ptsA, ptsB, cv2.RANSAC,reprojThresh)# return the matches along with the homograpy matrix# and status of each matched pointreturn (matches, H, status)# otherwise, no homograpy could be computedreturn Nonedef drawMatches(imageA, imageB, kpsA, kpsB, matches, status):img1 = imageAimg2 = imageBif len(matches) > 10:src_pts = np.float32([ kpsA[m.queryIdx].pt for m in matches ]).reshape(-1,1,2)dst_pts = np.float32([ kpsB[m.trainIdx].pt for m in matches ]).reshape(-1,1,2)M, mask = cv2.findHomography(src_pts, dst_pts, cv2.RANSAC,5.0)matchesMask = mask.ravel().tolist()h,w,_ = img1.shapepts = np.float32([ [0,0],[0,h-1],[w-1,h-1],[w-1,0] ]).reshape(-1,1,2)draw_params = dict(matchColor = (0,255,0), # draw matches in green colorsinglePointColor = None,matchesMask = matchesMask, # draw only inliersflags = 2)img_matchers = cv2.drawMatches(imageA,kpsA,imageB,kpsB,matches,None,**draw_params)# return the visualizationreturn img_matchersdef feature_matching_and_image_alignment(imageL, imageR, ratio=0.75, reprojThresh=4.0, showMatches=False):imageA, imageB = imageR, imageL# local invariant descriptors from them(kpsA, featuresA) = detectAndDescribe(imageA)(kpsB, featuresB) = detectAndDescribe(imageB)# match features between the two imagesM = matchKeypoints(kpsA, kpsB,featuresA, featuresB, ratio, reprojThresh)# if the match is None, then there aren't enough matched# keypoints to create a panoramaif M is None:return None# otherwise, apply a perspective warp to stitch the images# together(matches, H, status) = Mresult = cv2.warpPerspective(imageA, H,(imageA.shape[1] + imageB.shape[1], imageA.shape[0]))result[0:imageB.shape[0], 0:imageB.shape[1]] = imageB# check to see if the keypoint matches should be visualizedif showMatches:vis = drawMatches(imageA, imageB, kpsA, kpsB, matches,status)# return a tuple of the stitched image and the# visualizationreturn (result, vis)# return the stitched imagereturn resultresult, vis = feature_matching_and_image_alignment(cv2.imread('yosemite1.jpg'), cv2.imread('yosemite2.jpg'), showMatches=True)
flt_show(vis)
flt_show(result)
步骤3 图像背景去除
现在您已经将原始图像1和图像2扭曲到图像1的平面上,您需要将它们组合起来以产生无缝的结果。如果你简单地添加图像强度,重叠的区域看起来会很不错,但其他区域看起来会很暗,如图3所示。另一个简单的解决方案是将一幅图像复制粘贴到另一幅图像之上。这还将在边界上创建工件,如图5所示。减少伪影强度的一个解决方案是使用自适应权值来混合图像。靠近每幅图像边界的像素不如位于中心的像素可靠。那么如何将这些像素与与这些像素到相应图像边界的距离成比例的权重进行混合呢?我们提供了get_tinghe_变换函数,它取一个扭曲的RGB图像H×W×3,并产生一个单通道距离函数H×W×1。您可以使用这个函数来计算结果为img1 *权重1+img2*权重2。不要忘记将生成的图像规格化到0…255的范围。尝试使用np.最大值(denom,1.0)以避免除以零。将您的图像转换回无符号的8位整数与img.astype(“uint8”)
def get_distance_transform(img_rgb):'''Get distance to the closest background pixel for an RGB imageInput:img_rgb : np.array , HxWx3 RGB imageOutput:dist : np.array , HxWx1 distance imageeach pixel ’s intensity is proportional toits distance to the closest background pixelscaled to [0..255] for plotti'''# Threshold the image : any value above 0 maps into 255thresh = cv2.threshold(img_rgb , 0 , 255 , cv2 . THRESH_BINARY )[1]# Collapse the color dimensionthresh = thresh.any(axis =2)# Pad to make sure the border is treated as backgroundthresh = np.pad(thresh, 1, mode='maximum')# Get distance transformdist = distance_transform_edt(thresh) [1: -1 , 1: -1]# HxW -> HxWx1dist = dist[: , : , None ]return dist / dist . max () * 255.0def getMaskResult(result, show=False):mask = get_distance_transform(result)locs = np.where(mask>0)xmin = np.min(locs[1])xmax = np.max(locs[1])ymin = np.min(locs[0])ymax = np.max(locs[0])result_mask = result[ymin:ymax, xmin:xmax]if show:flt_show(result, 'before')flt_show(result_mask, 'after')return result_mask
result_mask = getMaskResult(result, True)
步骤4 缝合多张图像
拼接n个图像的一个简单方法是从左到右对序列进行排序,并逐步应用成对拼接:如果拼接每一对相邻图像,将得到n个−1的全景图。您可以一次又一次地对这些图像应用相同的拼接过程,直到您只留下一个宽的全景图。您只需要在它上面添加一个for循环。
imageList = [cv2.imread('yosemite1.jpg'), cv2.imread('yosemite2.jpg'), cv2.imread('yosemite3.jpg'),cv2.imread('yosemite4.jpg')]temp_image = feature_matching_and_image_alignment(imageList[0], imageList[1])
temp_image = getMaskResult(temp_image)
flt_show(temp_image1, title='Step 1')
for i in range(2, 4):temp_image = feature_matching_and_image_alignment(temp_image, imageList[i])temp_image = getMaskResult(temp_image)flt_show(temp_image, title='Step {}'.format(i))
步骤5 创建您自己的全景图,并讨论设置和结果。
请注意,这一步将主要根据您提供的讨论进行分级(例如,只捕获一些图像并在不编写的情况下生成结果不会给您很多分数)。为了获得一个好的全景,在捕捉自己的图像时有几件事需要考虑。
imageList = [cv2.imread('1.png'), cv2.imread('2.png'), cv2.imread('3.png'),cv2.imread('4.png'), cv2.imread('5.png')]temp_image = feature_matching_and_image_alignment(imageList[0], imageList[1])
temp_image = getMaskResult(temp_image)
flt_show(temp_image, title='Step 1')
for i in range(2, 5):temp_image = feature_matching_and_image_alignment(temp_image, imageList[i])temp_image = getMaskResult(temp_image)flt_show(temp_image, title='Step {}'.format(i))

# # # #发表评论
- 1。这已经在步骤4中完成了。
- 2。数据集捕捉了沿河的建筑风景,具有良好的视野和易于区分的特征。
- 3。相邻的图片有很好的重叠。
- 4. 摄像机角度的变化容易引起同态现象。如果天气晴朗,最好待在室外,视野开阔,位置好,光线也明亮。只要两幅图像之间的特征明显,摄像机是否自由移动并不重要。
当三张以上的图片拼接在一起时,由于黑色背景的原因,图像与其他图像的拼接会有很多困难。背景剔除可以解决这个问题。
感谢观看!由于是作业的缘故,文中可能有极少部分会出现语义不通顺的情况,但对本文的目的没有什么影响。
相关文章:
全景拼接python旗舰版
前言在这个项目中,您将构建一个管道,将几幅图像拼接成一个全景图。您还将捕获一组您自己的图像来报告最终的结果。步骤1 特征检测与描述本项目的第一步是对序列中的每幅图像分别进行特征检测。回想一下我们在这个类中介绍过的一些特征探测器:…...
(C语言)常见的字符串与内存操作函数
问:1. Solve the problems:我想用三种方法求字符串的长度怎么办?2. strlen处理的字符串中有什么时需要注意:什么只记为什么?当什么不起什么作用时,什么不计算在内,编译器会把什么,什…...
Linux基础笔记总结
♥️作者:小刘在C站 ♥️个人主页:小刘主页 ♥️每天分享云计算网络运维课堂笔记,努力不一定有收获,但一定会有收获加油!一起努力,共赴美好人生! ♥️夕阳下,是最美的绽放࿰…...
R语言学习笔记
1.R语言介绍 2.R语言安装 官网:https://www.r-project.org/ CARN → 选择China中任意镜像站点 → Download R for Windows → base(二进制版本R基础软件)→ Download R-4.2.2 for Windows (76 megabytes, 64 bit) 3.Rstudio安装 https://po…...
【软件测试】企业测试面试题9道,从自我介绍到项目考察+回答......
目录:导读前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结(尾部小惊喜)前言 1、自我介绍 您好&a…...
《Spring源码深度分析》第8章 数据库连接JDBC
目录标题前言一、数据库连接方式1.JDBC连接数据库2.Spring Jdbc连接数据库(JdbcTemplate)二、JdbcTemplate源码分析1.update/save功能的实现源码分析入口(关键)基础方法execute1.获取数据库连接池2.应用用户设定的输入参数3. 调用回调函数处理4. 资源释放Update中的回调函数2.q…...
ModuleNotFoundError的解决方案【已解决】
问题描述 有包却提示ModuleNotFoundError 在正常情况下,你使用pip或者conda检查是否有相应包的时候,显示的是有的。但是一旦运行程序就会报这个ModuleNotFoundError错误。 问题可能是程序运行环境不对。 解决方案 (1)进入正确…...
Vue驼峰与短横线分割命名中有哪些坑
目录 0.前言 驼峰和短横线分割命名注意事项 组件注册命名 父子组件数据传递时命名 父子组件函数传递 0.前言 Vue驼峰命名法指的是将变量以驼峰形式命名,例如 userName、userId 等,而短横线分隔符法则指的是用短横线分隔变量名,例如 user…...
从文件中加载数据以及异常处理
上期学习了数据的存储,这次学习数据的加载 你可以使用把openpyxl.load_workbook() 来打开一个已经存在的工作簿 >>> from openpyxl import load_workbook >>> wb load_workbook(filename empty_book.xlsx) >>> sheet_ranges wb[ran…...
【JavaSE】方法的使用
方法的使用BIT-5-方法的使用绪论1. 方法概念及使用1.1什么是方法1.2 方法定义1.3 实参和形参的关系(重要)1.4 没有返回值的方法2. 方法重载2.1 为什么需要方法重载2.2 方法重载概念3. 递归3.1 生活中的故事3.2 递归的概念3.2 递归执行过程分析3.3 递归练…...
ModelScope 垂类检测系列模型介绍
文章目录ModelScope介绍垂类模型介绍调用方式1 Demo Service2 Notebook3 本地使用* 二次开发总结ModelScope介绍 ModelScope 是阿里达摩院推出的 中文版模型即服务(MaaS, Model as a Service)共享平台。该平台在2022年的云栖大会上发布,之前…...
Linux | Linux卸载和安装MySQL(Ubuntu版)
最近又来到了Linux学习了,原因是要接触云服务器相关知识, 所以博主整理了一些关于Linux的知识, 欢迎各位朋友点赞收藏,天天开心丫,快乐写代码! Linux系列文章请戳 Linux教程专栏 目录 一、卸载MySQL 1…...
【C1】数据类型,常量变量,输入输出,运算符,if/switch/循环,/数组,指针,/结构体,文件操作,/编译预处理,gdb,makefile,线程
文章目录1.数据类型:单双引号,char(1B),int/float(32位系统,大小一样4B,但存储方式不同),double(8B),long double…...
【深度学习】pytorch的基础操作
import torch import numpy as np # 1.1 根据已有的数据创建张量 def test01(): # 1.1 创建标量 data torch.tensor(10) print(data) # 1.2 使用numpy数组来创建张量 data np.random.randn(2,3) data torch.tensor(data) print(data) # 1.3使用list…...
MWORKS--同元软控MWORKS介绍、安装与使用
MWORKS--同元软控MWORKS介绍、安装与使用1 同元软控介绍1.1 同元软控简介1.2 同元软控发展历史2 MWORKS介绍2.1 MWORKS简介2.2 MWORKS产品描述3 装备数字化3.1 发展3.2 内涵3.3 系统模型发展成为产品的一部分3.4 MWORKS系统模型数据管理3.4 MWORKS为装备数字化提供的套件4 下载…...
Python 解决dilb和face_recognition第三方包安装失败
目录 dilb和face_recognition第三方包安装失败 亲测有效的解决方法:whl安装方式 dilb和face_recognition第三方包安装失败 场景复现:因为需要用到dlibface_recognition,基于OpenCV做一些人脸识别的项目,在Pycharm中进行pip清华…...
Mac系统Mysql的8.0.22版本安装笔记和密码重置修改密码等问题方法
忘记密码官网教程地址:https://dev.mysql.com/doc/refman/5.7/en/resetting-permissions.html 5.7数据库安装指南参考:https://jingyan.baidu.com/article/fa4125ac0e3c2928ac709204.html 初次安装8.0.22遇到许多坑,密码修改失败;…...
驱动 | Linux | NVMe 不完全总结
本文主要参考这里 1’ 2 的解析和 linux 源码 3。 此处推荐一个可以便捷查看 linux 源码的网站 bootlin 4。 更新:2022 / 02 / 11 驱动 | Linux | NVMe 不完全总结NVMe 的前世今生从系统角度看 NVMe 驱动NVMe CommandPCI 总线从架构角度看 NVMe 驱动NVMe 驱动的文件…...
一个测试人员,在现阶段的环境下如何在测试行业发展和自我价值。
前言周末和几个测试圈子里的大佬饭局上聊了一些职场和测试职业发展相关的话题,我将聊天的内容做了整理和阐述。。朋友圈有测试同学对这篇文章提了比较深刻的建议,下面是他的评价和建议:评价:据说是大佬饭桌总结,有两点…...
pwn手记录题2
fastbin_reverse_into_tcache(2.34) 本题所使用的libc版本为2.34;(最新版 libc2.34版本已经没有了所谓的hook函数,甚至exit_hook(实际为某个函数指针)也已经不能够使用;能够利用的手法已经很少了; 高版本glibc堆的几…...
Perplexity Stack Overflow查询响应延迟超8秒?紧急修复指南:从token压缩到领域微调的4层加速方案
更多请点击: https://intelliparadigm.com 第一章:Perplexity Stack Overflow查询响应延迟超8秒?紧急修复指南:从token压缩到领域微调的4层加速方案 当Perplexity在Stack Overflow数据源上出现平均响应延迟 > 8s 的告警时&am…...
技术债务的职场政治:谁该为历史遗留问题买单
在软件测试从业者的日常工作中,技术债务是一个绕不开的话题。它像一颗隐藏在代码深处的定时炸弹,随时可能在项目推进的某个节点爆发,引发一系列连锁反应。而当技术债务问题浮出水面时,一场关于“谁该为历史遗留问题买单”的职场政…...
上海交通大学用1万条数据打败了工业界巨头的AI搜索神器
这项由上海交通大学研究团队主导完成的研究,以技术报告形式于2026年5月5日发布在预印本平台arXiv,编号为arXiv:2605.04036v1。对这一领域有深入兴趣的读者可以通过该编号检索完整论文。**一个让整个AI圈子都有些意外的故事**先说一个背景:现在…...
Gemini自动生成PPT实战手册:从零输入到专业演示文稿,3步完成95%的幻灯片工作流
更多请点击: https://intelliparadigm.com 第一章:Gemini自动生成PPT的核心原理与能力边界 Gemini 生成 PPT 的本质并非传统模板填充,而是基于多模态理解与结构化内容重构的端到端推理过程。其核心依赖于对用户输入(文本、大纲、…...
Python金融数据分析实战:从数据清洗到LLM智能问答机器人构建
1. 项目概述:一个金融数据分析与智能问答的实战项目 最近在整理一些数据分析的实战项目,正好翻到了之前为Forage BCGX GenAI项目做的一个金融分析案例。这个项目麻雀虽小,五脏俱全,它完整地走了一遍从原始数据清洗、指标计算、可视…...
BetterRTX终极指南:三步免费提升Minecraft画质的完整方案
BetterRTX终极指南:三步免费提升Minecraft画质的完整方案 【免费下载链接】BetterRTX-Installer The Powershell Installer for BetterRTX! BetterRTX is a Ray-Tracing mod for Minecraft Bedrock. 项目地址: https://gitcode.com/gh_mirrors/be/BetterRTX-Insta…...
别再手动折腾了!用Stack Builder一键搞定PostGIS 2.1 for PostgreSQL 9.2 (Windows 64位)
告别繁琐配置:用Stack Builder轻松部署PostGIS空间数据库 在Windows环境下配置PostgreSQL的空间扩展PostGIS,传统方式往往需要手动下载安装包、配置环境变量、执行SQL脚本等一系列操作。对于刚接触空间数据库的开发者来说,这个过程既耗时又容…...
Corvus Robotics推出可在零下仓库中自主盘点库存的新型无人机
物理AI机器人系统提供商Corvus Robotics近日发布了Corvus One冷链版——一款专为在零下20华氏度至常温环境下持续运行而设计的自主库存管理系统。该系统专为抵御极端低温、气流、霜冻和冷凝水而打造,能够在无需人工干预的情况下,对库存进行高频次、高精度…...
【LeetCode 手撕算法】(二分查找)搜索插入位置、搜索二维矩阵、查找数组相同的所有位置、搜索旋转排序数组、旋转升序数组的最小值
复杂度为O(log n)且有序用二分查找35-搜索插入位置思路:二分查找,左右指针 求中间值注意:while的查询条件是>class Solution {public int searchInsert(int[] nums, int target) {int left0;int rightnums.length-1;while(left<right){…...
保姆级教程:小白也能轻松上手 AI 硬件
大家好,我是siuser小伟如果你是一个小白,又想玩一下硬件的话,那我一定推荐你去接触 AI 小智。因为他们的生态非常好,教程非常详细,你也可以跑一个专属于你自己的 AI 硬件。这篇文章专门写给第一次部署小智 Go 后端的人…...
