三、全景拼接

一、项目所涉及到的一些知识点

Ⅰ,BF(Brute-Force)暴力匹配:把两张图像的特征点全部给算出来,然后使用归一化的欧氏距离比较这两张图像上特征点之间的大小关系,越小越相似。

SIFT算法

import cv2
import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline
def cv_show(name,img):cv2.imshow(name,img)cv2.waitKey(0)cv2.destroyAllWindows()
image1 = cv2.imread("book1.jpg")
image2 = cv2.imread("book2.jpg")
cv_show('image1',image1)
cv_show('image2',image2)
sift = cv2.xfeatures2d.SIFT_create()#SIFT构造特征
kp1,des1 = sift.detectAndCompute(image1,None)#计算图像的关键点并且去计算特征向量
kp2,des2 = sift.detectAndCompute(image2,None)#得到kp1图像的特征点、des特征点所对应的特征向量
bf = cv2.BFMatcher(crossCheck=True)

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

1对1匹配
matches = bf.match(des1,des2)
matches = sorted(matches,key=lambda x : x.distance)#因为获取到的特征太多了,这里根据相似程度来进行排序
image3 = cv2.drawMatches(image1,kp1,image2,kp2,matches[:10],None,flags=2)#将图像的关键点相近的进行连接在一块,把相似的关键点前十给绘制出来
cv_show('image3',image3)

在这里插入图片描述

1对K匹配
bf = cv2.BFMatcher()
matches = bf.knnMatch(des1,des2,k=2)#一个特征点找打与它2个相近的点
good = []
for m,n in matches:#将关键点进行过滤操作if m.distance < 0.75*n.distance:good.append([m])
image3 = cv2.drawMatchesKnn(image1,kp1,image2,kp2,good,None,flags=2)
cv_show('image3',image3)

在这里插入图片描述

Ⅱ,RANSAC(Random sample consensus)随机抽样一致算法

最小二乘法

回归算法中有最小二乘法,也就是有一些数据点,需要进行拟合这些数据点,拟合的函数要尽可能多的去满足所有的数据点。
由于最小二乘法为了满足所有的数据点,此时拟合的函数并不是特别理想的,因为有一些噪音点进行了误导。
在这里插入图片描述
在这里插入图片描述

RANSAC

RANSAC效果就显然好多了,因为它不受一些噪音点的误导。
在这里插入图片描述
在这里插入图片描述
RANSAC算法思路:选择初始样本点进行拟合,给定一个容忍范围,不断的进行更新迭代。
例如:初始样本点的格式为2
在这里插入图片描述
设置容忍范围,也就是这个线周围的虚线,这里找到有9个点属于局内点,是自己人,在容忍范围之内
在这里插入图片描述
接下来接着迭代,找到8个局内点,在容忍范围内,以此类推一直迭代,直到最后找出在容忍范围内拟合点最多的那一条曲线,就是最后求解的拟合曲线。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

单应性矩阵

图像可以通过单应性矩阵进行空间维度的变换,一般为3*3的矩阵,为了归一化方便,最后一个值常设置为1。即,单应性矩阵需要求解8个未知数,,需要8个方程,最少需要4对特征点。
在这里插入图片描述
为了构建单应性矩阵最少需要4对特征点,但是选取哪几对特征点好呢?图片进行暴力匹配之后会有很多的特征点,但是并不是所有的特征点都是正确的,故需要通过RANSAC算法进行筛选出效果最好的4对特征点来进行构建单应性矩阵。

二、完整代码

from Stitcher import Stitcher
import numpy as np
import cv2class Stitcher:# 拼接函数def stitch(self, images, ratio=0.75, reprojThresh=4.0, showMatches=False):# 获取输入图片(imageB, imageA) = images# 检测A、B图片的SIFT关键特征点,并计算特征描述子(kpsA, featuresA) = self.detectAndDescribe(imageA)(kpsB, featuresB) = self.detectAndDescribe(imageB)# 匹配两张图片的所有特征点,返回匹配结果M = self.matchKeypoints(kpsA, kpsB, featuresA, featuresB, ratio, reprojThresh)# 如果返回结果为空,没有匹配成功的特征点,退出算法if M is None:return None# 否则,提取匹配结果# H是3x3视角变换矩阵(matches, H, status) = M# 将图片A进行视角变换,result是变换后图片result = cv2.warpPerspective(imageA, H, (imageA.shape[1] + imageB.shape[1], imageA.shape[0]))self.cv_show('result', result)# 将图片B传入result图片最左端result[0:imageB.shape[0], 0:imageB.shape[1]] = imageBself.cv_show('result', result)# 检测是否需要显示图片匹配if showMatches:# 生成匹配图片vis = self.drawMatches(imageA, imageB, kpsA, kpsB, matches, status)# 返回结果return (result, vis)# 返回匹配结果return resultdef cv_show(self, name, img):cv2.imshow(name, img)cv2.waitKey(0)cv2.destroyAllWindows()def detectAndDescribe(self, image):# 将彩色图片转换成灰度图gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)# 建立SIFT生成器descriptor = cv2.xfeatures2d.SIFT_create()# 检测SIFT特征点,并计算描述子(kps, features) = descriptor.detectAndCompute(image, None)# 将结果转换成NumPy数组kps = np.float32([kp.pt for kp in kps])# 返回特征点集,及对应的描述特征return (kps, features)def matchKeypoints(self, kpsA, kpsB, featuresA, featuresB, ratio, reprojThresh):# 建立暴力匹配器matcher = cv2.BFMatcher()# 使用KNN检测来自A、B图的SIFT特征匹配对,K=2rawMatches = matcher.knnMatch(featuresA, featuresB, 2)matches = []for m in rawMatches:# 当最近距离跟次近距离的比值小于ratio值时,保留此匹配对if len(m) == 2 and m[0].distance < m[1].distance * ratio:# 存储两个点在featuresA, featuresB中的索引值matches.append((m[0].trainIdx, m[0].queryIdx))# 当筛选后的匹配对大于4时,计算视角变换矩阵if len(matches) > 4:# 获取匹配对的点坐标ptsA = np.float32([kpsA[i] for (_, i) in matches])ptsB = np.float32([kpsB[i] for (i, _) in matches])# 计算视角变换矩阵(H, status) = cv2.findHomography(ptsA, ptsB, cv2.RANSAC, reprojThresh)# 返回结果return (matches, H, status)# 如果匹配对小于4时,返回Nonereturn Nonedef drawMatches(self, imageA, imageB, kpsA, kpsB, matches, status):# 初始化可视化图片,将A、B图左右连接到一起(hA, wA) = imageA.shape[:2](hB, wB) = imageB.shape[:2]vis = np.zeros((max(hA, hB), wA + wB, 3), dtype="uint8")vis[0:hA, 0:wA] = imageAvis[0:hB, wA:] = imageB# 联合遍历,画出匹配对for ((trainIdx, queryIdx), s) in zip(matches, status):# 当点对匹配成功时,画到可视化图上if s == 1:# 画出匹配对ptA = (int(kpsA[queryIdx][0]), int(kpsA[queryIdx][1]))ptB = (int(kpsB[trainIdx][0]) + wA, int(kpsB[trainIdx][1]))cv2.line(vis, ptA, ptB, (0, 255, 0), 1)# 返回可视化结果return vis# 读取拼接图片
imageA = cv2.imread("left.jpg")
imageB = cv2.imread("right.jpg")# 把图片拼接成全景图
stitcher = Stitcher()
(result, vis) = stitcher.stitch([imageA, imageB], showMatches=True)# 显示所有图片
cv2.imshow("Image A", imageA)
cv2.imshow("Image B", imageB)
cv2.imshow("Keypoint Matches", vis)
cv2.imshow("Result", result)
cv2.waitKey(0)
cv2.destroyAllWindows()

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

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

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

相关文章

找回自建SVN密码

自建了一个SVN Repo自己用。重装系统之后密码忘了。 经过了漫长的Google过程&#xff0c;才知道Repo中的密码居然是明文保存的。 在yourRepoDir/conf/svnserve.conf下的password-db处设置&#xff0c;通常是yourRepoDir/conf/passwd文件。 打开passwd文件&#xff0c;就是明文保…

ruby hash方法_Ruby中带有示例的Hash.invert方法

ruby hash方法Hash.invert方法 (Hash.invert Method) In this article, we will study about Hash.invert Method. The working of this method can be predicted with the help of its name but it is not as simple as it seems. Well, we will understand this method with …

leetcode 216. 组合总和 III 思考分析

可能需要回顾的文章; leetcode 77. 组合 思考分析 1、题目 找出所有相加之和为 n 的 k 个数的组合。组合中只允许含有 1 - 9 的正整数&#xff0c;并且每种组合中不存在重复的数字。 说明&#xff1a; 所有数字都是正整数。 解集不能包含重复的组合。 2、递归 这一题和之前…

【Unity】Update()和FixedUpdate()

Update()每帧调用&#xff0c;FixedUpdate&#xff08;&#xff09;以指定频率被调用。可以在 Edit -> project settings -> Time -> Fixed Timestep 中设定该频率。转载于:https://www.cnblogs.com/xiayong123/p/3717002.html

约束执行区域(CER)

受约束的执行区域 (CER) 是创作可靠托管代码的机制的一部分。CER 定义一个区域&#xff0c;在该区域中公共语言运行库 (CLR) 会受到约束&#xff0c;不能引发可使区域中的代码无法完全执行的带外异常。在该区域中&#xff0c;用户代码受到约束&#xff0c;不能执行会导致引发带…

python 抓取网页链接_从Python中的网页抓取链接

python 抓取网页链接Prerequisite: 先决条件&#xff1a; Urllib3: It is a powerful, sanity-friendly HTTP client for Python with having many features like thread safety, client-side SSL/TSL verification, connection pooling, file uploading with multipart encod…

四、模拟英语四六级答题卡识别阅卷评分

一、思路分析 首先拿到答题卡照片的时候&#xff0c;需要对照片进行一系列预处理操作&#xff0c;通过透视变换将图像摆正方便后续的操作。每一道题五个选项&#xff0c;有五道题&#xff0c;通过字典存放准确答案。没有依次对答题卡进行轮廓检测&#xff0c;这里采用的是正方…

leetcode 17. 电话号码的字母组合 思考分析

题目 给定一个仅包含数字 2-9 的字符串&#xff0c;返回所有它能表示的字母组合。 给出数字到字母的映射如下&#xff08;与电话按键相同&#xff09;。注意 1 不对应任何字母。 思考与递归程序 解空间树的宽度是输入数字对应的字符的个数&#xff0c;深度是输入的数字的个数…

Blockquotes,引用,html里面,经常用到的一个!

blockquote元素的使用已经非常多样化&#xff0c;但语义上它只适用于一件事–标记了一段你的网页被引用从另一来源。这意味着&#xff0c;如果你想让那些花俏的引文&#xff0c;<blockquote>是不是你应该使用元素。让我们看一看如何你应该使用此元素&#xff1a; <art…

仔细分析了下这7行,貌似时间复杂度,空间复杂度都不大,为嘛就是执行效率这么低?...

for(Girl girl Girls.first(); !myGirlFriend.like(me); girl Girls.next()){if(!girl.hasBoyFriend(now) && i.like(girl)) { GirlFriend myGirlFriend (GirlFriend)girl; }} 转载于:https://www.cnblogs.com/naran/archive/2011/12/28/2305467.html…

BHMS的完整形式是什么?

BHMS&#xff1a;顺势疗法医学和外科学士 (BHMS: Bachelor of Homeopathic Medicine and Surgery) BHMS is an abbreviation of Bachelor of Homeopathic Medicine and Surgery. It is a medical degree program for under graduation in Homeopathy; an alternative move towa…

c++编程思想2 --友元存储控制

友元friend在c中的应用 我们知道在c的类访问权限中,private和 protected在类外面进行访问的时候 会因为权限而不能访问 &#xff0c;友元就解决了这个问题 。 可以这样理解&#xff0c;他为外部的 函数 或者类 进行了 访问授权,其实这已经超出OOP的范畴,但是对于C而言是以实用…

WordPress Event Easy Calendar插件多个跨站请求伪造漏洞

漏洞名称&#xff1a;WordPress Event Easy Calendar插件多个跨站请求伪造漏洞CNNVD编号&#xff1a;CNNVD-201309-083发布时间&#xff1a;2013-09-11更新时间&#xff1a;2013-09-11危害等级&#xff1a; 漏洞类型&#xff1a;跨站请求伪造威胁类型&#xff1a;远程CVE编号&…

XML转txt格式脚本

一、东北大学老师收集的钢材缺陷数据集是XML格式的&#xff0c;但是YOLOv5只允许使用txt文件标签 例如其中一种缺陷图片所对应的标签&#xff1a;crazing_1.xml <annotation><folder>cr</folder><filename>crazing_1.jpg</filename><source&…

python程序生成exe_使用Python程序生成QR代码的Python程序

python程序生成exeQR code is a short form of the quick response code. It is a type of matrix barcode that contains some information like some specific link, important message, email-id, etc. In Python, the qrcode module is used to generate the QR code of so…

leetcode 242. 有效的字母异位词 思考分析

题目 给定两个字符串 s 和 t &#xff0c;编写一个函数来判断 t 是否是 s 的字母异位词。 我们先考虑低阶版本&#xff0c;认为字符只有26种可能&#xff0c;然后将a ~ z的字符映射到数组的索引0 ~ 25&#xff0c;数组中存放的则是该索引出现的频次。 记录下s的频次和t的频次…

总结一下ERP .NET程序员必须掌握的.NET技术,掌握了这些技术工作起来才得心应手...

从毕业做.NET到现在&#xff0c;有好几年了&#xff0c;自认为只能是达到熟练的水平&#xff0c;谈不上精通。所以&#xff0c;总结一下&#xff0c;自己到底熟练掌握了哪些.NET方面的开发技术&#xff0c;以此对照&#xff0c;看看还有哪些不足&#xff0c;欢迎补充。 1 .NET …

js \n直接显示字符串_显示N个字符的最短时间

js \n直接显示字符串Problem statement: 问题陈述&#xff1a; You need to display N similar characters on a screen. You are allowed to do three types of operation each time. 您需要在屏幕上显示N个相似的字符。 每次允许您执行三种类型的操作。 You can insert a c…

示例 Demo 工程和 API 参考链接

Camera Explorer&#xff1a;有关 Windows Phone8 中有关增强 Camera API 的使用。文章链接 Filter Effects&#xff1a;对拍摄的照片或者图片库中的照片应用 Nokia Imaging SDK 中的滤镜。文章链接 Filter Explorer&#xff1a;演示了对新拍摄图片或者现有图片的编辑功能&…

三、标签准备

所有操作均在anaconda中的自己配置的环境下进行 一、安装labelimg 因为YOLO模型所需要的样本标签必须是txt类型&#xff0c;本人使用labelimg软件进行对图像进行打标签操作。 pip install pycocotools-windows pip install pyqt5 pip install labelimg 通过labelimg命令打…