OpenCV 第12课 图像处理—特征匹配(二)

4. 最近邻匹配

FLANN(Fast Library for Approximate Nearest Neighbors)用于进行近似最近邻搜索。它特别适用于在大规模数据集上快速查找数据点的最近邻、k个最近邻或半径内的邻居。FLANN基于多种索引技术,包括K-D树、K-means树、复合索引等,以提供高效的近似搜索算法。

4.1 FLANN特征匹配的原理

1、数据预处理‌:在进行特征匹配之前,首先需要对输入数据进行预处理。这通常包括特征提取(如SIFT、ORB等),将图像转换为数值特征向量。

2、构建索引‌:使用FLANN库,首先需要为特征向量构建一个搜索索引。FLANN支持多种索引类型,例如:

  • 线性搜索‌(Linear Search):适用于小规模数据集,但对于大规模数据集效率较低。
  • K-D ‌(KD-Tree):适用于高维数据,能够提供较好的查询性能。
  • K-means ‌(KMeans Tree):结合了K-means聚类和KD树的优势,适用于大规模数据集。
  • 复合索引‌(Composite Index):结合了多个索引以提高查询效率。

注意:选择合适的索引类型取决于数据的维度、数量以及查询性能需求

3、‌查询‌:一旦索引构建完成,就可以使用它来查询最近邻。这可以通过以下几种方式实现:

  • 最近邻搜索‌(Nearest Neighbor Search):找到一个查询点在数据集中的最近点。
  • K 个最近邻搜索‌(K-Nearest Neighbors Search):找到查询点在数据集中的k个最近点。
  • 半径内的邻居搜索‌(Radius Search):找到所有距离查询点在特定半径内的点。

4.2 FannBaseMatcher

**1、索引参数:**在构建FannBaseMatcher之前,你需要选择合适的索引参数,这些参数会影响到后续的搜索效率和准确性。

其中‌index_type‌: 指定索引的类型。通常有以下几种选项:

  • FLANN_INDEX_LINEAR: 线性搜索,适用于小数据集。
  • FLANN_INDEX_KDTREE: KD树,适用于中等规模的数据集。
  • FLANN_INDEX_KMEANS: K均值树,适用于大规模数据集。
  • FLANN_INDEX_COMPOSITE: 组合索引,结合了KDTREE和KMEANS的优点。
  • FLANN_INDEX_AUTOTUNED: 自动调优,自动选择最优的索引类型。
  • FLANN_INDEX_HIERARCHICAL:层次化索引结构
  • FLANN_INDEX_LHS:局部敏感哈希算法

trees‌: 仅当使用KD树或KMeans树时,这个参数指定树的数目。增加树的数目可以提高搜索速度,但也会增加内存消耗。

**当index_type =**FLANN_INDEX_LHS时,table_num表示哈希表的数量,key_size参数用于控制局部敏感哈希(LSH)算法中哈希表的键长度;multi_probe_level 控制多探针搜索的深度

**2、搜索参数:**在执行图像匹配时,你可以调整搜索参数来优化匹配结果。

  • checks‌: 这个参数用于控制搜索过程中的检查次数。对于KD树和KMeans树,较高的checks值可以增加召回率,但同时也会增加计算时间。对于自动调优索引,这个值通常设置为-2(自动选择)。
  • eps‌: 指定搜索过程的误差界限。当使用FLANN_INDEX_AUTOTUNED或FLANN_INDEX_HIERARCHICAL时,eps用于控制搜索的精度。较小的eps值可以提供更精确的结果,但会增加计算时间。

4.3 knnMatch

knnMatch是OpenCV中用于特征匹配的函数,主要用于特征描述符的k近邻匹配。以下是关键信息:

1、函数原型:knnMatch(descriptor1, descriptor2, k=2)

2、参数说明:

  • descriptor1:查询描述符(如通过detectAndCompute提取的特征)。
  • descriptor2:训练描述符(需与descriptor1格式一致)。
  • k:返回每个查询点的前k个最佳匹配。

4.4 drawMatchesKnn

drawMatchesKnn是OpenCV中用于绘制特征匹配的函数,适用于knnMatch返回的二维匹配结果(每个关键点匹配多个候选点)。以下是核心要点:

cv2.drawMatchesKnn(img1, keypoints1, img2, keypoints2, matches1to2, outImg, matchColor=None, singlePointColor=None, matchesMask=None, flags=None)

  1. matches1to2:二维列表,格式为[[match1, match2], ...],每个子列表对应一个关键点的多个匹配结果。
  2. flags:控制绘制行为,如cv2.DRAW_MATCHES_FLAGS_NOT_DRAW_SINGLE_POINTS可隐藏未匹配点。

4.5 代码示例

python 复制代码
import numpy as np
import cv2 as cv

img1 = cv.imread('test.jpg',cv.IMREAD_GRAYSCALE)    # 索引图像
img2 = cv.imread('test1.jpg',cv.IMREAD_GRAYSCALE)    # 训练图像
 
# 初始化ORB描述符
orb = cv.ORB_create()
 
# 基于ORB找到关键点和描述符
kp1, des1 = orb.detectAndCompute(img1,None)
kp2, des2 = orb.detectAndCompute(img2,None)

# FLANN的参数
FLANN_INDEX_LSH = 6
index_params= dict(algorithm = FLANN_INDEX_LSH,
                   table_number = 6, # 12
                   key_size = 12,     # 20
                   multi_probe_level = 1) #2
search_params = dict(checks=50)   # 或传递一个空字典
flann = cv.FlannBasedMatcher(index_params,search_params)

matches = flann.knnMatch(des1,des2,k=2)

img3 = cv.drawMatchesKnn(img1,kp1,img2,kp2,matches,None)
cv.imshow("show",img3)
cv.waitKey()
cv.destroyAllWindows()
相关推荐
庞轩px2 分钟前
MinorGC的完整流程与复制算法深度解析
java·jvm·算法·性能优化
夏同学Xavi8 分钟前
skls-mgr:统一管理 Agent Skills 的 CLI 工具
人工智能·程序员·命令行
Queenie_Charlie9 分钟前
Manacher算法
c++·算法·manacher
闻缺陷则喜何志丹9 分钟前
【树的直径 离散化】 P7807 魔力滋生|普及+
c++·算法·洛谷·离散化·树的直径
天青色等烟雨0912 分钟前
Skill的终局:不是被生成,而是能进化
人工智能·agent
FPGA-ADDA15 分钟前
第四篇:嵌入式系统常用通信接口详解(I2C、SPI、UART、RS232/485、CAN、USB)
人工智能·单片机·嵌入式硬件·fpga开发·信息与通信
AI_Ming17 分钟前
Seq2Seq-大模型知识点(程序员转行AI大模型学习)
算法·ai编程
智算菩萨18 分钟前
【How Far Are We From AGI】7 AGI的七重奏——从实验室到现实世界的应用图景与文明展望
论文阅读·人工智能·ai·agi·感知
若水不如远方23 分钟前
分布式一致性(六):拥抱可用性 —— 最终一致性与 Gossip 协议
分布式·后端·算法
计算机安禾27 分钟前
【C语言程序设计】第35篇:文件的打开、关闭与读写操作
c语言·开发语言·c++·vscode·算法·visual studio code·visual studio