BFMatcher匹配OpenCV抛出错误

时间:2016-10-09 06:38:34

标签: python opencv surf orb

我使用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

错误类似于this帖子。给出的解释是不完整和不充分的。我想知道如何解决这个问题。我已经使用ORB描述符以及距离为NORM_HAMMING的BFMatcher。错误重新出现。 任何帮助将不胜感激。

我用过的两张图片是:

box.png

box.png

box_in_scene.png

box_in_scene.png

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

5 个答案:

答案 0 :(得分:7)

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

root = newNode

在多张图片中搜索

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方法来构建基础数据结构(例如:KdTree将用于在FlannBasedMatcher的情况下进行搜索)。然后,您可以运行train以查找哪个测试图像与哪个查询图像更接近匹配。您可以检查K-d_tree并查看它如何用于搜索多维向量(Surf给出64维向量)。

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

多张图片搜索的代码示例

match

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

请参阅此处的完整示例:Opencv3.0 docs

其他信息

OS:Mac。
Python:2.7.10。
Opencv:3.0.0-dev [如果没记错的话,使用brew安装]。

答案 1 :(得分:3)

我发现我遇到了同样的错误。花了一段时间才弄清楚 - 我的一些图像有点没有特征,因此没有找到关键点,detectAndCompute返回None描述符。在传递给None之前,可能值得检查BFMatcher.add()元素的描述符列表。

答案 2 :(得分:2)

我得到了同样的错误。但就我而言,这是因为我在df[grep("code$", colnames(df))][] <- lapply(df[grep("code$", colnames(df))], function(x) paste0("0", x)) 中使用带有cv2.NORM_HAMMING指标的SIFT。将指标更改为cv2.BFMatcher_create解决了问题。

引用BFMatcher的文档:

  

cv2.NORM_L1 - normTypeNORM_L1NORM_L2NORM_HAMMING中的一个。 NORM_HAMMING2   和L1范数是SIFT和SURF描述符的首选,   L2应与ORB,BRISK和BRIEF NORM_HAMMING一起使用   应在NORM_HAMMING2WTA_K==3时与ORB一起使用(请参阅4构造函数   描述)。

答案 3 :(得分:0)

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

我在准备使用 SIFT ORB 的程序时遇到了很多困难,具体取决于用户的选择。最后,我可以为 SIFT ORB

找到 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)
    
  2. 捕获和处理帧时

    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)
    

答案 4 :(得分:0)

在我使用 ORB 的情况下,问题是它无法找到框架的特征并检查其是否为空。

qImageKeypoints, qImageDescriptors = orb.detectAndCompute(query_img_bw, None)
trainKeypoints, trainDescriptors = orb.detectAndCompute(train_img_bw, None)

if trainDescriptors is None:
    return False
else:
    # check some matching of the two images
    matcher = cv2.BFMatcher(cv2.NORM_HAMMING,crossCheck=False)
    matches = matcher.match(qImageDescriptors, trainDescriptors)