在 Python 中使用 FlannBasedMatcher 在 DMatch class 中使用 imgIdx 时出现问题

Problem with imgIdx in DMatch class using FlannBasedMatcher in Python

我和这里有同样的问题:

how to access best image corresponding to best keypoint match using opencv flannbasedmatcher and dmatch

很遗憾,这个 post 没有答案。

我有几个图像(和相应的描述符),我使用 'add' 方法添加到 FlannBasedMatcher(每组描述符一次,对应一个图像)。

然而,当我匹配图像时,return imgIdx 比训练集中的图像数量大得多。我觉得每个描述符都被当成一张图片,但这不是我想要的。

我想知道每个特征匹配到哪个图像(或描述符集)。

这是我的代码的一部分(我稍微简化了它,而且我知道 'test' 不适合作为变量名,但它是临时的)。 我还在这里阅读了 .key 文件,这些文件基本上是包含图像的关键点和描述符的文件(使用 SIFT 提取)。

我只是精确的说,在下面的代码中,featMatch只是我创建的class来创建一个FlannBasedMatcher(带有初始化参数)。

with open(os.path.join(ROOT_DIR,"images\descriptor_list.txt"),'r') as f:
    for line in f:
        folder_path = os.path.join(ROOT_DIR,"images\",line[:-1]+"\","*.key")
        list_key = glob.glob(folder_path)

        test2 = []
        for key in list_key:
            if os.path.isfile(key):
                feat = Features()
                feat.readFromFile(key)
                test = feat.descriptors
                test2 = test2+test
         featMatch.add(test2)

# Read submitted picture features
feat = Features()
feat.readFromFile(os.path.join(ROOT_DIR,"submitted_picture\sub.key"))
matches = []
matches.append(featMatch.knnMatch(np.array(feat.descriptors), k=3))
print(matches)

我期待在查看匹配项时,更具体地说是查看匹配项的 imgIdx 时,根据我添加的描述符集的数量,被告知匹配特征 (trainIdx) 对应于哪个图像索引'add' 方法。

但是按照这个假设,我应该能够让 imgIdx 大于我训练集中的图像(或训练集)的数量。

然而,在这里,我得到了诸如 2960 之类的数字,而我的训练集中只有大约 5 张图像。

我的猜测是它 return 是特征索引而不是图像索引,但我不知道为什么。

我注意到 C++ 中的 'add' 方法接受一个数组数组,其中我们有一个描述符集列表(我猜每个图像一个)。但是在这里我为每个图像设置了不同数量的特征,所以我无法真正创建一个每列中具有不同行数的 numpy 数组。

谢谢。

看了matcher.cpp的C++源码终于搞明白了:

https://github.com/opencv/opencv/blob/master/modules/features2d/src/matchers.cpp

我会 post 答案,以防有一天有人需要它。

我认为 'add' 方法在调用时会增加图像计数,但事实并非如此。所以,我意识到我必须创建一个 Mat 列表(或 python 中的 numpy 数组)并将它一次给 'add',而不是为每个图像调用它。

所以这里是更新的(和工作的)源代码:

with open(os.path.join(ROOT_DIR,"images\descriptor_list.txt"),'r') as f:
    list_image_descriptors = []
    for line in f:
        folder_path = os.path.join(ROOT_DIR,"images\",line[:-1]+"\","*.key")
        list_key = glob.glob(folder_path)

        for key in list_key:
            if os.path.isfile(key):
                feat = Features()
                feat.readFromFile(key)
                img_descriptors = np.array(feat.descriptors)
        list_image_descriptors.append(img_descriptors)
     featMatch.add(list_image_descriptors)

# Read submitted picture features
feat = Features()
feat.readFromFile(os.path.join(ROOT_DIR,"submitted_picture\sub.key"))
matches = []
matches.append(featMatch.knnMatch(np.array(feat.descriptors), k=3))
print(matches)

希望对您有所帮助。