python数字图像处理基础(九)——特征匹配

目录

      • 蛮力匹配(ORB匹配)
      • RANSAC算法
      • 全景图像拼接

蛮力匹配(ORB匹配)

Brute-Force匹配非常简单,首先在第一幅图像中选取一个关键点然后依次与第二幅图像的每个关键点进行(描述符)距离测试,最后返回距离最近的关键点.

对于BF匹配器,首先我们必须使用**cv2.BFMatcher()**创建 BFMatcher 对象。它需要两个可选的参数:

  • normType:它指定要使用的距离测量,默认情况下,它是cv2.NORM_L2,它适用于SIFT,SURF等(cv2.NORM_L1也在那里)。对于基于二进制字符串的描述符,如ORB,BRIEF,BRISK等,应使用cv2.NORM_HAMMING,使用汉明距离作为度量,如果ORB使用WTA_K == 3or4,则应使用cv2.NORM_HAMMING2
  • crossCheck:默认值为False。如果设置为True,匹配条件就会更加严格,只有到A中的第i个特征点与B中的第j个特征点距离最近,并且B中的第j个特征点到A中的第i个特征点也是最近时才会返回最佳匹配,即这两个特征点要互相匹配才行

两个重要的方法是BFMatcher.match()BFMatcher.knnMatch(), 第一个返回最佳匹配, 第二种方法返回k个最佳匹配,其中k由用户指定.

使用cv2.drawMatches()来绘制匹配的点,它会将两幅图像先水平排列,然后在最佳匹配的点之间绘制直线。如果前面使用的BFMatcher.knnMatch(),现在可以使用函数cv2.drawMatchsKnn为每个关键点和它的个最佳匹配点绘制匹配线。如果要选择性绘制就要给函数传入一个掩模.

一对一匹配 BFMatcher.match()

import numpy as np
import cv2
from matplotlib import pyplot as pltimg1 = cv2.imread('./image/girl1.jpg')
img2 = cv2.imread('./image/girl2.jpg')sift = cv2.SIFT_create()# kp代表特征点 des每个点对应特征向量
kp1, des1 = sift.detectAndCompute(img1, None)
kp2, des2 = sift.detectAndCompute(img2, None)bf = cv2.BFMatcher(crossCheck=True)  # 可选对象crossCheck# 1对1匹配
matches = bf.match(des1, des2)
matches = sorted(matches, key=lambda x: x.distance)  # 排序,通过距离来度量img3 = cv2.drawMatches(img1, kp1, img2, kp2, matches[:30], None, flags=2)  # matches[:10] 距离前十的给显示出来,即显示十条匹配线cv2.imshow('img', img3)
cv2.waitKey(0)
cv2.destroyAllWindows()

k对最佳匹配 BFMatcher.knnMatch()

import numpy as np
import cv2
from matplotlib import pyplot as pltimg1 = cv2.imread('./image/girl1.jpg')
img2 = cv2.imread('./image/girl2.jpg')sift = cv2.SIFT_create()# kp代表特征点 des每个点对应特征向量
kp1, des1 = sift.detectAndCompute(img1, None)
kp2, des2 = sift.detectAndCompute(img2, None)# k对最佳匹配
bf = cv2.BFMatcher()
matches = bf.knnMatch(des1, des2, k=2)good = []
for m, n in matches:# 过滤方法if m.distance < 0.75 * n.distance:good.append([m])img3 = cv2.drawMatchesKnn(img1, kp1, img2, kp2, good, None, flags=2)cv2.imshow('img', img3)
cv2.waitKey(0)
cv2.destroyAllWindows()

RANSAC算法

蛮力匹配是一种简单而直观的匹配方法,适用于小规模的特征点匹配。通过比较所有可能的特征点对,找到最佳匹配。而RANSAC算法则通过随机采样和一致性检验,从包含噪声的数据中估计出正确的模型参数,对于一些存在噪声和异常值的情况,RANSAC能够更稳健地估计模型。

利用RANSAC算法计算变换矩阵

RANSAC是"RANdom SAmple Consensus"(随机一致采样)的缩写。该方法是用来找到正确模型来拟合带有噪声数据的迭代方法。给定一个模型,例如点集之间的单应性矩阵。基本的思想是:数据中包含正确的点和噪声点,合理的模型应该能够在描述正确数据点的同时摒弃噪声点。

此外还有ORB匹配、SIFT的特征匹配、基于FLANN的匹配器的匹配,等等

全景图像拼接

全景图像拼接是将多张图像拼接成一张全景图的任务。在这个过程中,特征点匹配和单应性矩阵估计是关键的步骤。你提到的使用SIFT找到特征点,并通过单应性矩阵将图像进行变换,是一种常见的方法。这样可以在不同视角或位置拍摄的图像中找到对应的特征点,从而实现拼接。

通过SIFT找特征点

关于单应性矩阵(H矩阵):

利用两个图像中至少四个特征点能够求解一个单应性矩阵(homography matrix),然后用这个单应性矩阵能够将图像1中的某个坐标变换到图像2中对应的位置。然而,矩阵的推导是来自于相机在不同位姿拍摄同一个三维平面,所以使用opencv计算单应性矩阵的时候前提是两个图像对应区域必须是同一平面。

当进行全景图像拼接时,常常需要使用RANSAC算法估计单应性矩阵。下面是一个简单的示例代码,其中包括特征点匹配、RANSAC算法和全景图像拼接的步骤。

import cv2
import numpy as npdef find_keypoints_and_descriptors(image):# 使用SIFT算法找到图像的关键点和描述符sift = cv2.SIFT_create()kp, des = sift.detectAndCompute(image, None)return kp, desdef match_keypoints(des1, des2):# 使用BFMatcher进行特征点匹配bf = cv2.BFMatcher()matches = bf.knnMatch(des1, des2, k=2)# 使用比值测试排除不好的匹配good = []for m, n in matches:if m.distance < 0.75 * n.distance:good.append(m)return gooddef ransac_homography(matches, kp1, kp2, reproj_thresh=4.0):# 将匹配的关键点转换为numpy数组src_pts = np.float32([kp1[m.queryIdx].pt for m in matches]).reshape(-1, 1, 2)dst_pts = np.float32([kp2[m.trainIdx].pt for m in matches]).reshape(-1, 1, 2)# 使用RANSAC算法估计单应性矩阵H, mask = cv2.findHomography(src_pts, dst_pts, cv2.RANSAC, reproj_thresh)return Hdef stitch_images(image1, image2, H):# 将图像1进行透视变换,将其叠加到图像2上rows1, cols1 = image1.shape[:2]rows2, cols2 = image2.shape[:2]warp_img1 = cv2.warpPerspective(image1, H, (cols1 + cols2, rows2))warp_img1[:rows2, :cols2] = image2return warp_img1if __name__ == "__main__":# 读取两张图像img1 = cv2.imread('image1.jpg')img2 = cv2.imread('image2.jpg')# 找到关键点和描述符kp1, des1 = find_keypoints_and_descriptors(img1)kp2, des2 = find_keypoints_and_descriptors(img2)# 进行特征点匹配matches = match_keypoints(des1, des2)# 使用RANSAC估计单应性矩阵H = ransac_homography(matches, kp1, kp2)# 进行全景图像拼接result = stitch_images(img1, img2, H)# 显示拼接结果cv2.imshow('Panorama', result)cv2.waitKey(0)cv2.destroyAllWindows()

为了达到更好的拼接效果,可能需要使用更复杂的图像配准和融合技术。


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

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

相关文章

前端-基础 表格标签 总结

目录 表格的相关标签 &#xff1a; 表格的相关属性 合并单元格 &#xff1a; 表格的相关标签 &#xff1a; 表格标签 - <table> 行标签 - <tr> 单元格标签 - <td> 表头单元格标签 - <th> 表格结构标签 表头区域标签 - < thead >…

MySQL 查询数据

今天介绍一下 MySQL 数据库使用 SELECT 语句来查询数据。 语法 首先&#xff0c;介绍一下语法。以下为在 MySQL 数据库中查询数据通用的 SELECT 语法&#xff1a; SELECT column1, column2, ... FROM table_name [WHERE condition] [ORDER BY column_name [ASC | DESC]] [LI…

【算法】递归

递归 递归初始递归&#xff1a;数列求和递归的应用&#xff1a;任意进制转换递归深度限制递归可视化&#xff1a;分形树递归可视化&#xff1a;谢尔宾斯基Sierpinski三角形递归的应用&#xff1a;汉诺塔递归的应用&#xff1a;探索迷宫 分治策略和递归优化问题兑换最少个数硬币…

Vue 3 hooks的基本使用及疑问

前言 vue3也用过一段时间了&#xff0c;hooks听说过&#xff0c;但是一直没有用过。公司的前端项目里也没有相应的应用&#xff0c;因此打算系统的学习一下。 hooks与普通函数的区别 以实现一个加法功能为例。 普通函数未抽离 <template><div class"box&quo…

Java开发的审批流系统,前端使用vue,支持常态化工作审批流程

一、项目形式 springbootvueactiviti集成了activiti在线编辑器&#xff0c;快速开发平台&#xff0c;可插拔工作流服务。 二、项目介绍 本项目拥有用户管理&#xff0c;部门管理&#xff0c;代码生成&#xff0c;系统监管&#xff0c;报表&#xff0c;大屏展示&#xff0c;业…

贝塞尔曲线(Bezier Curve)原理、公式推导及matlab代码实现

目录 参考链接 定义 直观理解 公式推导 一次贝塞尔曲线&#xff08;线性公式&#xff09; 二次贝塞尔曲线&#xff08;二次方公式&#xff09; 三次贝塞尔曲线&#xff08;三次方公式&#xff09; n次贝塞尔曲线&#xff08;一般参数公式&#xff09; 代码实现 参考链接…

基于局部信息提取的人脸标志检测算法matlab仿真

目录 1.算法运行效果图预览 2.算法运行软件版本 3.部分核心程序 4.算法理论概述 4.1 人脸检测 4.2 局部区域选择 4.3 特征提取 5.算法完整程序工程 1.算法运行效果图预览 2.算法运行软件版本 matlab2022a 3.部分核心程序 .........................................…

一篇文章带你彻底了解flex布局

哈喽&#xff0c;大家好呀&#xff0c;我是前端理想哥&#xff0c;今天我们来聊聊 flex 布局。 好&#xff0c;主角登场。 CSS 弹性盒子模型( Flexible Box 或者 Flexbox ) 先来看看它的定义&#xff1a;弹性布局是指通过调整其内元素的宽高&#xff0c;从而在任何显示设备上…

【02】mapbox js api加载arcgis切片服务

需求&#xff1a; 第三方的mapbox js api加载arcgis切片服务&#xff0c;同时叠加在mapbox自带底图上 效果图&#xff1a; 形如这种地址去加载&#xff1a; http://zjq2022.gis.com:8080/demo/loadmapbox.html arcgis切片服务参考链接思路&#xff1a;【01】mapbox js api加…

基于gd32f103移植freemodbus master 主栈

1.移植freemodbus master需要先移植RT-Thread操作系统 GD32F103C8T6移植 RTT Nano 教程-CSDN博客 2.移植freemodbus master协议栈 在移植了RTT以后,我们需要移植就只有串口相关的函数 移植freemodbus master协议栈具体步骤 下载移植freemodbus master协议栈 源码添加协议栈…

2024 1.13~1.19 周报

一、本周计划 确定论文题目&#xff0c;重新思考能加的点子&#xff0c;重点在网络架构部分。主要了解了注意力模块如SE、CBAM、CA&#xff0c;在模型中插入注意力模块。读论文。 二、完成情况 2.1 论文题目 基于注意力的Unet盐体全波形反演 想法来源&#xff1a;使用的是二维…

全新AI助手结合GPT4、Dalle3和Midjourney图文创作

MidTool AI助手&#xff08;迷图网(MidTool)-免费ChatGPT中文版和Midjourney的AI绘画聊天软件&#xff09;是一个集成了多种人工智能技术的平台&#xff0c;旨在为用户提供全面的智能服务体验。它融合了GPT-4、DALLE 3和Midjourney等先进的AI工具&#xff0c;每个工具都有其独特…

【LeetCode热题100】【子串】滑动窗口最大值

题目 给你一个整数数组 nums&#xff0c;有一个大小为 k 的滑动窗口从数组的最左侧移动到数组的最右侧。你只可以看到在滑动窗口内的 k 个数字。滑动窗口每次只向右移动一位。 返回 滑动窗口中的最大值 。 示例 1&#xff1a; 输入&#xff1a;nums [1,3,-1,-3,5,3,6,7], …

【方法】如何合并多个PDF文件?

多个PDF文件&#xff0c;想合并成一个文件&#xff0c;要怎么操作呢&#xff1f; 如果PDF文件的数量少&#xff0c;并且页数也不多&#xff0c;可以试试将内容复制黏贴到Word文档&#xff0c;再转为PDF格式&#xff1b;如果文件数量多&#xff0c;页数也多&#xff0c;就不太合…

原型设计 Axure RP 9

Axure RP 9是一款专业的原型设计和协作工具&#xff0c;让用户快速创建高保真度的交互原型&#xff0c;模拟真实的用户界面和交互体验。该软件界面布局合理&#xff0c;易于使用&#xff0c;提供丰富的交互功能和效果&#xff0c;如动态面板、变量、条件逻辑、动画等。同时支持…

室内机器人区域覆盖算法仿真测试平台设计与实现(预告)

前一篇&#xff1a; 户外机器人区域覆盖算法仿真测试平台设计与实现&#xff08;预告&#xff09; 基本完全是人工智能生成的内容。 之前此课题只是课程中的一个项目案例。 ROS1云课→32愉快大扫除 但是可以感觉到过于宽泛&#xff0c;没有任何具体实践&#xff0c;比如使用…

MCM备赛笔记——熵权法

Key Concept 熵权法是一种基于信息熵概念的权重确定方法&#xff0c;用于多指标决策分析中。信息熵是度量信息量的不确定性或混乱程度的指标&#xff0c;在熵权法中&#xff0c;它用来反映某个指标在评价过程中的分散程度&#xff0c;进而确定该指标的权重。指标的分散程度越高…

【办公自动化】python实现图片上传到阿里云OSS

阿里云OSS简介 阿里云对象存储服务(Object Storage Service,简称OSS)是一种高可靠、高可用、安全稳定的云存储服务。它提供了海量、安全、低成本、高可靠的存储服务&#xff0c;适用于各种类型的文件存储需求。 阿里云OSS使用方法 注册阿里云账号并登录&#xff1b; 创建OSS…

【办公类-21-01】20240117育婴员操作题word合并1.0

背景需求&#xff1a; 最近学校组织老师们学习“育婴员”高级&#xff0c;每周学习2题操作&#xff0c;所以我是把每个学习内容单独做在一个word文件里 上周8套保健操作学完了&#xff0c;需要整理&#xff0c;并将8份Word文件合并 第一步&#xff1a;doc装docx 合并时程序报…

leedcode刷题day2

题目&#xff1a; 根据这道题我的思路是用python首先将第一个值赋给a&#xff0c;然后将下一个值赋值给b在这里写一个循环计算下一个值是否等于a&#xff0c;不等于就进入数组当等于a的时候输出数组长度&#xff0c;然后比较数组长度输出最长长度对应的元素不过显然这很慢。 然…