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

news2024/11/19 4:46:59

目录

前言

一、两个函数

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)

输出:

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

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

相关文章

第二十三天|回溯算法| 39. 组合总和,40. 组合总和II,131. 分割回文串

目录 39. 组合总和 未剪枝 剪枝优化 40. 组合总和II 131. 分割回文串 回溯 回溯动态规划优化回文串判断 今天的题目自己都没啥思路&#xff0c;二刷的时候再理解一下。尤其是131. 39. 组合总和 本题和77.组合 &#xff0c;216.组合总和III的区别是&#xff1a;本题没有…

IDEA 输入英文字体变了的问题

**问题&#xff1a;**有时不知道按了什么快捷键导致在 IDEA 输入英文字体变了&#xff0c;如下所示&#xff0c;看起来特别不顺眼&#xff1a; 出现以上问题是因为在输入时切换了中文输入法&#xff0c;并且在提示文字时按了 Shift 空格 键&#xff0c;导致出现以上字体变化情…

H、Happy Number(2024牛客国庆集训派对day7)

题目链接&#xff1a; H-Happy Number_2024牛客国庆集训派对day7 (nowcoder.com) 题目描述&#xff1a; 翻译为中文&#xff1a; 数据范围&#xff1a; 输入样例&#xff1a; 680 输出样例&#xff1a; 326623 分析: 本来以为是dfs&#xff0c;但是看到数据范围1e9, 联想到是…

uniapp自定义导航,全端兼容

我们在用uniapp 开发应用的时候&#xff0c;有的页面需要自定义导航&#xff0c; 1.如果普通的直接使用uni 扩展柜组件的 uni-nav-bar 也基本够用&#xff0c; 2.如果稍微带点自定义的这个值无法支持的&#xff0c;特别在小程序端&#xff0c;胶囊是会压住右边的按钮的 自定…

多模态简单了解

多模态 1.文本编码2. ViT图像编码器2.1图像矩阵self-attention计算&#xff1a; 3.Transformer多模态3.1CLIP 图文交互3.2 对比学习训练3.3 flamingo 图文交互3.4 LLava 图文交互 1.文本编码 简介&#xff1a; 即通过embedding将字符向量化&#xff0c;进入模型即可。 2. ViT…

水下图像增强(论文复现)

本文所涉及所有资源均在 传知代码平台 可获取。 目录 概述 一、论文思路 二、模型介绍&#xff1a; 三、实现方法 四、复现过程(重要) 部署方式 概述 2021年11月&#xff0c;提出一种用于水下图像增强的U型Transformer模型&#xff0c;这是首次在水下图像增强任务中使用Transfo…

InnoDB 磁盘结构 - RedoLog

文章目录 RedoLog是什么刷盘机制崩溃恢复相关参数Redo Log 和 Undo Log 对比 https://dev.mysql.com/doc/refman/8.0/en/innodb-redo-log.html RedoLog是什么 RedoLog 是MySQL的一种日志文件&#xff0c;用于在崩溃恢复期间纠正由不完整事务写入的数据。在正常操作过程中&…

AtCoder Beginner Contest 374

C - Separated Lunch 题目&#xff1a; 思路&#xff1a; dfs枚举每个数是否选入a数组中&#xff0c;求和比较 代码&#xff1a; #include <bits/stdc.h>using namespace std;typedef long long LL;const int N25;int a[N]; bool st[N]; int mn0x3f3f3f3f; int sum; …

VMWare安装ubuntu22虚拟机

1.下载VMware虚拟机和ubuntu 下载地址&#xff1a; VMware Workstation Pro - Download (softonic.com) Download Ubuntu Desktop | Ubuntu 2.Ubuntu的安装 1.VMware创建虚拟机。 2.选择默认即可点击下一步。 3.找到刚才下载的ubuntu20.04。选择下面的稍后安装操作系统。 …

众智OA办公系统 Account/Login SQL注入漏洞复现

0x01 产品简介 众智OA办公系统是一种专门为企业和机构的日常办公工作提供服务的综合性软件平台。它凭借先进的技术和人性化的设计理念,实现了信息的快速传递和自动化处理,帮助企业和机构实现信息化、自动化、智能化和标准化的办公管理。 0x02 漏洞概述 众智OA办公系统 Acc…

【命令操作】linux上watch命令详解 _ 统信 _ 麒麟 _ 方德

原文链接&#xff1a;【命令操作】linux上basename和dirname使用详解 | 统信 | 麒麟 | 方德 Hello&#xff0c;大家好啊&#xff01;今天给大家带来一篇关于Linux上watch命令的详解文章。watch命令是Linux系统中非常有用的一个工具&#xff0c;它可以定期执行指定的命令并在终端…

解决vscode cpptools-srv.exe占用内存过大,导致系统卡死问题

cpptools-srv.exe是安装了c扩展出来的进程。最新版本c扩展cpptools-srv.exe疯狂的占用内存&#xff0c;笔者机器64G内存 都被占满了&#xff0c;&#xff0c;&#xff0c;&#xff0c;&#xff0c;&#xff0c; 网上也试了一些其他的办法&#xff0c;设置里面限制内存不过不好…

一入递归深似海,算法之美无止境

最近在刷leetcode hot100,在写二叉树中最大路径和的时候,看到了一个佬对递归的理解,深受启发,感觉自己对于递归的题又行了!!! 这里给大家分享一下(建立大家先去尝试一下这道题再来看 124. 二叉树中的最大路径和 二叉树中的 路径 被定义为一条节点序列&#xff0c;序列中每…

【优选算法】--- 位运算

位运算 一、常见的位运算总结&#xff08;重点&#xff01;&#xff09;1、关于位运算的符号2、&#xff08;判断&#xff09;给一个数字n&#xff0c;确定它的二进制表示中的第X位&#xff0c;是1还是0&#xff1f;3、&#xff08;修改&#xff09;如何把一个二进制的数字的第…

算法:双指针系列(一)

双指针系列 一、移动零&#xff08;一&#xff09;题目分析&#xff08;二&#xff09;代码展示二、复写零&#xff08;一&#xff09;题目分析&#xff08;二&#xff09;代码展示三、快乐数&#xff08;一&#xff09;题目分析&#xff08;二&#xff09;代码展示&#xff08…

OceanBase 4.x 部署实践:如何从单机扩展至分布式部署

OceanBase 4.x 版本支持2种部署模式&#xff1a;单机部署与分布式部署&#xff0c;同时支持从单机平滑扩展至分布式架构。这样&#xff0c;可以有效解决小型业务向大型业务转型时面临的扩展难题&#xff0c;降低了机器资源的成本。 以下将详述如何通过命令行&#xff0c;实现集…

Matlab数据预处理——最小二乘法消除多项式趋势项

关注公众号“电击小子程高兴的MATLAB小屋”获取专属优惠 概要&#xff1a; 最小二乘法是一种常用的统计方法&#xff0c;用于通过拟合数据来消除多项式趋势项。以下是关于如何使用最小二乘法消除多项式趋势项的步骤和概念&#xff1a; 概念&#xff1a; 多项式趋势项&#…

动态规划一>解码方法

1.题目&#xff1a; . - 力扣&#xff08;LeetCode&#xff09; 2.解析&#xff1a; 版本一&#xff1a;图解&#xff1a; 注意&#xff1a; 前导0不能解码&#xff1a;06, 或者两个数字字符&#xff1a;其中一个解码失败&#xff0c;整个也解码失败 /**1.创建dp表2.初始化3.填…

GIS小技巧——一文教会你安装BlenderGIS插件

Blender是一款不错的三维渲染软件&#xff0c;用它来做三维地形图&#xff0c;能够更好地把地形纹理显现出来。不过&#xff0c;原始的Blender是没有地图底图的&#xff0c;要结合三维影像制作三维地形图&#xff0c;需要结合其他的软件&#xff0c;比如ArcGIS Pro&#xff0c;…

基于RSSI原理的蓝牙定位程序(matlab代码,3维空间、基站数量>3即可,可自适应)

目录 商品描述 商品描述 这款基于接收信号强度指示&#xff08;RSSI&#xff09;原理的蓝牙定位程序&#xff0c;专为需要高效、可靠定位解决方案的开发者和研究人员设计。无论是在室内环境还是复杂的三维空间&#xff0c;该程序都能通过N个蓝牙锚点&#xff0c;实现对未知点的…