再写-全景拼接

全景拼接

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:
    # 对欧式距离进行筛选d
    if 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 = 4

    Homography, 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_left

    cv2.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 = 4

    Homography, 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_left

    cv2.namedWindow("全景图", cv2.WINDOW_AUTOSIZE)
    cv2.imshow("全景图", Panorama)
    cv2.imwrite("END.png", Panorama)
    cv2.waitKey(0)
    cv2.destroyAllWindows(

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Day19-【Java SE进阶】网络编程

一、网络编程 1.概述 可以让设备中的程序与网络上其他设备中的程序进行数据交互(实现网络通信的)。java.net,*包下提供了网络编程的解决方案! 基本的通信架构 基本的通信架构有2种形式:CS架构(Client客户端/Server服务端)、BS架构(Browser浏览器/Server服务端)。 网络通信的…

轮腿机器人-五连杆正运动学解算

轮腿机器人-五连杆与VMC 1.五连杆正运动学分析2.参考文献 1.五连杆正运动学分析 如图所示为五连杆结构图&#xff0c;其中A&#xff0c;E为机器人腿部控制的两个电机&#xff0c;θ1,θ4可以通过电机的编码器测得。五连杆控制任务主要关注机构末端C点位置&#xff0c;其位置用直…

【Unity】常见性能优化

1 前言 本文将介绍下常用的Unity自带的常用优化工具&#xff0c;并介绍部分常用优化方法。都是比较基础的内容。 2 界面 2.1 Statistics窗口 可以简单查看Unity运行时的统计数据&#xff0c;当前一帧的性能数据。 2.1.1 Audio 音频相关内容。 Level&#xff1a;音量大小&a…

物联网云组态平台

TopStack 物联网云组态平台&#xff0c;提供从边缘感知及设备到云的数据采集、分析、可视化软件服务&#xff0c;提供完善的平台开发环境&#xff0c;协助客户完善垂直领域的业务应用开发。与伙伴共同打造多元产业物联网解决方案。 产品采用微前端、微服务架构进行设计&#x…

Testng测试框架(7)--测试运行

忽略测试 TestNG可以让你忽略类、特殊包、包及其子中的所有Test方法。 当在测试方法级别使用Ignore 注解&#xff0c;在功能上与Test(enabledfalse).一样。 以下例子将忽略类中所有tests。 import org.testng.annotations.Ignore; import org.testng.annotations.Test; Ign…

day9 | 栈与队列 part-1 (Go) | 232 用栈实现队列、225 用队列实现栈

今日任务 栈与队列的理论基础 (介绍:代码随想录)232 用栈实现队列(题目: . - 力扣&#xff08;LeetCode&#xff09;)225 用队列实现栈 (题目: . - 力扣&#xff08;LeetCode&#xff09; ) 栈与队列的理论基础 栈 : 先进后出 队列: 后进先出 老师给的讲解:代码随想录 …

left join limit offset 分页查询问题

1. LEFT JOIN 简介 在开始讨论LEFT JOIN的使用方法之前&#xff0c;让我们先简要回顾一下LEFT JOIN的概念。 LEFT JOIN是一种用于将左表和右表连接起来的操作。它会返回左表中的所有记录&#xff0c;并且对于每条左表记录&#xff0c;如果在右表中找到符合条件的记录&#xf…

js+网络摄像头实现人体肢体关键点动作捕获

最近有一个项目&#xff0c;客户需要用户人体姿势识别&#xff0c;进行表演考核用途&#xff0c;或者康复中心用户恢复护理考核&#xff0c;需要用摄像头进行人体四肢进行肢体关键点对比考核&#xff0c;资料还是太少了。只有个别大佬发了部分技术指导。感觉写的不错。 阿里云…

算法第四十一天-排除排序链表中的重复元素Ⅱ

排除排序链表中的重复元素Ⅱ 题目要求 解题思路 题意&#xff1a;在一个有序链表中&#xff0c;如果一个节点的值出现不止一次&#xff0c;那么把这个节点删除掉 重点&#xff1a;有序链表&#xff0c;所以&#xff0c;一个节点的值出现不止一次&#xff0c;那么他们必相邻。…

CMC学习系列 (7):β 范围 EEG-EMG 相干性与皮质光谱功率有关

CMC学习系列:β 范围 EEG-EMG 相干性与皮质光谱功率有关 0. 引言1. 主要贡献2. 方法2.1 目标2.2 实验范式2.3 数据处理和分析 3. 结果4. 讨论5. 总结欢迎来稿 论文地址&#xff1a;https://www.sciencedirect.com/science/article/abs/pii/S1053811907001760 论文题目&#xff…

一、接口自动化之pytest 运行参数

1、在跟目录下创建一个配置项pytest.ini [pytest] testpaths./testcases markersp0:高于优先级test:测试环境pro:生成环境2、打标签 3、运行命名pytest -m "p0"

单链表详解(无哨兵位),实现增删改查

1.顺序表对比单链表的缺点 中间或头部插入时&#xff0c;需要移动数据再插入&#xff0c;如果数据庞大会导致效率降低每次增容就需要申请空间&#xff0c;而且需要拷贝数据&#xff0c;释放旧空间增容造成浪费&#xff0c;因为一般都是以2倍增容 2.链表的基础知识 链表也是线…

蓝桥杯 — — 数数

数数 友情链接&#xff1a;数数 题目&#xff1a; 思路&#xff1a; 这道题目主要用到了埃氏筛法&#xff08;Sieve of Eratosthenes&#xff09;来快速求解质数的方法&#xff0c;思路很巧妙&#xff0c;并且用到了动态规划的思想。 我们首先定义两个数组mk和p&#xff0c…

LPA3399Pro搭建Qt开发环境

将以前的开发文档在此做一个记录。 一、介绍 Qt是一个跨平台的应用程序开发框架&#xff0c;支持多种操作系统和硬件架构&#xff0c;包括ARM架构的Linux。 RK3399Pro是一款基于ARM架构的处理器&#xff0c;用于嵌入式系统。可以在RK3399上搭建Qt开发环境&#xff0c;进行项目…

C语言学习笔记之结构体(一)

目录 什么是结构体&#xff1f; 结构体的声明 结构体变量的定义和初始化 结构体成员的访问 结构体传参 什么是结构体&#xff1f; 在现实生活中的很多事物无法用单一类型的变量就能描述清楚&#xff0c;如&#xff1a;描述一个学生&#xff0c;需要姓名&#xff0c;年龄&a…

演示:单包攻击,扫描类攻击,畸形报文攻击[Land攻击,泪滴攻击,ip地址欺骗]。配置防火墙进行防御

浏览上篇博客进行环境搭建 单包攻击 单包攻击&#xff08;Single Packet Attack&#xff09;是一种利用网络协议或应用程序中的漏洞进行的攻击方式。这种攻击通常只需要发送一个精心构造的数据包&#xff0c;就能够触发目标系统的漏洞&#xff0c;导致攻击者能够执行非授权的…

JVM修炼之路【12】- GC调优 、性能调优

上一篇中 我们详细讲了内存溢出 内存泄漏 还有相关的案例。 这篇博客中我们主要了解一下GC调优。 有些新手可能会有一点 疑问—— 这两者不是一回事吗&#xff1f;&#xff1f; 其实说一回事 也没错 因为GC调优本质上还是针对 堆上的内存 只不过前面我们关注的侧重点在于 不合…

关于机器学习中贝叶斯学习(Bayesian Learning)计算公式的理解

一、引言 在《统计学习的分类概述》中介绍了贝叶斯学习的概念和计算公式&#xff0c;可以看到这个公式就是概率统计理论中的贝叶斯公式&#xff0c;但在机器学习中这个公式与概率统计中的理解要复杂得多。 二、贝叶斯学习公式及各组成因子的含义 要理解贝叶斯学习公式&#…

【Spring Security】1.Spring Security介绍 功能介绍

文章目录 一、Spring Security介绍二、功能介绍 一、Spring Security介绍 官方文档&#xff1a;https://docs.spring.io/spring-security/reference/index.html 官网解释&#xff1a;Spring Security 是一个提供 身份验证、授权 和 针对常见攻击的保护 的框架。 它为 保护命令…

运放噪声评估的来龙去脉

运放噪声评估的来龙去脉 友情提示&#xff0c;运放电路的噪声分析还是比较复杂的&#xff0c;不论是基础理论还是对应的推导过程&#xff0c;都不是特别容易。考虑到兄弟们的基础参差不齐&#xff0c;所以我还是尽量说清楚点&#xff0c;这样导致看起来就有点罗里吧嗦&#xff…