BFMatcher中的OpenCV匹配长度

时间:2017-12-07 12:07:09

标签: python opencv

我试图在两个图像上使用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 个答案:

答案 0 :(得分:1)

因为crossCheck=True正在删除部分结果。

如果您查看docs for the BFMatcher() constructor

  

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

这看起来只会影响knnMatch()方法,但match()方法实际上explicitly call 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)