OpenCV 中的 BFMatcher 匹配抛出错误
BFMatcher match in OpenCV throwing error
我正在使用 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 post。给出的解释不完整,inadequate.I 想知道如何解决这个问题。我也使用了 ORB 描述符以及具有 NORM_HAMMING
距离的 BFMatcher。错误再次出现。
任何帮助将不胜感激。
我为此使用的两张图片是:
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
来查找哪个测试图像与哪个查询图像更匹配。您可以检查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。
其他信息
OS: Mac.
Python: 2.7.10.
Opencv: 3.0.0-dev [如果没记错的话,是用brew安装的]。
我发现我遇到了同样的错误。花了一些时间才弄清楚——我的一些图像有点没有特征,因此没有找到关键点,detectAndCompute
返回了 None
的描述符。在传递给 BFMatcher.add()
.
之前,可能值得检查 None
元素的描述符列表
我遇到了同样的错误。但就我而言,这是因为我在 cv2.BFMatcher_create
中使用带有 cv2.NORM_HAMMING
指标的 SIFT。将指标更改为 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).
编辑:使用的版本 Python 3.6、OpenCV 3.4.1
我在准备根据用户选择使用 SIFT 或 ORB 的程序时遇到了很多困难。最后,我可以为 BFMatcher 找到 SIFT 和 ORB
的正确参数
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)
我正在使用 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 post。给出的解释不完整,inadequate.I 想知道如何解决这个问题。我也使用了 ORB 描述符以及具有 NORM_HAMMING
距离的 BFMatcher。错误再次出现。
任何帮助将不胜感激。
我为此使用的两张图片是:
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
来查找哪个测试图像与哪个查询图像更匹配。您可以检查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。
其他信息
OS: Mac.
Python: 2.7.10.
Opencv: 3.0.0-dev [如果没记错的话,是用brew安装的]。
我发现我遇到了同样的错误。花了一些时间才弄清楚——我的一些图像有点没有特征,因此没有找到关键点,detectAndCompute
返回了 None
的描述符。在传递给 BFMatcher.add()
.
None
元素的描述符列表
我遇到了同样的错误。但就我而言,这是因为我在 cv2.BFMatcher_create
中使用带有 cv2.NORM_HAMMING
指标的 SIFT。将指标更改为 cv2.NORM_L1
解决了这个问题。
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 的程序时遇到了很多困难。最后,我可以为 BFMatcher 找到 SIFT 和 ORB
的正确参数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)