opencv 进阶17-使用K最近邻和比率检验过滤匹配(图像匹配)
K最近邻(K-Nearest Neighbors,简称KNN)和比率检验(Ratio Test)是在计算机视觉中用于特征匹配的常见技术。它们通常与特征描述子(例如SIFT、SURF、ORB等)一起使用,以在图像中找到相似的特征点。
下面是使用K最近邻和比率检验进行特征匹配的一般步骤:
-
提取特征描述子:
使用适当的特征提取算法(如SIFT、SURF、ORB等)从图像中提取特征点,并计算每个特征点的描述子。 -
特征点匹配:
对于两幅图像,分别计算每个特征点的描述子,并使用KNN算法来找到在第二幅图像中与每个特征点最接近的K个特征点。 -
比率检验:
对于每个特征点,计算最接近的两个特征点的距离比率(通常称为比率检验)。如果最近的邻居距离远离次近邻居距离,则说明匹配比较可靠。您可以使用一个阈值来过滤匹配。 -
过滤匹配:
应用比率检验,将那些距离比率低于阈值的匹配点过滤掉。这可以帮助排除掉不太可靠的匹配。 -
绘制匹配结果:
将保留下来的匹配点绘制在两幅图像上,以便观察和分析。
想象一下,一大群知名哲学家邀请你评判他们关于对生命、宇宙
和一切事物都很重要的一个问题的辩论。在每位哲学家轮流发言时,你都会认真听。最后,在所有哲学家都发表完他们所有的论点时,你浏览笔记,会发现以下两件事:
- 每位哲学家都不赞同其他哲学家的观点。
- 没有哲学家比其他哲学家更有说服力。
根据最初的观察,你推断最多只有一位哲学家的观点是正确的,
但事实上,也有可能所有哲学家的观点都是错误的。然后,根据第二次观察,即使其中一位哲学家的观点是正确的,你也会开始担心可能会选择一个观点错误的哲学家。不管你怎么看,这些人都会让你的晚宴迟到。你称其为平局,并说辩论中仍有最重要的问题尚未解决。我们可以对判断哲学家辩论的假想问题与过滤糟糕关键点匹配的实际问题进行比较。
首先,假设查询图像中的每个关键点在场景中最多有一个正确的
匹配。也就是说,如果查询图像是NASA标识,那么就假定另一幅图像、(场景)最多包含一个NASA标识。假设一个查询关键点最多有一个正确或者良好的匹配,那么在考虑所有可能的匹配时,我们主要观察糟糕的匹配。
因此,蛮力匹配器计算每个可能匹配的距离分值,可以提供大量的对糟糕匹配的距离分值的观察。与无数糟糕的匹配相比,我期望良好的匹配会有明显更好(更低)的距离分值,因此糟糕的匹配分值可以帮助我们为针对良好的匹配选择一个阈值。这样的阈值不一定能很好地推广到不同的查询关键点或者不同的场景,但是至少在具体案例上会有所帮助。
现在,我们来考虑修改后的蛮力匹配算法的实现,该算法以上述
方式自适应地选择距离阈值。在上一节的示例代码中,我们使用
cv2.BFMatcher类的match方法来获得包含每个查询关键点的单个最佳匹配(最小距离)的列表。这样的实现丢弃了有关所有可能的糟糕匹配的距离分值的信息,而这类信息是自适应方法所需要的。幸运的是,cv2.BFMatcher还提供了knnMatch方法
,该方法接受一个参数k,可以指定希望为每个查询关键点保留的最佳(最短距离)匹配的最大数量。(在某些情况下,得到的匹配数可能比指定的数量最大值更少。)KNN表示K最近邻(K-Nearest Neighbor)。
我们会使用knnMatch方法为每个查询关键点请求两个最佳匹配的
列表。基于每个查询关键点至多有一个正确匹配的假设,我们确信次优匹配是错误的。次优匹配的距离分值乘以一个小于1的值,就可以获得阈值。
然后,只有当距离分值小于阈值时,才将最佳匹配视为良好的匹
配。这种方法被称为比率检验(ratio test),最先是由David
Lowe(SIFT算法的作者)提出来的。他在论文“Distinctive Image
Features from Scale-Invariant Keypoints”(网址为
https://www.cs.ubc.cs/~lowe/papers/ijcv04.pdf)中描述了比率检
验。具体来说,在“Application to object recognition”部分,他
声明如下:
一个匹配正确的概率可以根据最近邻到第2近邻的距离比例来确
定。
我们可以用与前面代码示例相同的方式加载图像、检测关键点,
并计算ORB描述符。然后,使用下面两行代码执行蛮力KNN匹配:
bf = cv2.BFMatcher(cv2.NORM_HAMMING, crossCheck= False)knn_matches = bf.knnMatch(descriptors1, descriptors2, k=2)
knnMatch返回列表的列表,每个内部列表至少包含一个匹配项,
且不超过k个匹配项,各匹配项从最佳(最短距离)到最差依次排序。
下列代码行根据最佳匹配的距离分值对外部列表进行排序:
# 根据匹配的质量,对匹配进行排序,显示前n个排序knn_matches = sorted(knn_matches, key=lambda x: x[0].distance)
总体代码如下:
import cv2def orb_test():# 加载图片 灰色img1 = cv2.imread('images\\quexiao\\2-1.png')gray1 = cv2.cvtColor(img1, cv2.COLOR_BGR2GRAY)img2 = cv2.imread('images\\quexiao\\2.png')gray2 = cv2.cvtColor(img2, cv2.COLOR_BGR2GRAY)image1 = gray1.copy()image2 = gray2.copy()'''1.使用ORB算法检测特征点、描述符'''orb = cv2.ORB_create(128)keypoints1, descriptors1 = orb.detectAndCompute(image1, None)keypoints2, descriptors2 = orb.detectAndCompute(image2, None)# BFMatcher解决匹配bf = cv2.BFMatcher(cv2.NORM_HAMMING, crossCheck= False)knn_matches = bf.knnMatch(descriptors1, descriptors2, k=2)# matches = bf.match(descriptors1, descriptors2)# 根据匹配的质量,对匹配进行排序,显示前n个排序knn_matches = sorted(knn_matches, key=lambda x: x[0].distance)# 绘制前10个最佳匹配img_matches = cv2.drawMatchesKnn(img1, keypoints1, img2, keypoints2, knn_matches[:10], img2,flags=cv2.DRAW_MATCHES_FLAGS_NOT_DRAW_SINGLE_POINTS)cv2.imshow('matche', img_matches)cv2.waitKey(0)cv2.destroyAllWindows()if __name__ == '__main__':orb_test()
运行效果:
将此输出图像与上一节中的输出图像进行比较,可以看到使用KNN
和比率检验可以过滤掉很多糟糕的匹配项。剩余的匹配项并不完美,但是几乎所有的匹配项都指向了正确的区域。
实验原图在上一节中,上一节 opencv 进阶16-基于FAST特征和BRIEF描述符的ORB(图像匹配)
相关文章:

opencv 进阶17-使用K最近邻和比率检验过滤匹配(图像匹配)
K最近邻(K-Nearest Neighbors,简称KNN)和比率检验(Ratio Test)是在计算机视觉中用于特征匹配的常见技术。它们通常与特征描述子(例如SIFT、SURF、ORB等)一起使用,以在图像中找到相似…...

Mac Flutter web环境搭建
获取 Flutter SDK 下载以下安装包来获取最新的 stable Flutter SDK将文件解压到目标路径, 比如: cd ~/development $ unzip ~/Downloads/flutter_macos_3.13.0-stable.zip 配置 flutter 的 PATH 环境变量: export PATH"$PATH:pwd/flutter/bin" // 这个命…...

在外SSH远程连接macOS服务器
文章目录 前言1. macOS打开远程登录2. 局域网内测试ssh远程3. 公网ssh远程连接macOS3.1 macOS安装配置cpolar3.2 获取ssh隧道公网地址3.3 测试公网ssh远程连接macOS 4. 配置公网固定TCP地址4.1 保留一个固定TCP端口地址4.2 配置固定TCP端口地址 5. 使用固定TCP端口地址ssh远程 …...

Dockerfile文件详细
Dockerfile 是一个文本文件,里面包含组装新镜像时用到的基础镜像和各种指令,使用dockerfile 文件来定义镜像,然后运行镜像,启动容器。 dockerfile文件的组成部分 一个dockerfile文件包含以下部分: 基础镜像信息&…...

C语言学习系列-->看淡指针(3)
文章目录 一、字符指针变量二、数组指针变量2.1 概述2.2 数组指针初始化 三、二维数组传参本质四、函数指针五、typedef关键字六、函数指针数组 一、字符指针变量 在指针的类型中我们知道有⼀种指针类型为字符指针 char* 一般使用: #include<stdio.h>int main…...

Java抽象类详解
抽象类 抽象类的概念 在面向对象的概念中,所有的对象都是通过类来描绘的,但是反过来,并不是所有的类都是来描绘对象的,如果一个类中没有包含足够的信息来描绘一个具体的对象,这样的类就是抽象类。比如: 说…...

06-微信小程序-注册程序-场景值
06-微信小程序-注册程序 文章目录 注册小程序参数 Object object案例代码 场景值场景值作用场景值列表案例代码 注册小程序 每个小程序都需要在 app.js 中调用 App 方法注册小程序实例,绑定生命周期回调函数、错误监听和页面不存在监听函数等。 详细的参数含义和使…...

多种方法实现 Nginx 隐藏式跳转(隐式URL,即浏览器 URL 跳转后保持不变)
多种方法实现 Nginx 隐藏式跳转(隐式URL,即浏览器 URL 跳转后保持不变)。 一个新项目,后端使用 PHP 实现,前端不做路由,提供一个模板,由后端路由控制。 Route::get(pages/{name}, [\App\Http\Controllers\ResourceController::class, getResourceVersion])...

视频汇聚云平台EasyCVR视频监控管理平台进行SDN转推的操作步骤
视频汇聚/视频云存储/集中存储/视频监控管理平台EasyCVR能在复杂的网络环境中,将分散的各类视频资源进行统一汇聚、整合、集中管理,实现视频资源的鉴权管理、按需调阅、全网分发、云存储、智能分析等,视频智能分析平台EasyCVR融合性强、开放度…...

SQL 语句继续学习之记录二
三, 聚合与排序 对表进行聚合查询,即使用聚合函数对表中的列进行合计值或者平均值等合计操作。 通常,聚合函数会对null以外的对象进行合计。但是只有count 函数例外,使用count(*) 可以查出包含null在内的全部数据行数。 使用dis…...

【Python原创设计】基于Python Flask 机器学习的全国+上海气象数据采集预测可视化系统-附下载链接以及详细论文报告,原创项目其他均为抄袭
基于Python Flask 机器学习的全国上海气象数据采集预测可视化系统 一、项目简介二、开发环境三、项目技术四、功能结构五、运行截图六、功能实现七、数据库设计八、源码获取 一、项目简介 在信息科技蓬勃发展的当代,我们推出了一款基于Python Flask的全国上海气象数…...

Unity进阶–通过PhotonServer实现人物选择和多人同步–PhotonServer(四)
文章目录 Unity进阶–通过PhotonServer实现人物选择和多人同步–PhotonServer(四)服务端客户端 Unity进阶–通过PhotonServer实现人物选择和多人同步–PhotonServer(四) 服务端 服务端结构如下: UserModel using System; using System.Collections.Generic; usin…...
【Go 基础篇】Go语言获取用户终端输入:实现交互式程序的关键一步
介绍 在许多编程场景中,我们需要编写交互式程序,以便用户可以在终端中输入数据并与程序进行交互。Go语言提供了丰富的方式来获取用户终端输入,使得编写交互式程序变得简单而有趣。本篇博客将深入探讨Go语言中获取用户终端输入的各种方法&…...

学习笔记:Opencv实现拉普拉斯图像锐化算法
2023.8.19 为了在暑假内实现深度学习的进阶学习,Copy大神的代码,记录学习日常 图像锐化的百科: 图像锐化算法-sharpen_lemonHe_的博客-CSDN博客 在环境配置中要配置opencv: pip install opencv-contrib-python Code and lena.png…...

如何在前端实现WebSocket发送和接收UDP消息(多线程模式)
目录 简介:步骤1:创建WebSocket连接步骤2:创建Web Workers步骤3:发送和接收UDP消息(多线程模式)结束语: 简介: 本文将继续介绍如何在前端应用中利用WebSocket技术发送和接收UDP消息…...

【微服务】一文了解 Nacos
一文了解 Nacos Nacos 在阿里巴巴起源于 2008 2008 2008 年五彩石项目(完成微服务拆分和业务中台建设),成长于十年双十一的洪峰考验,沉淀了简单易用、稳定可靠、性能卓越的核心竞争力。 随着云计算兴起, 2018 2018 20…...

量子计算对信息安全的影响:探讨量子计算技术对现有加密方法和信息安全基础设施可能带来的颠覆性影响,以及应对策略
第一章:引言 随着科技的迅猛发展,量子计算作为一项颠覆性的技术正逐渐走入我们的视野。量子计算以其强大的计算能力引发了全球科技界的广泛关注。然而,正如硬币的两面,量子计算技术所带来的不仅仅是计算能力的巨大飞跃࿰…...

ajax-axios-url-form-serialize 插件
AJAX AJAX 概念 1.什么是 AJAX ? mdn 使用浏览器的 XMLHttpRequest 对象 与服务器通信 浏览器网页中,使用 AJAX技术(XHR对象)发起获取省份列表数据的请求,服务器代码响应准备好的省份列表数据给前端,前端拿到数据数…...

【AIGC】单图换脸离线版软件包及使用方法
云端再好,都不如放自己手里啊,想怎么就怎么玩。云端再好,都不如放自己手里啊,想怎么就怎么玩。 Roop作为一个新出的开源项目,配置起来还是有一定难度的。 我已经把各种依赖,模型,环境配置已经…...

8.19论文阅读
文章目录 Graph-Segmenter: Graph Transformer with Boundary-aware Attention for Semantic Segmentation方法 SCSC: Spatial Cross-scale Convolution Module to Strengthen both CNNs and Transformers方法 Deformable Mixer Transformer with Gating for Multi-Task Learni…...

C++_核心编程_多态案例二-制作饮品
#include <iostream> #include <string> using namespace std;/*制作饮品的大致流程为:煮水 - 冲泡 - 倒入杯中 - 加入辅料 利用多态技术实现本案例,提供抽象制作饮品基类,提供子类制作咖啡和茶叶*//*基类*/ class AbstractDr…...

【第二十一章 SDIO接口(SDIO)】
第二十一章 SDIO接口 目录 第二十一章 SDIO接口(SDIO) 1 SDIO 主要功能 2 SDIO 总线拓扑 3 SDIO 功能描述 3.1 SDIO 适配器 3.2 SDIOAHB 接口 4 卡功能描述 4.1 卡识别模式 4.2 卡复位 4.3 操作电压范围确认 4.4 卡识别过程 4.5 写数据块 4.6 读数据块 4.7 数据流…...
ip子接口配置及删除
配置永久生效的子接口,2个IP 都可以登录你这一台服务器。重启不失效。 永久的 [应用] vi /etc/sysconfig/network-scripts/ifcfg-eth0修改文件内内容 TYPE"Ethernet" BOOTPROTO"none" NAME"eth0" DEVICE"eth0" ONBOOT&q…...
基于Java Swing的电子通讯录设计与实现:附系统托盘功能代码详解
JAVASQL电子通讯录带系统托盘 一、系统概述 本电子通讯录系统采用Java Swing开发桌面应用,结合SQLite数据库实现联系人管理功能,并集成系统托盘功能提升用户体验。系统支持联系人的增删改查、分组管理、搜索过滤等功能,同时可以最小化到系统…...
纯 Java 项目(非 SpringBoot)集成 Mybatis-Plus 和 Mybatis-Plus-Join
纯 Java 项目(非 SpringBoot)集成 Mybatis-Plus 和 Mybatis-Plus-Join 1、依赖1.1、依赖版本1.2、pom.xml 2、代码2.1、SqlSession 构造器2.2、MybatisPlus代码生成器2.3、获取 config.yml 配置2.3.1、config.yml2.3.2、项目配置类 2.4、ftl 模板2.4.1、…...

Golang——7、包与接口详解
包与接口详解 1、Golang包详解1.1、Golang中包的定义和介绍1.2、Golang包管理工具go mod1.3、Golang中自定义包1.4、Golang中使用第三包1.5、init函数 2、接口详解2.1、接口的定义2.2、空接口2.3、类型断言2.4、结构体值接收者和指针接收者实现接口的区别2.5、一个结构体实现多…...

MyBatis中关于缓存的理解
MyBatis缓存 MyBatis系统当中默认定义两级缓存:一级缓存、二级缓存 默认情况下,只有一级缓存开启(sqlSession级别的缓存)二级缓存需要手动开启配置,需要局域namespace级别的缓存 一级缓存(本地缓存&#…...

【无标题】湖北理元理律师事务所:债务优化中的生活保障与法律平衡之道
文/法律实务观察组 在债务重组领域,专业机构的核心价值不仅在于减轻债务数字,更在于帮助债务人在履行义务的同时维持基本生活尊严。湖北理元理律师事务所的服务实践表明,合法债务优化需同步实现三重平衡: 法律刚性(债…...

Linux-进程间的通信
1、IPC: Inter Process Communication(进程间通信): 由于每个进程在操作系统中有独立的地址空间,它们不能像线程那样直接访问彼此的内存,所以必须通过某种方式进行通信。 常见的 IPC 方式包括&#…...

echarts使用graphic强行给图增加一个边框(边框根据自己的图形大小设置)- 适用于无法使用dom的样式
pdf-lib https://blog.csdn.net/Shi_haoliu/article/details/148157624?spm1001.2014.3001.5501 为了完成在pdf中导出echarts图,如果边框加在dom上面,pdf-lib导出svg的时候并不会导出边框,所以只能在echarts图上面加边框 grid的边框是在图里…...