内容来自: Basics of Brute-Force Matcher

Brute-Force Matcher翻译过来就是“暴力匹配器”的意思

暴力匹配器(Brute-Force matcher)很简单。它取第一集合中某一个特征的描述子,与第二集合中所有特征的描述子通过某种距离度量进行匹配,然后返回距离最近的那个。

对于 BF matcher,首先我们必须用 cv.BFMatcher() 来创建一个 BFMatcher 对象。它有两个可选参数。第一个是 normType,指定要使用哪种距离测量方式。默认是 cv.NORM_L2。这是适合用在 SIFT、SURF 等浮点描述子的(也有 cv.NORM_L1)。对于像 ORB、BRIEF、BRISK 等基于二进制字符串的描述子,应使用 cv.NORM_HAMMING(它用 Hamming 距离)。如果 ORB 在构造时使用 WTA_K == 3 或 4,就应该用 cv.NORM_HAMMING2。

第二个参数是布尔变量 crossCheck,默认是 false。如果设为 true,则 Matcher 只返回那些匹配对 (i, j),满足 A 集合的第 i 个描述子在 B 集合中与第 j 个描述子是最优匹配,且反过来 B 集合的第 j 个描述子在 A 集合中与第 i 个描述子也是最优匹配。也就是说,这两个集合中的特征必须相互匹配。这会提供更加一致的结果。

一旦创建了 BFMatcher,对我们有两个重要的方法:BFMatcher.match() 和 BFMatcher.knnMatch()。第一个返回最好的匹配。第二个返回 k 个最好的匹配(k 由用户指定)。当我们需要在匹配上做进一步处理时,这个可能会很有用。

使用ORB描述子的暴力匹配:

在这里,我们将看一个简单的例子,演示如何在两张图像之间进行特征匹配。在这个例子里,我有一张 queryImage 和一张 trainImage。我们将尝试通过特征匹配,在 trainImage 中找到 queryImage。(使用的图像是 /samples/data/box.png 和 /samples/data/box_in_scene.png)

我们将使用 ORB 描述子来做特征匹配。

import numpy as np
import cv2 as cv
import matplotlib.pyplot as plt
 
img1 = cv.imread('box.png',cv.IMREAD_GRAYSCALE)          # queryImage
img2 = cv.imread('box_in_scene.png',cv.IMREAD_GRAYSCALE) # trainImage
 
# Initiate ORB detector
orb = cv.ORB_create()
 
# find the keypoints and descriptors with ORB
kp1, des1 = orb.detectAndCompute(img1,None)
kp2, des2 = orb.detectAndCompute(img2,None)

接下来我们用距离测量方式 cv.NORM_HAMMING(因为我们用的是 ORB 描述子)创建一个 BFMatcher 对象,并把 crossCheck 打开以获得更好的结果。然后我们调用 Matcher.match() 方法来获取两张图像间的最佳匹配。接着我们把这些匹配按距离(distance)升序排序,这样距离最小(匹配最好的)会排在前面。最后我们只画出前 10 个匹配(只是为了便于看清楚,你可以根据需要画更多)。

# create BFMatcher object
bf = cv.BFMatcher(cv.NORM_HAMMING, crossCheck=True)
 
# Match descriptors.
matches = bf.match(des1,des2)
 
# Sort them in the order of their distance.
matches = sorted(matches, key = lambda x:x.distance)
 
# Draw first 10 matches.
img3 = cv.drawMatches(img1,kp1,img2,kp2,matches[:10],None,flags=cv.DrawMatchesFlags_NOT_DRAW_SINGLE_POINTS)
 
plt.imshow(img3),plt.show()

注意: ratio test指的就是比值测试。

ORB 的描述子是二进制描述子,完全可以配合 cv::BFMatcher::knnMatch() 使用——常见做法是设置 k=2,再对两邻近匹配做 Lowe 的 ratio test(比值测试) 来筛掉歧义匹配;同时把距离度量设为 cv::NORM_HAMMING(若 ORB 的 WTA_K 为 3 或 4,则用 cv::NORM_HAMMING2)。

在这里插入图片描述

Logo

火山引擎开发者社区是火山引擎打造的AI技术生态平台,聚焦Agent与大模型开发,提供豆包系列模型(图像/视频/视觉)、智能分析与会话工具,并配套评测集、动手实验室及行业案例库。社区通过技术沙龙、挑战赛等活动促进开发者成长,新用户可领50万Tokens权益,助力构建智能应用。

更多推荐