当前位置:网站首页>opencv学习笔记六--图像拼接
opencv学习笔记六--图像拼接
2022-07-01 14:52:00 【Cloudy_to_sunny】
opencv学习笔记六--图像拼接
import numpy as np
import cv2
import matplotlib.pyplot as plt#Matplotlib是RGB
class 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]] = imageB
self.cv_show('result', result)
# 检测是否需要显示图片匹配
if showMatches:
# 生成匹配图片
vis = self.drawMatches(imageA, imageB, kpsA, kpsB, matches, status)
# 返回结果
return (result, vis)
# 返回匹配结果
return result
#显示函数
def cv_show(self,name,img):
b,g,r = cv2.split(img)
img_rgb = cv2.merge((r,g,b))
plt.imshow(img_rgb)
plt.show()
def cv_show1(self,name,img):
plt.imshow(img)
plt.show()
cv2.imshow(name,img)
cv2.waitKey()
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=2
rawMatches = matcher.knnMatch(featuresA, featuresB, 2)#1对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时,返回None
return None
# 画出匹配点
def 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] = imageA
vis[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_01.png")
imageB = cv2.imread("right_01.png")
# 把图片拼接成全景图
stitcher = Stitcher()
(result, vis) = stitcher.stitch([imageA, imageB], showMatches=True)


# 显示所有图片
stitcher.cv_show("Image A", imageA)
stitcher.cv_show("Image B", imageB)
stitcher.cv_show("Keypoint Matches", vis)
stitcher.cv_show("Result", result)




边栏推荐
- SQLAchemy 常用操作
- Quelle valeur le pdnp peut - il apporter aux gestionnaires de produits? Vous savez tout?
- 三十之前一定要明白的职场潜规则
- Solidty智能合约开发-简易入门
- [stage life summary] I gave up the postgraduate entrance examination and participated in the work. I have successfully graduated and just received my graduation certificate yesterday
- C 语言基础
- NPDP产品经理国际认证报名有什么要求?
- Mongodb second call -- implementation of mongodb high availability cluster
- Generate random numbers (4-bit, 6-bit)
- ArrayList 扩容详解,扩容原理[通俗易懂]
猜你喜欢

JVM performance tuning and practical basic theory part II

Details of appium key knowledge

定了!2022海南二级造价工程师考试时间确定!报名通道已开启!

C#学习笔记(5)类和继承

Rearrangement of overloaded operators

Internet hospital system source code hospital applet source code smart hospital source code online consultation system source code

对于编程思想和能力有重大提升的书有哪些?

2022-2-15 learning the imitation Niuke project - post in Section 2

SQLAchemy 常用操作

【牛客网刷题系列 之 Verilog快速入门】~ 多功能数据处理器、求两个数的差值、使用generate…for语句简化代码、使用子模块实现三输入数的大小比较
随机推荐
[零基础学IoT Pwn] 复现Netgear WNAP320 RCE
643. Maximum average number of subarrays I
Cannot link redis when redis is enabled
互联网医院系统源码 医院小程序源码 智慧医院源码 在线问诊系统源码
Reorganize the trivial knowledge points at the end of the term
Word2vec yyds dry goods inventory
如何看待国企纷纷卸载微软Office改用金山WPS?
Research Report on development trend and competitive strategy of global 4-aminodiphenylamine industry
Solid basic basic grammar and definition function
[零基础学IoT Pwn] 复现Netgear WNAP320 RCE
Yyds dry goods inventory hcie security day13: firewall dual machine hot standby experiment (I) firewall direct deployment, uplink and downlink connection switches
Research Report on development trend and competitive strategy of global consumer glassware industry
关于软件测试的一些思考
JVM第一话 -- JVM入门详解以及运行时数据区分析
【牛客网刷题系列 之 Verilog快速入门】~ 使用函数实现数据大小端转换
C 语言基础
Research Report on the development trend and competitive strategy of the global traditional computer industry
官宣:Apache Doris 顺利毕业,成为 ASF 顶级项目!
The first technology podcast month will be broadcast soon
Digital transformation: data visualization enables sales management