类型错误:缺少必要参数'outImg' (位置6)

49

当我运行我的Python代码时

import numpy as np
import cv2
import matplotlib.pyplot as plt

img1 = cv2.imread('/home/shar/home.jpg',0)          # queryImage
img2 = cv2.imread('/home/shar/home2.jpg',0) # trainImage

# Initiate SIFT detector

sift = cv2.xfeatures2d.SIFT_create()
# find the keypoints and descriptors with SIFT
kp1, des1 = sift.detectAndCompute(img1,None)
kp2, des2 = sift.detectAndCompute(img2,None)

# BFMatcher with default params
bf = cv2.BFMatcher()
matches = bf.knnMatch(des1,des2, k=2)

# Apply ratio test
good = []
for m,n in matches:
    if m.distance < 0.75*n.distance:
        good.append([m])

# cv2.drawMatchesKnn expects list of lists as matches.
img3 = cv2.drawMatchesKnn(img1,kp1,img2,kp2,good,flags=2)


plt.imshow(img3),plt.show()

从这一行开始

img3 = cv2.drawMatchesKnn(img1,kp1,img2,kp2,good,flags=2)

我遇到了这个错误

TypeError: Required argument 'outImg' (pos 6) not found

我正在使用Python3和OpenCV3。


我想象outImg应该是一个numpy数组。 - Padraic Cunningham
它的签名是 cv2.drawMatches(img1, keypoints1, img2, keypoints2, matches1to2[, outImg[, matchColor[, singlePointColor[, matchesMask[, flags]]]]]),因此我推测如果您指定了 flags,则需要同时指定所有先前的参数。 - Pynchia
2
我认为文档是错误/误导的。我已经根据OP发现的问题在OpenCV GitHub上创建了一个问题(https://github.com/Itseez/opencv/issues/4237)。 - J Richard Snape
一个小提示 - 工厂方法 cv2.BFMatcher_create() 已经取代了默认的 cv2.BFMatcher()根据官方文档 - Zhanwen Chen
4个回答

82

根据您展示的代码和相关问题12,您似乎正在遵循此教程页面

函数文档在此处(虽然我注意到它仍标为“beta”),并暗示outImg是可选的。然而,Python错误消息是明确的——第6个位置需要一个参数,函数签名中命名为outImg。我怀疑文档可能不完全符合代码要求。看起来C++代码的签名,也就是Python调用的代码绑定没有给outImg提供默认值,因此需要提供该参数。

请注意,您可以在Python3解释器中查看实际绑定的doc字符串(如果存在)<function_name>.__doc__。在这种情况下,您可以看到outImg不被显示为可选项。以下是我的安装输出:

>>> cv2.drawMatchesKnn.__doc__
'drawMatchesKnn(img1, keypoints1, img2, keypoints2, matches1to2, outImg[, matchC
olor[, singlePointColor[, matchesMask[, flags]]]]) -> outImg'

解决方案(注意-在Windows安装中验证,而不是Linux)

您可能会注意到该教程上的最后一个示例,它使用以下代码,在outImg位置传入None。我认为这对于您的情况也可以起作用。

draw_params = dict(matchColor = (0,255,0),
                   singlePointColor = (255,0,0),
                   matchesMask = matchesMask,
                   flags = 0)

img3 = cv2.drawMatchesKnn(img1,kp1,img2,kp2,matches,None,**draw_params)

您无需传递所有的draw_params字典,只需尝试传递flags即可。

img3 = cv2.drawMatchesKnn(img1,kp1,img2,kp2,matches,None,flags=2)

我已经在安装了OpenCV 3的全新环境中进行了验证(虽然是在Windows上使用预编译二进制文件)


NameError: 名称'matchesMask'未定义 - shar
1
好的 - 这有点简洁,说实话。如果你尝试使用代码的第一个版本 - 即使用draw_params,那么你当然必须定义自己的matchesMask。不过,在那之下我提供了一个选项,它不要求你使用draw_params。用我的答案中最后一行替换你当前调用的drawMatchesKnn()即可 - 忽略教程中以 draw_params 开头的引用代码。我为完整性包含了它,但意识到它可能会让人困惑。另请参阅我在回答你其他问题时提供的示例。 - J Richard Snape
1
在Linux Mint 17.3 Cinnamon上验证,使用OpenCV 2.4.9。感谢@JRichardSnape的帮助。 - Kanishka Ganguly
1
已验证可在macOS 10.12 Sierra和OpenCV 3.2.0上运行。有效! - maephisto
收到此错误:SystemError:<built-in function drawMatchesKnn>返回NULL而未设置错误。 - john

17

好的,大家好,我也是一个新手,在经过数小时的在线研究后,似乎出现了一个名为Error(-255) NumpyAllocator的错误,许多网站建议你打开cv2.cpp文件并注释掉163行代码。我的建议是,如果您正在使用OpenCV 3.1,请降级到OpenCV 3.0.0。

这个bug似乎存在于OpenCV 3.1中,此外,在使用ORB算法的代码中,OpenCV.org上的文档有些过时,其中指出:

enter code here#启动ORB检测器 enter code hereorb = cv2.ORB() # 注意,由于现在情况已经改变,您将会收到一个错误,请将其更改为: enter code hereorb = cv2.ORB_create()

以下是我在Windows 10上使用OpenCV 3.0.0的代码示例:

  # Example of Brute Force matching base on ORB Algorithm
  #Modify Author : Waheed Rafiq R&D student Birmingham City University UK
  #Original author : OpenCV.org
  #Date Updated : 21/04/2016 : 13:45 

  import numpy as np
  import cv2
  from matplotlib import pyplot as plt 

  img1 = cv2.imread('wr-pb.jpg',0)          # queryImage
  img2 = cv2.imread('Waheed.jpg',0) # trainImage

  # Initiate ORB detector
  orb = cv2.ORB_create()

  # find the keypoints and descriptors with ORB
  kp1, des1 = orb.detectAndCompute(img1,None)
  kp2, des2 = orb.detectAndCompute(img2,None)

  # create BFMatcher object
  bf = cv2.BFMatcher(cv2.NORM_HAMMING, crossCheck=True)

 # Match descriptors.
 matches = bf.match(des1,des2)

 # Sort them in the order of their distance.
 matches = sorted(matches, key = lambda x:x.distance)

 # Draw first 10 matches.
 img3 = cv2.drawMatches(img1,kp1,img2,kp2,matches ,None, flags=2)

 plt.imshow(img3),plt.show()

我希望这可以帮到你,我喜欢Stack Overflow,它是互联网上最好的资源。


谢谢。它在Linux上使用OpenCV 3和Python 3可以工作。 - Y.E.S.

3

我的代码:img3 = cv2.drawMatchesKnn(img1, kp1, img2, kp2, good, flags=2)

在加入关键词和参数“None”后,这段代码可以正常运行:img3 = cv2.drawMatches(img1,kp1,img2,kp2,matches ,None, flags=2)


0

这很可能是一个bug。你可以做的是将第六个参数传递为None

img3 = cv2.drawMatchesKnn(img1,kp1,img2,kp2,good,flags=2,None)

我在尝试使用SIFT时遇到了类似的问题。当我将None用作参数时,问题得以解决。


不确定为什么这个被踩了,因为它对我来说是有效的。 - 6infinity8
无法在关键字参数后传递位置参数,这是语法错误。 - Mahesh

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接