OpenCV投掷中的BFMatcher匹配

2024-10-01 00:23:42 发布

您现在位置:Python中文网/ 问答频道 /正文

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

错误类似于thispost。我想知道如何解决这个问题。我也使用了ORB描述符和具有NORM_HAMMING距离的BFMatcher。错误再次出现。 任何帮助都将不胜感激。

我使用的两个图像是:

box.png

方框.png

box_in_scene.png

box_in_scene.png中的box_

我在linux中使用Python 3.5.2和opencv3.1.x。


Tags: in图像srcboxpngtypematchcv2
3条回答

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

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

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顾名思义,没有内部搜索优化数据结构,因此具有空列方法。

多图像搜索的代码示例

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

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

其他信息

操作系统:Mac。
Python:2.7.10.
Opencv:3.0.0-dev[如果记住正确,请使用brew安装]。

我也犯了同样的错误。但在我的例子中,这是因为我在使用SIFT和cv2.NORM_HAMMING度量。将度量更改为cv2.NORM_L1解决了这个问题。

引用BFMatcher的文档:

normType – One of NORM_L1, NORM_L2, NORM_HAMMING, NORM_HAMMING2. L1 and L2 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 when WTA_K==3 or 4 (see ORB::ORB constructor description).

相关问题 更多 >