BFMatcher match in OpenCV throwing error
我正在使用 SURF 描述符进行图像匹配。我打算将给定的图像与图像数据库进行匹配。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | 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) |
1 2 3 4 5 | 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 描述符以及具有
任何帮助将不胜感激。
我使用的两张图片是:
box.png
box_in_scene.png
我在 linux 中使用 Python 3.5.2 和 OpenCV 3.1.x。
要在两个图像的描述符之间进行搜索,请使用:
1 2 3 4 5 6 7 8 9 | 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) |
在多个图像中搜索
注意:- 顾名思义,BruteForceMatcher 没有内部搜索优化数据结构,因此具有空训练方法。
多图像搜索的代码示例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | 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 docs.
其他信息
操作系统:Mac。
Python:2.7.10。
Opencv:3.0.0-dev [如果没记错,使用 brew 安装]。
我遇到了同样的错误。但就我而言,这是因为我在
BFMatcher 的引用文档:
normType – One ofNORM_L1 ,NORM_L2 ,NORM_HAMMING ,NORM_HAMMING2 .L1
andL2 norms are preferable choices for SIFT and SURF descriptors,
NORM_HAMMING should be used with ORB, BRISK and BRIEF,NORM_HAMMING2
should be used with ORB whenWTA_K==3 or4 (seeORB::ORB constructor
description).
我发现我遇到了同样的错误。花了一段时间才弄明白——我的一些图像有些无特色,因此没有找到关键点,
之前,可能值得检查
编辑:版本使用 Python 3.6、OpenCV 3.4.1
根据用户的选择,我在准备使用 SIFT 或 ORB 的程序时费了很大力气。最后,我可以为 SIFT 和 ORB
找到正确的 BFMatcher 参数
1 2 3 4 5 | import cv2 import numpy as np # ask user whether to use SIFT or ORB detect_by = input("sift or orb") |
创建匹配对象
1 2 3 4 5 | 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 2 3 4 5 6 | 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 的情况下,问题是它找不到框架的特征并检查它是否为空。
1 2 3 4 5 6 7 8 9 | 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) |