首页 > 其他分享 >机器学习:opencv--图像拼接

机器学习:opencv--图像拼接

时间:2024-10-09 21:21:46浏览次数:10  
标签:kps 匹配 -- cv2 opencv 描述符 拼接 图像 特征

目录

前言

一、两个函数

1.显示图像

2.计算图片特征与描述符

二、代码实例

1.准备图像

2.特征检测

3.特征匹配

4.图像变换

5.图像融合


前言

图像拼接是一种将多张图像合成一幅大图的技术,常用于全景图生成、图像拼接和图像合成等应用场景。

 

一、两个函数

1.显示图像

def cv_show(name, img):
    cv2.imshow(name, img)
    cv2.waitKey(0)

 

2.计算图片特征与描述符

  1. 将输入图像转换成灰度图
  2. 创建sift对象
  3. 对该灰度图进行特征检测并计算描述符
  4. 将每一个关键点的坐标装入数组
  5. 返回关键点,关键点坐标数组和描述符
def detectAndDescribe(image):
    gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
    sift = cv2.SIFT_create()
    # 检测SIFT特征点,并计算描述符,第二个参数为掩膜
    (kps, des) = sift.detectAndCompute(gray, None)
    # 将结果转換成NumPy数组
    kps_float = np.float32([kp.pt for kp in kps])
    # kp.pt 包含两个值,分别是关键点在图像中的 x 和 y 坐标。这些坐标通常是浮点数,可以精确地描述关键点在图像中的位置。
    return (kps, kps_float, des)

 

二、代码实例

1.准备图像

  • 选择需要拼接的图像,确保它们之间有一定的重叠区域。
import cv2
import numpy as np
import sys

"""读取拼接图片"""
imageA = cv2.imread('1.jpg')
cv_show('imageA', imageA)
imageB = cv2.imread('2.jpg')
cv_show('imageB', imageB)

 输出:

 

2.特征检测

  • 使用特征检测算法(如 SIFT、ORB 或 AKAZE)找到每张图像中的关键特征点。
"""计算图片特征点及描述符"""
(kpsA, kps_floatA, desA) = detectAndDescribe(imageA)
(kpsB, kps_floatB, desB) = detectAndDescribe(imageB)

 

3.特征匹配

  • 通过描述子匹配算法(如 BFMatcher 或 FLANN)将不同图像中的特征点进行匹配。
"""建立暴力匹配器BFMatcher,在匹配大型训练集合是使用FlannBasedMatcher速度更快"""
matcher = cv2.BFMatcher()
# knnMatch(queryDescriptors,trainDescriptors,k,mask=None, compactResult=None)
# 使用KNN检测来自A、B图的SIFT特征匹配对,参数说明:
# queryDescriptors:查询图像A的描述符
# trainDescriptors:目标图像B的描述符
# k:最佳匹配的描述符个数。一般K=2.
# 返回的数据结构描述:
# distance:匹配的特征点描述符的欧式距离,数值越小也就说明个特征点越相近。
# queryIdx:查询图像的特征点描述符的下标(第几个特征点描述符),同时也是描述符对应特征点的下标。
# trainIdx:目标图像的特征点描述符下标,同时也是描述符对应特征点的下标。
# 选查询图像中的一个关键点 选目标图像中的两个点 进行判断
rawMatches = matcher.knnMatch(desB, desA, 2)
good = []  # 例如,[[m1, m2], [m3, m4], ...] 的格式,其中 m1, m2 是对应于同一关键点的两个匹配。
matches = []
for m in rawMatches:
    # 当最近距离跟次近距离的比值小于0.65值时,保留此匹配对
    if len(m) == 2 and m[0].distance < 0.65 * m[1].distance:
        good.append(m)
        # 存储两个点在featuresA,featuresB中的索引值
        matches.append((m[0].trainIdx, m[0].queryIdx))
print(len(good))
print(matches)

# 绘制k近邻匹配结果
# kp2 是要取两个关键点的图像
vis = cv2.drawMatchesKnn(imageB, kpsB, imageA, kpsA, good, None, flags=cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS)
cv_show('Keypoint Matches', vis)

输出:

 

4.图像变换

  • 根据计算出的变换矩阵,将图像变换到同一平面上。
"""透视变换"""
if len(matches) > 4:  # 当筛选后的匹配对大于4时,计算视角变换矩阵。
    # 获取匹配对的点坐标
    ptsA = np.float32([kps_floatA[i] for (i, _) in matches])  # matches是通过阈值筛选之后的特征点对象
    ptsB = np.float32([kps_floatB[i] for (_, i) in matches])  # kps_floatA是图片A中的全部特征点坐标
    # 计箅透视变換矩阵
    # findHomography(srcPoints, dstPoints, method=None, ransacReprojThreshold=None)
    # 计算视角变换矩阵,透视变换雨数,与cv2.getPerspectiveTransform()的区别在与可多个数据点变换
    # 参数srcPoints:选一个关键点的图
    # 参数dstPoints:选两个关键点的图
    # 參数method:计算变换矩降的方法
    # 0 - 使用所有的点,最小二乘法
    # RANSAC - 基于随机样本一致性,https://zhuanlan.zhihu.com/p/402727549
    # LMEDS - 最小中值
    # RHO - 转于浙近样本一致性
    # ransacReprojThreshold:最大允许币投影错误阀值。该参数只有在method参数为RANSAC与RHO的时启用,默认为3
    # 返回值中:h为变换矩阵、mask是掩模标志,指示哪些点对是内点、哪些是外点。 内点;指那些与估计的模型非常接近的数据点,通常是正确匹魔或真实数据。
    (H, mask) = cv2.findHomography(ptsB, ptsA, cv2.RANSAC, 10)
else:
    print('图片未找到4个以上匹配点')
    sys.exit()

输出:

 

5.图像融合

  • 将变换后的图像合成在一起,可以使用加权平均、渐变等方式来平滑拼接缝隙。
result = cv2.warpPerspective(imageB, H, (imageB.shape[1] + imageA.shape[1], imageB.shape[0]))
cv_show("resultB", result)
# 将图片A传入result图片最左璇
result[0:imageA.shape[0], 0:imageA.shape[1]] = imageA
cv_show("result", result)

输出:

标签:kps,匹配,--,cv2,opencv,描述符,拼接,图像,特征
From: https://blog.csdn.net/weixin_65047977/article/details/142748674

相关文章

  • 杂项之 - 康托展开
    在洛谷上闲逛时无意中看到了这个东东,顺便学了一下Part1康托展开是什么康拓展开是一种将排列映射为一个自然数的双射康托展开可以用来求一个\(1\simn\)的任意排列的排名。Part2康托展开的公式对于一个排列\(a_1\dotsa_n\)把\(1\simn\)的所有排列按字典序排序,这个......
  • 【NVIDIA NIM 黑客松训练营】使用NVIDIA AI Workbench 创建一个在线代码生成器
    随着人工智能技术的不断进步,越来越多的工具和服务开始集成AI功能来提升用户体验。本教程将指导你如何使用PythonFlask框架结合NVIDIA提供的NIM服务,创建一个简单的在线代码生成器。用户可以通过一个直观的Web界面输入请求,系统将返回对应的Python代码。项目背景对于那些正......
  • 深度学习:循环神经网络RNN
    目录一、神经网络的历程1.传统神经网络存在的问题2.提出一种新的神经网络二、RNN基本结构1.RNN基本结构2.RNN的独特结构3.RNN的局限性一、神经网络的历程1.传统神经网络存在的问题无法训练出具有顺序的数据。模型搭建时没有考虑数据上下之间的关系。因为传统神经网......
  • 外包干了5天,技术明显退步。。。。。
    先说一下自己的情况,本科生,19年通过校招进入南京某软件公司,干了接近2年的功能测试,今年年初,感觉自己不能够在这样下去了,长时间呆在一个舒适的环境会让一个人堕落!而我已经在一个企业干了2年的功能测试,已经让我变得不思进取,谈了2年的女朋友也因为我的心态和工资和我分手了。于是,我......
  • 【Redis入门到精通十】Redis哨兵
    目录哨兵(Sentinel)1.哨兵的由来2.哨兵的基本概念3.基于docker安装配置Redis哨兵4.哨兵选取主节点的原理1.主观下线2.客观下线3.选举出哨兵的leader4.leader挑选出合适的slave成为新的master哨兵(Sentinel)    RedisSentinel是Redis的高可用实现方案,在......
  • 【MySQL】库的操作
    文章目录一、查看数据库(显示所有的数据库)二、创建数据库三、查看创建数据库的SQL语句四、修改数据库五、删除数据库一、查看数据库(显示所有的数据库)语法:showdatabases;解释:show显示databases复数形式;每条语句的结尾二、创建数据库语法:CREATE{DATABASE|......
  • JS刷力扣-链表【持续跟新】
    力扣的链表归类2.两数相加【链表+递归】前置知识:1.链表是一种通过指针串联在一起的线性结构,每一个节点由两部分组成,一个是数据域一个是指针域(存放指向下一个节点的指针),最后一个节点的指针域指向null(空指针的意思)。2.链表的入口节点称为链表的头结点也就是head。leet......
  • HCIA 无线配置实验
    实验拓扑实验需求1、用户划分vlan30,网段为192.168.30.0/242、AP和AC划分vlan20,网段为192.168.20.0/243、有线网段使用vlan10,网段为192.168.10.0/24配置思路及验证结果核心交换机<SW1>system-view进入系统视图[SW1]......
  • 蓝禾,汤臣倍健,三七互娱,得物,顺丰,快手,游卡,oppo,康冠科技,途游游戏,埃科光电25秋招内推
    蓝禾,汤臣倍健,三七互娱,得物,顺丰,快手,游卡,oppo,康冠科技,途游游戏,埃科光电25秋招内推①蓝禾【岗位】国内/国际电商运营,设计,研发,营销,职能,工作地:深圳【校园大使推荐码】71T3HES【一键内推】https://sourl.cn/68rjxY②得物【八大职类】技术、供应链、产品、运营、设计、职能、商......
  • 外包干了3个月,技术退步明显。。。。。
    先说一下自己的情况,本科生,19年通过校招进入广州某软件公司,干了接近4年的功能测试,今年年初,感觉自己不能够在这样下去了,长时间呆在一个舒适的环境会让一个人堕落!而我已经在一个企业干了四年的功能测试,已经让我变得不思进取,谈了2年的女朋友也因为我的心态和工资和我分手了。于是,......