OpenCV 中的 BFMatcher 匹配抛出错误

新手上路,请多包涵

我正在使用 SURF 描述符进行图像匹配。我计划将给定图像与图像数据库相匹配。

 import cv2
import numpy as np
surf = cv2.xfeatures2d.SURF_create(400)

img1 = cv2.imread('box.png',0)
img2 = cv2.imread('box_in_scene.png',0)

kp1,des1 = surf.detectAndCompute(img1,None)
kp2,des2 = surf.detectAndCompute(img2,None)

bf = cv2.BFMatcher(cv2.NORM_L1,crossCheck=True)
#I am planning to add more descriptors
bf.add(des1)

bf.train()

#This is my test descriptor
bf.match(des2)

问题在于 bf.match 是我收到以下错误:

 OpenCV Error: Assertion failed (type == src2.type() && src1.cols == src2.cols && (type == CV_32F || type == CV_8U)) in batchDistance, file /build/opencv/src/opencv-3.1.0/modules/core/src/stat.cpp, line 3749
Traceback (most recent call last):
  File "image_match4.py", line 16, in <module>
    bf.match(des2)
cv2.error: /build/opencv/src/opencv-3.1.0/modules/core/src/stat.cpp:3749: error: (-215) type == src2.type() && src1.cols == src2.cols && (type == CV_32F || type == CV_8U) in function batchDistance

错误类似于 这篇 文章。给出的解释不完整和不充分。我想知道如何解决这个问题。我也使用了 ORB 描述符以及具有 NORM_HAMMING 距离的 BFMatcher。错误再次出现。任何帮助将不胜感激。

我为此使用的两个图像是:

盒子.png

盒子.png

box_in_scene.png

box_in_scene.png

我在 Linux 中使用 Python 3.5.2 和 OpenCV 3.1.x。

原文由 motiur 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 1.4k
2 个回答

要在两个图像的描述符之间搜索,请 使用:

 img1 = cv2.imread('box.png',0)
img2 = cv2.imread('box_in_scene.png',0)

kp1,des1 = surf.detectAndCompute(img1,None)
kp2,des2 = surf.detectAndCompute(img2,None)

bf = cv2.BFMatcher(cv2.NORM_L1,crossCheck=False)
matches = bf.match(des1,des2)

在多个图像中搜索

add 方法用于添加多个测试图像的描述符。一旦所有描述符都被索引,您就可以运行 train 方法来构建底层数据结构(例如:KdTree,在 FlannBasedMatcher 的情况下将用于搜索)。然后您可以运行 match 来查找哪个测试图像与哪个查询图像更匹配。您可以检查 K-d_tree 并了解如何使用它来搜索多维向量(Surf 给出 64 维向量)。

注意:- BruteForceMatcher,顾名思义,没有内部搜索优化数据结构,因此具有空的 train 方法。

多图像搜索的代码示例

import cv2
import numpy as np
surf = cv2.xfeatures2d.SURF_create(400)

# Read Images
train = cv2.imread('box.png',0)
test = cv2.imread('box_in_scene.png',0)

# Find Descriptors
kp1,trainDes1 = surf.detectAndCompute(train, None)
kp2,testDes2  = surf.detectAndCompute(test, None)

# Create BFMatcher and add cluster of training images. One for now.
bf = cv2.BFMatcher(cv2.NORM_L1,crossCheck=False) # crossCheck not supported by BFMatcher
clusters = np.array([trainDes1])
bf.add(clusters)

# Train: Does nothing for BruteForceMatcher though.
bf.train()

matches = bf.match(testDes2)
matches = sorted(matches, key = lambda x:x.distance)

# Since, we have index of only one training image,
# all matches will have imgIdx set to 0.
for i in range(len(matches)):
    print matches[i].imgIdx

对于 bf.match 的 DMatch 输出,请参阅 文档

请在此处查看完整示例: Opencv3.0 文档

其他信息

操作系统:Mac。

蟒蛇:2.7.10。

Opencv: 3.0.0-dev [如果没记错的话,是用brew安装的]。

原文由 saurabheights 发布,翻译遵循 CC BY-SA 3.0 许可协议

编辑:使用 Python 3.6、OpenCV 3.4.1 的版本

在准备根据用户选择使用 SIFTORB 的程序时,我费了很大劲。最后,我可以为 SIFTORB 找到 BFMatcher 的正确参数

import cv2
import numpy as np

# ask user whether to use SIFT or ORB
detect_by = input("sift or orb")
  1. 创建匹配器对象
   if detect_by == "sift":
       matcher = cv2.BFMatcher(normType=cv2.NORM_L2, crossCheck=False)

   elif detect_by is "orb":
       matcher = cv2.BFMatcher(normType=cv2.NORM_HAMMING, crossCheck=False)

  1. 在捕获和处理帧时
   while there_is_frame_to_process:
       if detect_by is "sift":
           matches = matcher.knnMatch(np.asarray(gray_des, np.float32), np.asarray(target_des, np.float32), k=2)

       elif detect_by is "orb":
           matches = matcher.knnMatch(np.asarray(gray_des, np.uint8), np.asarray(target_des, np.uint8), k=2)

原文由 Ali Eren Çelik 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题