再写-全景拼接

全景拼接

1. 将读取进行灰度转化,并且输出图像,关键点和计算描述

import cv2
import numpy as np# 将读取进行灰度转化,并且输出图像,关键点和计算描述
image_left = cv2.imread("C:\\Users\\HONOR\\Desktop\\image\\pinjie_1.png")
image_right = cv2.imread("C:\\Users\\HONOR\\Desktop\\image\\pinjie_2.png")
imge_letf = cv2.resize(image_left, (image_right.shape[1], image_left.shape[0]))
print(imge_letf.shape)
# 图像灰度化
image_left_gray = cv2.cvtColor(image_left, cv2.COLOR_RGB2GRAY)
image_right_gray = cv2.cvtColor(image_right, cv2.COLOR_RGB2GRAY)
# 创建sift对象
sift = cv2.SIFT_create()
# 计算关键点
kp_left, des_left = sift.detectAndCompute(image_left_gray, None)
kp_right, des_right = sift.detectAndCompute(image_right_gray, None)
# 绘制关键点
draw_left = cv2.drawKeypoints(image_left_gray, kp_left, None, flags=cv2.DRAW_MATCHES_FLAGS_NOT_DRAW_SINGLE_POINTS
)
draw_right = cv2.drawKeypoints(image_right_gray, kp_right, None, flags=cv2.DRAW_MATCHES_FLAGS_NOT_DRAW_SINGLE_POINTS
)
# 显示图片
cv2.imshow('draw_left', np.hstack((image_left, draw_left)))
cv2.imshow('draw_right', np.hstack((image_right, draw_right)))
cv2.waitKey(0)
# 保存图片
cv2.imwrite('draw_left.png', np.hstack((image_left, draw_left)))
cv2.imwrite('draw_right.png', np.hstack((image_right, draw_right)))

运行后保存图片:
请添加图片描述

在这里插入图片描述

2.利用匹配器 匹配两个描述符的相近程度,并将特征点进行连线

# 使用**cv.BFMatcher**()创建BFMatcher对象
bf = cv2.BFMatcher()
# 利用匹配器 匹配两个描述符的相近程度
# (knn 匹配可以返回k个最佳的匹配项    bf返回所有的匹配项)
matches = bf.knnMatch(des_right, des_left, k=2)
# 按照相近程度,进行排序
matches = sorted(matches, key=lambda x: x[0].distance / x[1].distance)good = []for m, n in matches:# 对欧式距离进行筛选dif m.distance < 0.6 * n.distance:good.append(m)
all_good_image = cv.drawMatches(img_right, key_right, img_left, key_left, good_match, None, None, None, None, flags=2)bfs.img_show("关键点之间进行连线", all_goog_image)

在这里插入图片描述

3.对图像进行拼接

if len(good) > 4:ptsR = np.float32([kp_right[m.queryIdx].pt for m in good]).reshape(-1, 1, 2)ptsL = np.float32([kp_left[m.trainIdx].pt for m in good]).reshape(-1, 1, 2)ransacReprojThreshold = 4Homography, status = cv2.findHomography(ptsR, ptsL, cv2.RANSAC, ransacReprojThreshold)Panorama = cv2.warpPerspective(image_right, Homography, (image_right.shape[1] + image_left.shape[1], image_right.shape[0]))cv2.imshow("扭曲变换后的右图", Panorama)cv2.imwrite('扭曲变换后的右图.png', Panorama)cv2.waitKey(0)cv2.destroyAllWindows()Panorama[0:image_left.shape[0], 0:image_left.shape[1]] = image_leftcv2.namedWindow("全景图", cv2.WINDOW_AUTOSIZE)cv2.imshow("全景图", Panorama)cv2.imwrite("END.png", Panorama)cv2.waitKey(0)cv2.destroyAllWindows()

在这里插入图片描述
在这里插入图片描述

    Panorama[0:image_left.shape[0], 0:image_left.shape[1]] = image_left
ValueError: could not broadcast input array from shape (376,498,3) into shape (374,498,3)

以上保存的原因是:出现这个问题的主要原因是因为list中array的shape不一致造成的,所以发生这个问题的时候。

解决方法:这个 时候检测一下面这两段代码有没有起作用

image_right = cv2.resize(image_right, (400, 800))
image_left = cv2.resize(image_left, (400, 800))

bug解决:
在这里插入图片描述

如果我们的扭曲变换后的图最后的图出现这样的情况的话我们需要关注一下以下代码

因为这个段代码是将左图`des_left`作为模板图,右图作为`des_right`最为去匹配的图
matches = bf.knnMatch(des_left, des_right, k=2)但是这两段代码所反映的情况是将右图作为模板图进行拼接(也就是计算机蒙了)Panorama = cv2.warpPerspective(image_right, Homography, (image_right.shape[1] + image_left.shape[1], image_right.shape[0]))Panorama[0:image_left.shape[0], 0:image_left.shape[1]] = image_left

源码:

# -*- coding: UTF-8 -*-
# @Project :opencv 
# @File    :全景拼接笔记.py
# @Author  :阿龙的代码在报错
# @IDE     :PyCharm 
# @Date    :2024/4/13 16:23
import cv2
import numpy as np# 将读取进行灰度转化,并且输出图像,关键点和计算描述
image_left = cv2.imread("C:\\Users\\HONOR\\Desktop\\image\\pinjie_1.png")
image_right = cv2.imread("C:\\Users\\HONOR\\Desktop\\image\\pinjie_2.png")
# 将图片设置为同样的大小
image_right = cv2.resize(image_right, (400, 800))
image_left = cv2.resize(image_left, (400, 800))
# 图像灰度化
gray_left = cv2.cvtColor(image_left, cv2.COLOR_BGR2GRAY)
gray_right = cv2.cvtColor(image_right, cv2.COLOR_BGR2GRAY)sift = cv2.SIFT_create()kp_left, des_left = sift.detectAndCompute(image_left, None)
kp_right, des_right = sift.detectAndCompute(image_right, None)draw_left = cv2.drawKeypoints(gray_left, kp_left, None, flags=cv2.DRAW_MATCHES_FLAGS_NOT_DRAW_SINGLE_POINTS)draw_right = cv2.drawKeypoints(gray_right, kp_right, None, flags=cv2.DRAW_MATCHES_FLAGS_NOT_DRAW_SINGLE_POINTS)# 显示图片
cv2.imshow('draw_left', np.hstack((image_left, draw_left)))
cv2.imshow('draw_right', np.hstack((image_right, draw_right)))
cv2.waitKey(0)
# 保存图片
cv2.imwrite('draw_left.png', np.hstack((image_left, draw_left)))
cv2.imwrite('draw_right.png', np.hstack((image_right, draw_right)))# 使用**cv.BFMatcher**()创建BFMatcher对象
bf = cv2.BFMatcher()
# 利用匹配器 匹配两个描述符的相近成都
# (knn 匹配可以返回k个最佳的匹配项    bf返回所有的匹配项)
matches = bf.knnMatch(des_right, des_left, k=2)# queryDescriptors:查询图像的特征描述子集 (第一个参数)
# trainDescriptors:训练图像的特征描述子集 (第二个参数)
# 按照相近程度,进行排序
matches = sorted(matches, key=lambda x: x[0].distance / x[1].distance)good = []for m, n in matches:# 对欧式距离进行筛选if m.distance < 0.6 * n.distance:good.append(m)
all_goog_image = cv2.drawMatches(image_right, kp_right, image_left, kp_left, good, None, None, None, None, flags=2
)
cv2.imshow("关键点之间进行连线", all_goog_image)
cv2.imwrite('all_good.png', all_goog_image)if len(good) > 4:ptsR = np.float32([kp_right[m.queryIdx].pt for m in good]).reshape(-1, 1, 2)ptsL = np.float32([kp_left[m.trainIdx].pt for m in good]).reshape(-1, 1, 2)ransacReprojThreshold = 4Homography, status = cv2.findHomography(ptsR, ptsL, cv2.RANSAC, ransacReprojThreshold)Panorama = cv2.warpPerspective(image_right, Homography, (image_right.shape[1] + image_left.shape[1], image_right.shape[0]))cv2.imshow("扭曲变换后的右图", Panorama)cv2.imwrite('扭曲变换后的右图.png', Panorama)cv2.waitKey(0)cv2.destroyAllWindows()Panorama[0:image_left.shape[0], 0:image_left.shape[1]] = image_leftcv2.namedWindow("全景图", cv2.WINDOW_AUTOSIZE)cv2.imshow("全景图", Panorama)cv2.imwrite("END.png", Panorama)cv2.waitKey(0)cv2.destroyAllWindows(

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

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

相关文章

机器人坐标系转换之从世界坐标系到局部坐标系

三角函数实现 下面是代码c和python实现&#xff1a; #include <iostream> #include <cmath>struct Point {double x;double y; };class RobotCoordinateTransform { private:Point origin; // 局部坐标系的原点在世界坐标系中的坐标public:RobotCoordinateTransfo…

【深度学习】图像风格混合——StyleGAN2原理解析

1、前言 上一篇文章&#xff0c;我们详细讲解了StyleGAN的原理。这篇文章&#xff0c;我们就来讲解一下StyleGAN2&#xff0c;也就是StyleGAN的改进版。 原论文&#xff1a;Analyzing and Improving the Image Quality of StyleGAN 参考代码&#xff1a;①Pytorch版本&#…

【Godot4.2】CanvasItem绘图函数全解析 - 7.自定义节点TextBoard

概述 之前发布的几篇文章几乎阐述了CanvasItem绘图函数最基础的内容。 本篇结合draw_style_box()和TextParagraph类&#xff0c;自定义了一个可以自适应宽高显示多行文本&#xff0c;且带有一个样式盒作为背景的文字板节点TextBoard。 系列目录 0.概述1.绘制简单图形2.设定绘…

SPP论文笔记

这篇论文讨论了在深度卷积网络中引入空间金字塔池化&#xff08;SPP&#xff09;层的方法&#xff0c;以解决传统深度卷积网络需要固定图像尺寸的限制。以下是论文各部分的总结&#xff1a; 1. 引言 论文指出现有的深度卷积神经网络&#xff08;CNN&#xff09;需要固定大小的…

全景剖析SSD SLC Cache缓存设计原理-2

四、SLC缓存对SSD的寿命是否有优化&#xff1f; 当使用QLC或TLC NAND闪存并将其切换到SLC模式进行写入时&#xff0c;会对闪存的寿命产生以下影响&#xff1a; 短期寿命提升&#xff1a; SLC模式下&#xff0c;每个存储单元仅存储一个比特数据&#xff0c;相对于QLC或TLC来说…

前端vue: 使用ElementUI适配国际化

i18n介绍 i18n&#xff08;其来源是英文单词 internationalization的首末字符i和n&#xff0c;18为中间的字符数&#xff09;是“国际化”的简称。 前端国际化步骤 1、安装i18n插件 安装插件时候&#xff0c;注意必须指定版本号&#xff0c;不然安装会报错。 npm i vue-i1…

linux 部署安装mongodb教程

现在去官网下载mongodb的tar包,在本地创建文件夹 cd /home wget https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-rhel70-4.2.17.tgz tar -zxvf mongodb-linux-x86_64-rhel70-4.2.17.tgz mv mongodb-linux-x86_64-rhel70-4.2.17 mongodb cd /home/mongodb mkdir log t…

GAN:对抗式生成网络之图片生成

对抗式生成网络(Adversarial Generative Network, AGN)这一术语在您提供的信息中并未直接出现。通常,在深度学习文献和实践中,与“对抗”和“生成”概念相结合的网络架构指的是生成式对抗网络(Generative Adversarial Networks, GANs)。GANs由Ian Goodfellow等人于2014年…

数据结构之单链表相关刷题

找往期文章包括但不限于本期文章中不懂的知识点&#xff1a; 个人主页&#xff1a;我要学编程(ಥ_ಥ)-CSDN博客 所属专栏&#xff1a;数据结构 数据结构之单链表的相关知识点及应用-CSDN博客 下面题目基于上面这篇文章&#xff1a; 下面有任何不懂的地方欢迎在评论区留言或…

wangeditor与deaftjs的停止维护,2024编辑器该如何做技术选型(一)

wangeditor暂停维护的声明&#xff1a; wangeditor是国内开发者开发的编辑器&#xff0c;用户也挺多&#xff0c;但是由于作者时间关系&#xff0c;暂停维护。 deaft的弃坑的声明&#xff1a; draft是Facebook开源的&#xff0c;但是也弃坑了&#xff0c;说明设计的时候存在很大…

LeetCode最长有效括号问题解

给定一个仅包含字符的字符串(’ 和 ‘)’&#xff0c;返回最长有效的长度(出色地-形成) 括号子弦。 示例1&#xff1a; 输入&#xff1a;s “(()” 输出&#xff1a;2 说明&#xff1a;最长的有效括号子字符串是 “()” 。 示例2&#xff1a; 输入&#xff1a;s “)()())…

在Linux上利用mingw-w64生成exe文件

一、概要 1、elf与exe 在Linux上用gcc直接编译出来的可执行文件是elf格式的&#xff0c;在Windows上是不能运行的 Windows上可执行文件的格式是exe 利用mingw-w64可以在Linux上生成exe格式的可执行文件&#xff0c;将该exe文件拷贝到Windows上就可以运行 2、程序要留给用户…

体验Humane AI:我与可穿戴AI别针的生活

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗&#xff1f;订阅我们的简报&#xff0c;深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同&#xff0c;从行业内部的深度分析和实用指南中受益。不要错过这个机会&#xff0c;成为AI领…

如何使用 ArcGIS Pro 制作热力图

热力图是一种用颜色表示数据密度的地图&#xff0c;通常用来显示空间分布数据的热度或密度&#xff0c;我们可以通过 ArcGIS Pro 来制作热力图&#xff0c;这里为大家介绍一下制作的方法&#xff0c;希望能对你有所帮助。 数据来源 教程所使用的数据是从水经微图中下载的POI数…

JVM复习

冯诺依曼模型与计算机处理数据过程相关联&#xff1a; 冯诺依曼模型&#xff1a; 输入/输出设备存储器输出设备运算器控制器处理过程&#xff1a; 提取阶段&#xff1a;输入设备传入原始数据&#xff0c;存储到存储器解码阶段&#xff1a;由CPU的指令集架构ISA将数值解…

分布式技术--------------ELK大规模日志实时收集分析系统

目录 一、ELK日志分析系统 1.1ELK介绍 1.2ELK各组件介绍 1.2.1ElasticSearch 1.2.2Kiabana 1.2.3Logstash 1.2.4可以添加的其它组件 1.2.4.1Filebeat filebeat 结合logstash 带来好处 1.2.4.2缓存/消息队列&#xff08;redis、kafka、RabbitMQ等&#xff09; 1.2.4.…

搭建基于Hexo的个人博客,以及git相关命令

全文写完之后的总结 测试命令 hexo clean hexo g hexo s 上传到服务器命令 hexo clean hexo g hexo d 上传到服务器&#xff08;如果上一个命令用不了&#xff09;&#xff0c;也要先hexo clean,hexo g git init git add . git commit -m "first commit" git p…

部署HDFS集群(完全分布式模式、hadoop用户控制集群、hadoop-3.3.4+安装包)

目录 前置 一、上传&解压 &#xff08;一 &#xff09;上传 &#xff08;二&#xff09;解压 二、修改配置文件 &#xff08;一&#xff09;配置workers文件 &#xff08;二&#xff09;配置hadoop-env.sh文件 &#xff08;三&#xff09;配置core-site.xml文件 &…

Fuel tank position

Fuel tank position 汽车油箱位置在哪里&#xff0c;加油的时候就不会听错方向

uni-app的页面中使用uni-map-common的地址解析(地址转坐标)功能,一直报请求云函数出错

想在uni-app的页面中使用uni-map-common的地址解析&#xff08;地址转坐标&#xff09;功能&#xff0c;怎么一直报请求云函数出错。 不看控制台啊,弄错了控制台&#xff0c;就说怎么一直没有打印出消息。 所以开始换高德地图的&#xff0c;昨天申请了两个 一开始用的第二个web…