Python OpenCV抛出错误中的BFMatcher匹配

Python OpenCV抛出错误中的BFMatcher匹配,python,opencv,surf,orb,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.detectAn

我正在使用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
OpenCV错误:在batchDistance文件/build/OpenCV/src/OpenCV-3.1.0/modules/core/src/stat.cpp第3749行中,断言失败(type==src2.type()&&src1.cols==src2.cols&&type==cv32f | | type==CV 8U))
回溯(最近一次呼叫最后一次):
文件“image_match4.py”,第16行,在
bf.匹配(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==cv8u)在函数batchDistance中
错误与post类似。我想知道如何解决这个问题。我使用了ORB描述符以及BFMatcher的
NORM\u HAMMING
距离。错误再次出现。 任何帮助都将不胜感激

我在这里使用的两个图像是:

box.png

box_in_scene.png


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

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

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
,查找哪个测试图像与哪个查询图像是否更匹配。您可以检查并查看如何使用它来搜索多维向量(Surf提供64维向量)

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

多图像搜索代码示例

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输出,请参阅

请参阅此处的完整示例:

其他信息

操作系统:Mac。
Python:2.7.10.

Opencv:3.0.0-dev[如果记得正确,请使用brew安装]

我发现我也犯了同样的错误。花了一段时间才弄明白-我的一些图像有些没有特征,因此没有找到关键点,并且
detectAndCompute
为描述符返回了
None
。在传递到
BFMatcher.add()
之前,可能值得检查
None
元素的描述符列表。我收到了相同的错误。但在我的例子中,这是因为我在
cv2.BFMatcher\u create
中使用SIFT和
cv2.NORM\u HAMMING
度量。将度量更改为
cv2.NORM\u L1
解决了该问题

引用以下文件:

normType
–属于
NORM\u L1
NORM\u L2
NORM\u HAMMING
NORM\u HAMMING 2
之一<代码>L1 对于SIFT和SURF描述符,
L2
规范是更好的选择,
NORM\u-HAMMING
应与ORB一起使用,轻快简洁,
NORM\u-HAMMING 2
WTA_K==3
4
时,应与ORB一起使用(请参见
ORB::ORB
构造函数 说明)


编辑:使用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")
  • 创建匹配器对象

    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)
    
  • 在捕获和处理帧时

    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)
    

  • 在我使用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)
    

    我使用它的多个图像。上面的代码是最简单的版本。您给出的示例代码适用于两个图像。我想将一个图像的描述符与多个图像的描述符列表进行比较。问题就在那里。对不起,我错过了。给我一点时间看看这个问题。我想我问的是类似的问题:嗨,我面临着同样的错误。一切似乎都很好。顺便说一句,BruteForceMatcher并没有真正出现,因为它并没有训练。我还尝试了FlannMatcher(因为我的项目使用了FlannMatcher/C++),但遇到了这个opencv错误:那么
    。检测和计算
    会出现在opencv 3x和更高版本中吗?我使用的是2.4,它说
    找不到模块对象
    …这取决于opencv版本。遵循2.4或3.x。