OpenCV中BFMatcher的匹配长度

4

我正在尝试在两张图片上使用 SIFT,并使用 OpenCV 中的 BFMatcher 匹配关键点。

然而,匹配数不等于查询描述符的数量。有人能解释一下为什么它们不相等吗?

根据 docs 的介绍,match() 函数"为查询集中的每个描述符找到最佳匹配项。"

import cv2
import numpy as np

im1 = cv2.imread("trex1.png", cv2.IMREAD_GRAYSCALE)
im2 = cv2.imread("trex2.png", cv2.IMREAD_GRAYSCALE)

sift = cv2.xfeatures2d.SIFT_create()
kp1, des1 = sift.detectAndCompute(im1, None)
kp2, des2 = sift.detectAndCompute(im2, None)

im_kp1 = np.zeros(im1.shape, dtype=np.uint8)
im_kp2 = np.zeros(im1.shape, dtype=np.uint8)
im_kp1 = cv2.drawKeypoints(im1,kp1,None)
im_kp2 = cv2.drawKeypoints(im2,kp2,None)

bf = cv2.BFMatcher(cv2.NORM_L2, crossCheck=True)
matches = bf.match(des1,des2)

print len(des1)
# Result : 78
print len(des2)
# Result : 71
print len(matches)
# Result : 55
1个回答

6

因为 crossCheck=True 会删除一些结果。

如果您查看 BFMatcher() 构造函数的文档

crossCheck 如果它是 false,则这将是默认的 BFMatcher 行为,当它为每个查询描述符找到 k 个最近邻居时。如果 crossCheck==true,则 k=1 的 knnMatch() 方法仅返回一对 (i,j),使得对于第 i 个查询描述符,匹配器集合中的第 j 个描述符是最近的,并反之亦然,即 BFMatcher 仅返回一致的对。当有足够的匹配时,这种技术通常产生最佳结果以最小化异常值数量。这是 SIFT 论文中由 D. Lowe 使用的比率测试的替代方法。

这看起来只会影响 knnMatch() 方法,但实际上,match() 方法实际上会显式调用 knnMatch()

void DescriptorMatcher::match( InputArray queryDescriptors, std::vector<DMatch>& matches, InputArrayOfArrays masks )
{
    CV_INSTRUMENT_REGION()

    std::vector<std::vector<DMatch> > knnMatches;
    knnMatch( queryDescriptors, knnMatches, 1, masks, true /*compactResult*/ );
    convertMatches( knnMatches, matches );
}
如果你设置crossCheck=False(或者只不指定,默认值是False),那么你将得到:
len(query_descriptors) == len(matches)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接