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)
- matches1to2:二维列表,格式为[[match1, match2], ...],每个子列表对应一个关键点的多个匹配结果。
- 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()