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

shar picture shar · Jul 25, 2015 · Viewed 42.6k times · Source

When I run my python code

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()

From this line

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

I get this error

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

I am using python3 and opencv3

Answer

J Richard Snape picture J Richard Snape · Jul 26, 2015

You seem to be following this tutorial page (based on the code you've shown in this and your two related questions 1, 2).

The function documentation is here (although I note it is still labelled "beta") and implies that outImg is optional. However, the python error message is explicit - an argument is required in position 6, it is named outImg in the function signature. I suspect the documentation may not exactly match the code requirements. It appears that the signature of the C++ code that the python binding is calling has no default value for outImg, so need that argument to be supplied.

Note that you can inspect the doc string for the actual binding in the python3 interpreter (if it exists) by looking at <function_name>.__doc__. In this case, you can see that outImg is not shown as optional. Here is the output from my installation:

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

Solution (note - verified on a windows install, not Linux)

You might note the last example on that tutorial, which uses the following code - passing in None in the place of outImg. I think that will work for your case also.

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)

You don't need to pass all the draw_params dict, you could try just passing flags i.e.

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

I have verified this on a fresh install of OpenCV 3 (albeit on Windows, using a prebuilt binary)