Opencv:BoW 计算 SURF 描述符

Opencv: BoW computing SURF descriptors

我正在尝试对一组图像进行词袋处理,提取 SURF 描述符。但是,我在下面粘贴的代码的最后一行收到以下错误:

type == src2.type() && src1.cols == src2.cols && (type == CV_32F || type == CV_8U)

如果我改用 "SIFT",那么一切正常。但是当我使用 "SURF" 时,BoW 无法计算 SURF 描述符。

这是实例化 SURF 的正确方法吗?我可以使用 cv2.NORM_L2 距离函数吗?

imgs2Keypoints = {}
kmeansTrainer = cv2.BOWKMeansTrainer(10);  
for pathToImage in images:
    sift = cv2.SURF(400)
    img = cv2.imread(pathToImage)
    kp, des = sift.detectAndCompute(img, None)
    des = np.float32(des)
    kmeansTrainer.add(des)
    imgs2Keypoints[pathToImage] = kp 
vocabulary = kmeansTrainer.cluster()
bow_ext.setVocabulary(vocabulary)

surf2 = cv2.DescriptorExtractor_create("SURF")
bow_ext = cv2.BOWImgDescriptorExtractor(surf2, cv2.BFMatcher(cv2.NORM_L2))

for pathToImage in images:
    img = cv2.imread(pathToImage)
    histogram = bow_ext.compute(img, imgs2Keypoints[pathToImage])[0]

编辑:

sift = cv2.SURF(400)

创建扩展的 SURF 描述符(128 维),而

surf2 = cv2.DescriptorExtractor_create("SURF")

创建标准的 SURF 描述符(64 维)。

一个可能的解决方案是禁用 sift 对象的扩展描述符

sift.extended = False

编辑 2:

与扩展描述符一起使用:

surf2.setBool("extended", True)

关于L2范数:是的,L2距离很好。如 OpenCV docs 所述:

L1 and L2 norms are preferable choices for SIFT and SURF descriptors