【OpenCV-Python】教程:4-9 特征匹配 match

news2024/11/18 23:22:31

OpenCV Python 特征匹配

【目标】

  • 特征匹配
  • Brute-Force Matcher 和 FLANN Matcher

【理论】

Brute-Force Matcher字面意思是蛮力匹配器,所以它的过程也很简单,从一个集合里取出一个特征描述子,然后与第二个集合里的特征逐个的进行匹配比较。返回最近的一个。

对于BF matcher,首先我们必须使用cv.BFMatcher()创建BFMatcher对象。它接受两个可选参数。第一个是normType。它指定了要使用的距离测量。默认为cv.NORM_L2。对于 SIFT 和 SURF 来说很好。对于基于二进制字符串的描述符,如ORB, BRIEF, BRISK等等,应该使用NORM_HAMMING,它使用汉明距离作为度量。如果ORB使用WTA_K == 3或4,

第二个参数是布尔变量,crossCheck默认为false。如果为真,Matcher只返回值为(i,j)的匹配,这样集合A中的第i个描述符与集合B中的第j个描述符是最佳匹配,反之亦然。也就是说,两个集合中的两个特征应该相互匹配。该方法可较好地替代D.Lowe在SIFT论文中提出的比值检验方法。

创建后,有两个重要的方法是BFMatcher.match()和BFMatcher.knnMatch()。第一个返回最佳匹配。第二个方法返回k个用户指定的最佳匹配项。当我们需要做额外的工作时,它可能会有用。

就像我们使用 cv2.drawKeypoints 绘制关键点一样,cv2.drawMatches 绘制匹配点。它将两张图像水平堆叠,并从第一张图像连接到第二张图像,以显示最佳匹配。

【代码】

  • ORB 特征及 bf matcher

在这里插入图片描述

# ORB 特征及 bf matcher
import numpy as np 
import cv2 
import matplotlib.pyplot as plt

img1 = cv2.imread("assets/box.png", 0)
img2 = cv2.imread("assets/box_in_scene.png", 0)

# 创建 ORB 对象
orb = cv2.ORB_create()

# 检测关键点并计算特征
kp1, des1 = orb.detectAndCompute(img1, None)
kp2, des2 = orb.detectAndCompute(img2, None)

# 创建匹配器
bf = cv2.BFMatcher(cv2.NORM_HAMMING, crossCheck=True)

# 匹配
matchs = bf.match(des1, des2)

# 排序
matchs = sorted(matchs, key=lambda x: x.distance)

# 绘制匹配结果
img_res = cv2.drawMatches(img1, kp1, img2, kp2, matchs[:15], None, flags=cv2.DrawMatchesFlags_NOT_DRAW_SINGLE_POINTS)

cv2.imshow("orb-bfmatches", img_res)
cv2.waitKey(0)
cv2.destroyAllWindows()
  • SIFT 和 bf knn matcher

在这里插入图片描述

# SIFT 和 bf knn matcher
import numpy as np 
import cv2

img1 = cv2.imread("assets/box.png", 0)
img2 = cv2.imread("assets/box_in_scene.png", 0)

sift = cv2.SIFT_create()

kp1, des1 = sift.detectAndCompute(img1, None)
kp2, des2 = sift.detectAndCompute(img2, None)

bf = cv2.BFMatcher()
matches = bf.knnMatch(des1, des2, k=2)

good = []
for m, n in matches:
    if m.distance < 0.5*n.distance:
        good.append([m])

img_res = cv2.drawMatchesKnn(img1, kp1, img2, kp2, good,
                            None, flags=cv2.DrawMatchesFlags_NOT_DRAW_SINGLE_POINTS)

cv2.imshow("sift-bfknnmatches", img_res)
cv2.waitKey(0)
cv2.destroyAllWindows()
  • sift FLANN matcher

# sift FLANN matcher
import numpy as np 
import cv2 

img1 = cv2.imread("assets/box.png", 0)
img2 = cv2.imread("assets/box_in_scene.png", 0)

# 初始化创建
sift = cv2.SIFT_create()

# 关键点检测和特征计算
kp1, des1 = sift.detectAndCompute(img1, None)
kp2, des2 = sift.detectAndCompute(img2, None)

# FLANN parameters
FLANN_INDEX_KDTREE = 1
index_params = dict(algorithm=FLANN_INDEX_KDTREE, trees=5)
search_params = dict(checks=50)   # or pass empty dictionary
flann = cv2.FlannBasedMatcher(index_params, search_params)
matches = flann.knnMatch(des1, des2, k=2)

# Need to draw only good matches, so create a mask
matchesMask = [[0, 0] for i in range(len(matches))]
# ratio test as per Lowe's paper
for i, (m, n) in enumerate(matches):
    if m.distance < 0.5*n.distance:
        matchesMask[i] = [1, 0]
draw_params = dict(matchColor=(0, 255, 0),
                    singlePointColor=(255, 0, 0),
                    matchesMask=matchesMask,
                    flags=cv2.DrawMatchesFlags_DEFAULT)
img3 = cv2.drawMatchesKnn(img1, kp1, img2, kp2, matches, None, **draw_params)

cv2.imshow("sift-flannmatches", img3)
cv2.waitKey(0)
cv2.destroyAllWindows()

【接口】

  • BFMatcher
cv2.BFMatcher(	[, normType[, crossCheck]]	) ->	<BFMatcher object>
  • normType: NORM_L1, NORM_L2, NORM_HAMMING, NORM_HAMMING2; L1和L2是SIFT和SURF描述符使用,ORB,BRISK和BRIEF使用,NORM_HAMMING2 是 ORB 中 WTA_K==3或4时使用。
  • crossCheck: 如果为 false, 默认的 BFMatcher 返回 k 最近邻的匹配描述符,如果为真,并且 k=1时,返回的匹配对
cv2.drawMatches(	img1, keypoints1, img2, keypoints2, matches1to2, outImg[, matchColor[, singlePointColor[, matchesMask[, flags]]]]	) ->	outImg
cv2.drawMatches(	img1, keypoints1, img2, keypoints2, matches1to2, outImg, matchesThickness[, matchColor[, singlePointColor[, matchesMask[, flags]]]]	) ->	outImg
cv2.drawMatchesKnn(	img1, keypoints1, img2, keypoints2, matches1to2, outImg[, matchColor[, singlePointColor[, matchesMask[, flags]]]]	) ->	outImg

绘制两幅图像中的匹配的点。

  • img1: 第一幅图像
  • keypoints1: 第一幅图像中的关键点
  • img2: 第二幅图像
  • keypoints2: 第二幅图像中的关键点
  • matches1to2: 第一幅图像和第二幅图像中匹配的描述符
  • outImg: 绘制结果的图像
  • matchColor: 绘制匹配点的颜色,如果 matchColor==Scalar::all(-1) 则颜色随机生成
  • singlePointColor: 绘制单个匹配点的颜色,如果 singlePointColor==Scalar::all(-1) 则颜色随机生成
  • matchesMask: 如果为空,绘制所有;
  • flags: 绘制特征的标识符 DrawMatchesFlags.
  • DrawMatchesFlags

在这里插入图片描述

【参考】

  1. OpenCV: Feature Matching

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

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

相关文章

传统MES架构的智能化改进---python在Aprol上的实践

一、开题依据 MES是属于生产车间级的管理信息系统。作为生产与计划之间的信息“集线器”&#xff0c;MES 主要包括以下功能模块&#xff1a;工序详细调度、资源分配和状态管理、生产单元分配、过程管理、人力资源管理、维护管理、质量管理、文档控制、产品跟踪和产品清单管理、…

Solidworks导出为URDF用于MoveIT总结(带prismatic)

环境 Solidwoks2018 SP0 / Solidwoks2021 SP5&#xff1b;Ubuntu20.04&#xff1b;ROS1 Noetic; Solidwoks2018 SP0对于平移副有问题&#xff0c;显示不出来&#xff0c;Solidwoks2021 SP5没有问题。 官网有段话&#xff1a; There is a known STL export bug with SolidWork…

Jdk Tomcat 安装教程 — 2022.12.11

文章目录一、安装jdk教程二、tomcat 安装三、修改Tomcat端口号安装Tomcat之前要确保安装jdk一、安装jdk教程 安装vim命令包&#xff0c;此操作如果执行不了&#xff0c;需要使用root权限执行 执行如下命令&#xff1a; yum install -y vim-enhanced2. 下载jdk安装包&#xff…

3D打印切片软件Cura入门

安装好之后&#xff0c;添加一台打印机&#xff0c;参数可以随便设置。 Cura安装包&#xff1a; 链接&#xff1a;https://pan.baidu.com/s/1T1MBcZYBCVfhtFKDBjypmQ?pwd2022 提取码&#xff1a;2022 基本操作 按住鼠标右键不放&#xff1a;旋转 按住滚轮不放&#xff1…

制作USB启动盘(U盘安装ubuntu20.04)

文章目录制作USB启动盘&#xff08;U盘安装ubuntu20.04&#xff09;制作USB启动盘的工具ubuntu20.04系统安装u盘制作进入bios制作USB启动盘&#xff08;U盘安装ubuntu20.04&#xff09; 制作USB启动盘的工具 制作USB启动盘的工具有rufus&#xff0c;UNetbootin&#xff0c;Un…

汇编语言—第1章 各类存储芯片及内存空间

1、各类存储器芯片 一台PC机中&#xff0c;装有多个存储类芯片&#xff0c;这些存储器芯片从物理连接上来看是独立的、不同的器件。 &#xff08;1&#xff09;随机存储器 用于存放供CPU使用的绝大部分程序和数据 &#xff08;2&#xff09;装有BIOS&#xff08;Basic Input/Ou…

AI遮天传 DL-反馈神经网络RNN

本文会先介绍动态系统的概念&#xff0c;然后介绍两种简单的反馈神经网络&#xff0c;然后再介绍两种门控神经网络(LSTM, GRU)&#xff0c;最后是关于反馈神经网络的应用(本次以语音识别为例)。 RNN: Recurrent neural network&#xff0c;一般叫它“反馈神经网络”或者“循环神…

1565_AURIX_TC275_开关电源模式相关寄存器

全部学习汇总&#xff1a; GreyZhang/g_TC275: happy hacking for TC275! (github.com) 这个寄存器可以设置开关电源的开关频率&#xff0c;之前在文档中看到过这个默认的数值是1.5M的频率&#xff0c;现在看来应该是这个1.56M的一个近似了。准确的数值不是1.5M而是1.56M。 1. …

任务四:标准化组织概览

标准化组织概览一、标准化组织1、ITU电信标准化部门无线电通信部门电信发展部门2、3GPP3、3GPP24、CCSA二、TDD-LTE与FDD-LTE系统的对比三、LTE技术特点及基本指标1、LTE主要技术特点2、峰值数据速率3、控制面延迟4、用户面延迟5、用户吞吐量6、频谱效率7、移动性8、覆盖9、频谱…

同事跳槽拿下阿里 P6Offer,程序员:会点基础还真不行

前阵子&#xff0c;同事程序员 H 偷偷的向阿里菜鸟投递了自己的简历... 不久后程序员 H 就收到了阿里菜鸟的面试通知&#xff0c;经历 5 轮面试&#xff0c;一举成功拿下 offer 并定级 P6。 小天趁着未来的阿里大佬还在身边&#xff0c;向程序员 H 讨教了一下面试阿里菜鸟的经…

法则三:架构师如何在一定时间内最大化自己的增量价值

法则三&#xff1a;架构师如何在一定时间内最大化自己的增量价值 作为一个架构师&#xff0c;必须要创造足够的商业价值&#xff0c;才能保障自己职业的长期。 那么你作为架构师&#xff0c;该如何为你的公司、部门或团队提供可量化的增量价值呢&#xff1f; 主要有扩大收入与…

2022.12.11 学习周报

文章目录摘要文献阅读1.题目2.摘要3.传统RNN存在的问题4.RNN与IndRNN的对比4.1 隐含层状态更新公式4.2 结构示意图4.3 IndRNN的优势5.IndRNN的分析5.1 RNN5.2 LSTM5.3 IndRNN的初始化5.4 梯度截断5.5 IndRNN6.实验结果6.1 Adding Problem6.2 Sequential MNIST Classification6.…

Spring 体系常用项目

如今做Java尤其是web几乎是避免不了和Spring打交道了&#xff0c;但是Spring是这样的大而全&#xff0c;新鲜名词不断产生&#xff0c;学起来给人一种凌乱的感觉&#xff0c;我就在这里总结一下&#xff0c;理顺头绪。 Spring Spring 概述 Spring 是一个开源框架&#xff0c…

R语言学习笔记——基础篇:第六章-基本图形

R语言 R语言学习笔记——入门篇&#xff1a;第六章-基本图形 文章目录R语言一、条形图1.1、垂直与水平条形图补——数据为因子时绘制垂直与水平条形图1.2、堆砌条形图与分组条形图1.3、数据整合条形图1.4、条形图的微调1.5、棘状图二、饼图三、直方图四、核密度图4.1、简易核密…

CSS基础-装饰,基线,光标类型,边框圆角(胶囊),文字溢出,元素隐藏,边框合并,css画三角形...

CSS基础-装饰 目录CSS基础-装饰1.1 认识基线(了解)1.2 文字对齐问1.3 垂直对齐方式(拓展)项目中 vertical-align 可以解决的问题2.1 光标类型3.1 边框圆角3.2 边框圆角的常见应用4.1 溢出部分显示效果5.1 元素本身隐藏(拓展)元素整体透明度(拓展)边框合并(拓展)用CSS画三角形技…

关键字(五):const和volatile

关键字一."令人误解"的关键字—const1.const的基本特质2.const的各种应用场景1.修饰变量2.修饰数组3.修饰指针4.修饰函数的参数5.修饰返回值二.最易变的关键字—volatile一."令人误解"的关键字—const 1.const的基本特质 简单的示例 const所修饰的变量不可…

[附源码]计算机毕业设计海南与东北的美食文化差异及做法的研究展示平台Springboot程序

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; Springboot mybatis MavenVue等等组成&#xff0c;B/S模式…

2023最新SSM计算机毕业设计选题大全(附源码+LW)之java在线图书馆信息管理系统g6977

好的选题直接决定了毕业设计好坏&#xff0c;甚至决定了能否毕业。今天&#xff0c;我们就来聊一聊毕设该怎么选题。 这里分三个选题标准。 第一&#xff0c;参考所在学校往年选题类型和难度 可以向学长学姐了解往年的选题类型&#xff0c;以及使用的技术&#xff0c;不用向…

Kotlin如何延时准确的循环执行事件,比如倒计时或每一秒执行一次事件

前言 延时循环执行事件很简单,且有很多方式,但想要延时相对精确,就需要稍微设计一下了 普通的方案 线程内阻塞的方案 这种方案很简单,示例代码如下 while (true){block()//执行逻辑Thread.sleep(1000)//延时1秒} 但缺点也是显而易见,其是线程阻塞的,比较浪费资源 异步或挂…

26-Vue之ECharts-柱状图

ECharts-柱状图前言柱状图实现步骤柱状图常见效果标记显示前言 本篇来学习下柱状图的实现 柱状图实现步骤 ECharts 最基本的代码结构准备x轴的数据准备 y 轴的数据准备 option , 将 series 中的 type 的值设置为: bar <!DOCTYPE html> <html lang"en">…