三、全景拼接

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

Ⅰ,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,一经查实,立即删除!

相关文章

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

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

约束执行区域(CER)

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

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

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

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

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

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…

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的频次…

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…

三、标签准备

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

leetcode 39. 组合总和 思考分析

目录1、题目2、思考分析3、未经优化代码4、剪枝优化1、题目 给定一个无重复元素的数组 candidates 和一个目标数 target &#xff0c;找出 candidates 中所有可以使数字和为 target 的组合。 candidates 中的数字可以无限制重复被选取。 2、思考分析 解空间树宽度部分即数…

一、机器学习概念

一、何为机器学习(Mechine Learning)&#xff1f; 答&#xff1a;利用已有数据(经验)&#xff0c;来训练某种模型&#xff0c;利用此模型来预测未来。机器学习是人工智能的核心Mechine Learning。 例如&#xff1a;你和狗蛋儿7点在老槐树下集合&#xff0c;如何一块约去开黑&a…

Java线程新特征——Java并发库

一、线程池 Sun在Java5中&#xff0c;对Java线程的类库做了大量的扩展&#xff0c;其中线程池就是Java5的新特征之一&#xff0c;除了线程池之外&#xff0c;还有很多多线程相关的内容&#xff0c;为多线程的编程带来了极大便利。为了编写高效稳定可靠的多线程程序&#xff0c;…

leetcode 40. 组合总和 II 思考分析

题目 给定一个数组 candidates 和一个目标数 target &#xff0c;找出 candidates 中所有可以使数字和为 target 的组合。 candidates 中的每个数字在每个组合中只能使用一次。 思考以及代码 如果我们直接套用39题的思路&#xff0c;那么就会出现重复的组合。 重复组合的…

二、线性回归

一、回归 可以拿正态分布为例&#xff0c;比如身高&#xff0c;若平均身高为1.78m&#xff0c;绝大多数人都是1.78m左右&#xff0c;超过2m的很少&#xff0c;低于1m的也不多。 很多事情都会回归到一定的区间之内&#xff0c;即回归到平均值。 机器学习没有完美解&#xff0c…

【转】HMM学习最佳范例五:前向算法1 .

五、前向算法&#xff08;Forward Algorithm&#xff09; 计算观察序列的概率&#xff08;Finding the probability of an observed sequence&#xff09; 1.穷举搜索&#xff08; Exhaustive search for solution&#xff09;  给定隐马尔科夫模型&#xff0c;也就是在模型参…

leetcode 349. 两个数组的交集 思考分析

题目 给定两个数组&#xff0c;编写一个函数来计算它们的交集。 1、暴力双for循环 class Solution { public:vector<int> intersection(vector<int>& nums1, vector<int>& nums2) {vector<int> result;vector<int> res;if(nums1.siz…

三、梯度下降法求解最优θ值

一、梯度下降法(GD&#xff0c;Gradient Descent) Ⅰ、得到目标函数J(θ)&#xff0c;求解使得J(θ)最小时的θ值 当然&#xff0c;这里只是取了俩特征而已&#xff0c;实际上会有m个特征维度 通过最小二乘法求目标函数最小值 令偏导为0即可求解出最小的θ值&#xff0c;即…

leetcode 131. 分割回文串 思考分析

题目 给定一个字符串 s&#xff0c;将 s 分割成一些子串&#xff0c;使每个子串都是回文串。 返回 s 所有可能的分割方案。 思考 问题可以分为两个子问题&#xff1a;1、判断回文串2、分割数组 判断回文串 bool isPalindrome_string(string s,int startindex,int endinde…