当前位置: 首页 > news >正文

opencv 进阶17-使用K最近邻和比率检验过滤匹配(图像匹配)

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

下面是使用K最近邻和比率检验进行特征匹配的一般步骤:

  1. 提取特征描述子:
    使用适当的特征提取算法(如SIFT、SURF、ORB等)从图像中提取特征点,并计算每个特征点的描述子。

  2. 特征点匹配:
    对于两幅图像,分别计算每个特征点的描述子,并使用KNN算法来找到在第二幅图像中与每个特征点最接近的K个特征点。

  3. 比率检验:
    对于每个特征点,计算最接近的两个特征点的距离比率(通常称为比率检验)。如果最近的邻居距离远离次近邻居距离,则说明匹配比较可靠。您可以使用一个阈值来过滤匹配。

  4. 过滤匹配:
    应用比率检验,将那些距离比率低于阈值的匹配点过滤掉。这可以帮助排除掉不太可靠的匹配。

  5. 绘制匹配结果:
    将保留下来的匹配点绘制在两幅图像上,以便观察和分析。

想象一下,一大群知名哲学家邀请你评判他们关于对生命、宇宙
和一切事物都很重要的一个问题的辩论。在每位哲学家轮流发言时,你都会认真听。最后,在所有哲学家都发表完他们所有的论点时,你浏览笔记,会发现以下两件事:

  • 每位哲学家都不赞同其他哲学家的观点。
  • 没有哲学家比其他哲学家更有说服力。

根据最初的观察,你推断最多只有一位哲学家的观点是正确的,
但事实上,也有可能所有哲学家的观点都是错误的。然后,根据第二次观察,即使其中一位哲学家的观点是正确的,你也会开始担心可能会选择一个观点错误的哲学家。不管你怎么看,这些人都会让你的晚宴迟到。你称其为平局,并说辩论中仍有最重要的问题尚未解决。我们可以对判断哲学家辩论的假想问题与过滤糟糕关键点匹配的实际问题进行比较。

首先,假设查询图像中的每个关键点在场景中最多有一个正确的
匹配。也就是说,如果查询图像是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* 一般使用&#xff1a; #include<stdio.h>int main…...

Java抽象类详解

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

06-微信小程序-注册程序-场景值

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

多种方法实现 Nginx 隐藏式跳转(隐式URL,即浏览器 URL 跳转后保持不变)

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

视频汇聚云平台EasyCVR视频监控管理平台进行SDN转推的操作步骤

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

SQL 语句继续学习之记录二

三&#xff0c; 聚合与排序 对表进行聚合查询&#xff0c;即使用聚合函数对表中的列进行合计值或者平均值等合计操作。 通常&#xff0c;聚合函数会对null以外的对象进行合计。但是只有count 函数例外&#xff0c;使用count(*) 可以查出包含null在内的全部数据行数。 使用dis…...

【Python原创设计】基于Python Flask 机器学习的全国+上海气象数据采集预测可视化系统-附下载链接以及详细论文报告,原创项目其他均为抄袭

基于Python Flask 机器学习的全国上海气象数据采集预测可视化系统 一、项目简介二、开发环境三、项目技术四、功能结构五、运行截图六、功能实现七、数据库设计八、源码获取 一、项目简介 在信息科技蓬勃发展的当代&#xff0c;我们推出了一款基于Python Flask的全国上海气象数…...

Unity进阶–通过PhotonServer实现人物选择和多人同步–PhotonServer(四)

文章目录 Unity进阶–通过PhotonServer实现人物选择和多人同步–PhotonServer(四)服务端客户端 Unity进阶–通过PhotonServer实现人物选择和多人同步–PhotonServer(四) 服务端 服务端结构如下&#xff1a; UserModel using System; using System.Collections.Generic; usin…...

【Go 基础篇】Go语言获取用户终端输入:实现交互式程序的关键一步

介绍 在许多编程场景中&#xff0c;我们需要编写交互式程序&#xff0c;以便用户可以在终端中输入数据并与程序进行交互。Go语言提供了丰富的方式来获取用户终端输入&#xff0c;使得编写交互式程序变得简单而有趣。本篇博客将深入探讨Go语言中获取用户终端输入的各种方法&…...

学习笔记:Opencv实现拉普拉斯图像锐化算法

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

如何在前端实现WebSocket发送和接收UDP消息(多线程模式)

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

【微服务】一文了解 Nacos

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

量子计算对信息安全的影响:探讨量子计算技术对现有加密方法和信息安全基础设施可能带来的颠覆性影响,以及应对策略

第一章&#xff1a;引言 随着科技的迅猛发展&#xff0c;量子计算作为一项颠覆性的技术正逐渐走入我们的视野。量子计算以其强大的计算能力引发了全球科技界的广泛关注。然而&#xff0c;正如硬币的两面&#xff0c;量子计算技术所带来的不仅仅是计算能力的巨大飞跃&#xff0…...

ajax-axios-url-form-serialize 插件

AJAX AJAX 概念 1.什么是 AJAX ? mdn 使用浏览器的 XMLHttpRequest 对象 与服务器通信 浏览器网页中&#xff0c;使用 AJAX技术&#xff08;XHR对象&#xff09;发起获取省份列表数据的请求&#xff0c;服务器代码响应准备好的省份列表数据给前端&#xff0c;前端拿到数据数…...

【AIGC】单图换脸离线版软件包及使用方法

云端再好&#xff0c;都不如放自己手里啊&#xff0c;想怎么就怎么玩。云端再好&#xff0c;都不如放自己手里啊&#xff0c;想怎么就怎么玩。 Roop作为一个新出的开源项目&#xff0c;配置起来还是有一定难度的。 我已经把各种依赖&#xff0c;模型&#xff0c;环境配置已经…...

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…...

Lombok 的 @Data 注解失效,未生成 getter/setter 方法引发的HTTP 406 错误

HTTP 状态码 406 (Not Acceptable) 和 500 (Internal Server Error) 是两类完全不同的错误&#xff0c;它们的含义、原因和解决方法都有显著区别。以下是详细对比&#xff1a; 1. HTTP 406 (Not Acceptable) 含义&#xff1a; 客户端请求的内容类型与服务器支持的内容类型不匹…...

脑机新手指南(八):OpenBCI_GUI:从环境搭建到数据可视化(下)

一、数据处理与分析实战 &#xff08;一&#xff09;实时滤波与参数调整 基础滤波操作 60Hz 工频滤波&#xff1a;勾选界面右侧 “60Hz” 复选框&#xff0c;可有效抑制电网干扰&#xff08;适用于北美地区&#xff0c;欧洲用户可调整为 50Hz&#xff09;。 平滑处理&…...

React Native 导航系统实战(React Navigation)

导航系统实战&#xff08;React Navigation&#xff09; React Navigation 是 React Native 应用中最常用的导航库之一&#xff0c;它提供了多种导航模式&#xff0c;如堆栈导航&#xff08;Stack Navigator&#xff09;、标签导航&#xff08;Tab Navigator&#xff09;和抽屉…...

边缘计算医疗风险自查APP开发方案

核心目标:在便携设备(智能手表/家用检测仪)部署轻量化疾病预测模型,实现低延迟、隐私安全的实时健康风险评估。 一、技术架构设计 #mermaid-svg-iuNaeeLK2YoFKfao {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg…...

在rocky linux 9.5上在线安装 docker

前面是指南&#xff0c;后面是日志 sudo dnf config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo sudo dnf install docker-ce docker-ce-cli containerd.io -y docker version sudo systemctl start docker sudo systemctl status docker …...

【算法训练营Day07】字符串part1

文章目录 反转字符串反转字符串II替换数字 反转字符串 题目链接&#xff1a;344. 反转字符串 双指针法&#xff0c;两个指针的元素直接调转即可 class Solution {public void reverseString(char[] s) {int head 0;int end s.length - 1;while(head < end) {char temp …...

Nginx server_name 配置说明

Nginx 是一个高性能的反向代理和负载均衡服务器&#xff0c;其核心配置之一是 server 块中的 server_name 指令。server_name 决定了 Nginx 如何根据客户端请求的 Host 头匹配对应的虚拟主机&#xff08;Virtual Host&#xff09;。 1. 简介 Nginx 使用 server_name 指令来确定…...

Robots.txt 文件

什么是robots.txt&#xff1f; robots.txt 是一个位于网站根目录下的文本文件&#xff08;如&#xff1a;https://example.com/robots.txt&#xff09;&#xff0c;它用于指导网络爬虫&#xff08;如搜索引擎的蜘蛛程序&#xff09;如何抓取该网站的内容。这个文件遵循 Robots…...

OPenCV CUDA模块图像处理-----对图像执行 均值漂移滤波(Mean Shift Filtering)函数meanShiftFiltering()

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 算法描述 在 GPU 上对图像执行 均值漂移滤波&#xff08;Mean Shift Filtering&#xff09;&#xff0c;用于图像分割或平滑处理。 该函数将输入图像中的…...

dify打造数据可视化图表

一、概述 在日常工作和学习中&#xff0c;我们经常需要和数据打交道。无论是分析报告、项目展示&#xff0c;还是简单的数据洞察&#xff0c;一个清晰直观的图表&#xff0c;往往能胜过千言万语。 一款能让数据可视化变得超级简单的 MCP Server&#xff0c;由蚂蚁集团 AntV 团队…...