Python OpenCV抛出错误中的BFMatcher匹配
我正在使用SURF描述符进行图像匹配。我计划将给定的图像与图像数据库进行匹配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
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的版本 我在准备一个根据用户的选择使用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")
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。