0

After I have generated the Fundamental and Essential Matrix from Camera calibration, I am trying to get the Epipolar lines, and draw them in my images to test the Matrix I have generated, following this python-opencv tutorial

Here is the code for impelementing the drawing epipolar lines function:

    def drawlines(img1,img2,lines,pts1,pts2):
        ''' img1 - image on which we draw the epilines for the points in img2
            lines - corresponding epilines 
        '''
        r,c = img1.shape
        img1 = cv2.cvtColor(img1,cv2.COLOR_GRAY2BGR)
        img2 = cv2.cvtColor(img2,cv2.COLOR_GRAY2BGR)
        for r,pt1,pt2 in zip(lines,pts1,pts2):
            color = tuple(np.random.randint(0,255,3).tolist())
            x0,y0 = map(int, [0, -r[2]/r[1] ])
            x1,y1 = map(int, [c, -(r[2]+r[0]*c)/r[1] ])
            img1 = cv2.line(img1, (x0,y0), (x1,y1), color,1)
            img1 = cv2.circle(img1,tuple(pt1),5,color,-1)
            img2 = cv2.circle(img2,tuple(pt2),5,color,-1)
        return img1,img2

but when I run the following code to generate the epipolar lines, I got this error:

Traceback (most recent call last): File "FundMat.py", line 124,
in img5,img6 = drawlines(img1,img2,lines1,pts1,pts2) File "FundMat.py", line 21, in drawlines img1 = cv2.circle(img1,tuple(pt1),5,color,-1)
TypeError: function takes exactly 2 arguments (1 given)

So, why I got this error and how to solve it?

alkasm
  • 22,094
  • 5
  • 78
  • 94
Kamal El-Saaid
  • 145
  • 2
  • 11
  • You only included a version-specific tag for OpenCV instead of the general `opencv` tag which means your question got lost in the abyss. Answerers on Stack subscribe to certain tags so they can easily find questions, and version specific ones are far less popular. Feel free to tag with version specific tags if you feel the issue might be related to the version, but always include the general one for exposure so more people actually see your question. This is why no one answered this question though it is a simple fix. – alkasm Dec 04 '17 at 08:04

1 Answers1

1

Your points are in a different format than OpenCV wants. Your pt1 and pt2 probably look something like np.array([[x, y]]), but look what the tuple looks like when you cast it:

>>> pt1 = np.array([[50, 50]])
>>> tuple(pt1)
(array([50, 50]),)

This is a tuple with a single element, instead of two items like you expect. Obviously for drawing, it wants a tuple with length 2 (namely, the x and y coordinates). Hence the error; the inner function expects two arguments but only one value was inside your tuple. To demonstrate:

>>> pt1 = np.array([[50, 50]])
>>> cv2.circle(img, tuple(pt1), 5, 255, -1)
Traceback (most recent call last):  
  File "...", line 10, in <module>  
    cv2.circle(img, tuple(pt1), 5, 255, -1) TypeError: function takes exactly 2 arguments (1 given)

Instead, this is what you want the tuple to look like:

>>> tuple(pt1[0])
(50, 50)

Supposing you want to be able to handle points passed in either format, just reshape the point first. Either way you only have two values in the pt1 or pt2 arrays, so reshaping won't affect it. For e.g. you could use flatten() from numpy:

>>> tuple(pt1.flatten())
(50, 50)

And this should fix your issue.

>>> pt1 = np.array([[50, 50]])
>>> cv2.circle(img, tuple(pt1.flatten()), 5, 255, -1)
>>> 
alkasm
  • 22,094
  • 5
  • 78
  • 94