opencv特征匹配中match与KnnMatch返回数据类型

本文详细介绍了OpenCV中BFMatcher和KnnMatch在图像特征匹配中的应用,比较了它们的返回结果类型,并探讨了如何通过距离阈值和比率选择进行匹配优化。展示了使用match和knnMatch进行特征点匹配及结果可视化的方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1、match

    # 初始化 BFMatcher
    bf = cv.BFMatcher()
    # 对描述子进行匹配
    # des1/des2分别是两幅图片特征点的特征向量
    matches = bf.match(des1, des2)
    # 打印match返回数据的类型
    print(type(matches[0]))

match匹配的返回结果是DMatch类型。

DMatch数据结构包含三个非常重要的数据分别是queryIdx,trainIdx,distance;
queryIdx:某一特征点在本帧图像的索引;
trainIdx:trainIdx是该特征点在另一张图像中相匹配的特征点的索引;

distance:代表这一对匹配的特征点描述符的欧式距离,数值越小也就说明俩个特征点越相近。

    print("queryIdx=%d"%matches[0].queryIdx)
    print("trainIdx=%d"%matches[0].trainIdx)
    print("distance=%d"%matches[0].distance)

    输出:
    queryIdx=0
    trainIdx=105
    distance=68

 2、Knnmatch

bf = cv2.BFMatcher()
matches1 = bf.knnMatch(des1, des2, k=2)
# 打印match返回数据的类型
print(type(matches1[0]))
<class 'tuple'>

knnMatch匹配的返回结果是一个元组:说明结果不能改变;

对元组内元素进行类型查询: 所以Knnmatch与match的返回值类型一样,只不过一组返回的2个DMatch类型。

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

for x in matches1[0]:
    print(type(x))

3、总结 

综上所知:

(1)match匹配的返回结果是DMatch类型。distance:代表这一对匹配的特征点描述符的欧式距离,数值越小也就说明俩个特征点越相近。

(2)Knnmatch与match的返回值类型一样,只不过一组返回的2个DMatch类型。这2个DMatch数据类型是2个与原图像特征点最接近的2个特征点(match返回的是最匹配的),只有这2个特征点的欧式距离小于一定值的时候才会认为匹配成功。(可以理解为:2个与原图像特征点最接近和次接近的特征点,一般第一个是最接近匹配点,第二个是次接近匹配点)

4、匹配优化 

(1)对于match类型(注意显示匹配结果:cv.drawMatches

 # 初始化 BFMatcher
    bf = cv.BFMatcher()
    # 对描述子进行匹配
    # des1/des2分别是两幅图片特征点的特征向量
    matches = bf.match(des1, des2)

    # 计算最大距离和最小距离
    min_distance = matches[0].distance
    max_distance = matches[0].distance
    for x in matches:
        if x.distance < min_distance:
            min_distance = x.distance
        if x.distance > max_distance:
            max_distance = x.distance

    # 筛选匹配点
    '''
        当描述子之间的距离大于两倍的最小距离时,认为匹配有误。
        但有时候最小距离会非常小,所以设置一个经验值30作为下限。
    '''
    good_match = []
    for x in matches:
        if x.distance <= max(2 * min_distance, 30):
            good_match.append(x)

    # 绘制匹配结果
    outimage = cv.drawMatches(img1, kp1, img2, kp2, match, outImg=None)

(2)对于Knnmatch类型(注意显示匹配结果:cv.drawMatchesKnn

# 调整ratio
# ratio=0.4:对于准确度要求高的匹配;
# ratio=0.6:对于匹配点数目要求比较多的匹配;
# ratio=0.5:一般情况下。
ratio1 = 0.3
good1 = []

for m1, n1 in matches1:
# 如果最接近和次接近的比值小于一个既定的值,那么我们保留这个最接近的值,认为它和其匹配的点为good_match
    if m1.distance < ratio1 * n1.distance:
        good1.append([m1])
match_result1 = cv2.drawMatchesKnn(img1, kp1, img2, kp2, good1, None, flags=2)

<think>我们正在处理用户关于OpenCV特征匹配的请求。用户希望获得使用教程或示例代码。根据引用[3],我们有一个关于特征匹配的实战教程,其中提到了使用cv::drawMatches函数来可视化匹配结果。同时,引用[1]和[2]是关于模板匹配的,而用户询问的是特征匹配,这是两种不同的技术。因此,我们应主要参考引用[3]的内容。特征匹配通常包括以下步骤:1.检测关键点(如SIFT、SURF、ORB等)。2.计算描述符。3.使用描述符匹配关键点(如BFMatcher或FlannBasedMatcher)。4.可选:过滤匹配(例如使用Lowe'sratiotest或基于距离的阈值)。5.可视化匹配结果。由于用户要求教程或示例代码,我们将提供基于OpenCV的ORB特征匹配的示例代码(因为SIFT和SURF是专利算法,而ORB是免费的,且OpenCV内置支持)。注意:根据引用[3],他们使用了25个最佳匹配点,并使用了cv::drawMatches函数。我们将提供Python版本的代码(考虑到用户可能使用Python),并按照以下步骤:步骤1:导入必要的库步骤2:读取两个图像(一个是查询图像,一个是训练图像)步骤3:初始化ORB检测器(或其他特征检测器)步骤4:检测关键点和计算描述符步骤5:创建BFMatcher(Brute-ForceMatcher)对象步骤6:匹配描述符步骤7:应用比率测试(Lowe'sratiotest)来过滤匹配(可选,但可以提高匹配质量)步骤8:绘制匹配结果(只绘制前N个最佳匹配)步骤9:显示图像注意:OpenCV的drawMatches函数在Python中的使用。由于引用[3]是C++代码,我们将转换为Python。另外,引用[4]提到了一些OpenCV的实用代码示例,但这里我们专注于特征匹配。现在,我们生成示例代码和解释。</think>### OpenCV 特征匹配教程 特征匹配是计算机视觉中的核心技术,用于在两幅图像间寻找相似特征点。以下是基于 OpenCV 的完整实现流程和代码示例: #### 一、核心步骤 1. **特征检测**:使用算法(如 SIFT、ORB 等)检测关键点 2. **描述符计算**:为每个关键点生成特征向量 3. **特征匹配**:计算特征向量间的相似度 4. **匹配过滤**:保留最佳匹配点(如比率测试) 5. **结果可视化**:绘制匹配对应关系 #### 二、完整示例代码 (Python) ```python import cv2 import numpy as np # 1. 读取图像 img1 = cv2.imread('image1.jpg', cv2.IMREAD_GRAYSCALE) # 查询图像 img2 = cv2.imread('image2.jpg', cv2.IMREAD_GRAYSCALE) # 训练图像 # 2. 初始化特征检测器 (ORB算法) orb = cv2.ORB_create(nfeatures=1000) # 3. 检测关键点并计算描述符 keypoints1, descriptors1 = orb.detectAndCompute(img1, None) keypoints2, descriptors2 = orb.detectAndCompute(img2, None) # 4. 创建BFMatcher对象 bf = cv2.BFMatcher(cv2.NORM_HAMMING, crossCheck=True) # 5. 特征匹配 matches = bf.match(descriptors1, descriptors2) # 6. 按距离排序并保留最佳匹配 (前25个) matches = sorted(matches, key=lambda x: x.distance)[:25] # 7. 可视化匹配结果 result_img = cv2.drawMatches( img1, keypoints1, img2, keypoints2, matches, None, flags=cv2.DrawMatchesFlags_NOT_DRAW_SINGLE_POINTS, matchColor=(0, 255, 0), # 绿色连线 singlePointColor=(255, 0, 0) # 蓝色关键点 ) # 8. 显示结果 cv2.imshow('Feature Matching', result_img) cv2.waitKey(0) cv2.destroyAllWindows() ``` #### 三、关键参数说明 1. **特征检测器选择**: - `ORB_create()`:快速且无专利限制(推荐) - `SIFT_create()`:更高精度但需 OpenCV 额外模块 - `AKAZE_create()`:适用于尺度/旋转变化 2. **匹配器类型**: - `BFMatcher`:暴力匹配(适合小规模数据集) - `FlannBasedMatcher`:近似最近邻(适合大规模数据) 3. **匹配过滤方法**: - **比率测试**:`knnMatch()` + Lowe's 比率标准(见相关问题1) - **距离阈值**:`match.distance < 0.75 * min_dist` - **RANSAC**:几何一致性验证(见相关问题2) #### 四、应用场景 1. 图像拼接(全景图生成) 2. 目标识别跟踪 3. 3D重建中的特征对应 4. 增强现实中的姿态估计 5. 视觉SLAM系统[^3]
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小鹿( ﹡ˆoˆ﹡ )

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值