无法使用 opencv 和 python 在相机校准和 3D 重建中绘制对极线
Can't draw the epipolar lines in camera calibration and 3D- reconstruction using opencv & python
在我从相机校准生成基本矩阵和基本矩阵后,我试图获取对极线,并将它们绘制在我的图像中以测试我生成的矩阵,然后 python-opencv tutorial
下面是实现绘制极线功能的代码:
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
但是当我运行下面的代码生成对极线时,我得到了这个错误:
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)
那么,为什么会出现此错误以及如何解决?
您的点的格式与 OpenCV 想要的格式不同。你的 pt1
和 pt2
可能看起来像 np.array([[x, y]])
,但看看当你转换它时元组的样子:
>>> pt1 = np.array([[50, 50]])
>>> tuple(pt1)
(array([50, 50]),)
这是一个只有一个元素的元组,而不是你期望的两个元素。显然对于绘图,它需要一个长度为 2 的元组(即 x
和 y
坐标)。因此错误;内部函数需要 两个 个参数,但元组中只有一个值。演示:
>>> 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)
相反,这就是您希望元组的样子:
>>> tuple(pt1[0])
(50, 50)
假设您希望能够处理以任一格式传递的点,只需先重塑该点。无论哪种方式,您在 pt1
或 pt2
数组中只有两个值,因此重塑不会影响它。例如你可以使用 numpy 中的 flatten()
:
>>> tuple(pt1.flatten())
(50, 50)
这应该可以解决您的问题。
>>> pt1 = np.array([[50, 50]])
>>> cv2.circle(img, tuple(pt1.flatten()), 5, 255, -1)
>>>
在我从相机校准生成基本矩阵和基本矩阵后,我试图获取对极线,并将它们绘制在我的图像中以测试我生成的矩阵,然后 python-opencv tutorial
下面是实现绘制极线功能的代码:
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
但是当我运行下面的代码生成对极线时,我得到了这个错误:
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)
那么,为什么会出现此错误以及如何解决?
您的点的格式与 OpenCV 想要的格式不同。你的 pt1
和 pt2
可能看起来像 np.array([[x, y]])
,但看看当你转换它时元组的样子:
>>> pt1 = np.array([[50, 50]])
>>> tuple(pt1)
(array([50, 50]),)
这是一个只有一个元素的元组,而不是你期望的两个元素。显然对于绘图,它需要一个长度为 2 的元组(即 x
和 y
坐标)。因此错误;内部函数需要 两个 个参数,但元组中只有一个值。演示:
>>> 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)
相反,这就是您希望元组的样子:
>>> tuple(pt1[0])
(50, 50)
假设您希望能够处理以任一格式传递的点,只需先重塑该点。无论哪种方式,您在 pt1
或 pt2
数组中只有两个值,因此重塑不会影响它。例如你可以使用 numpy 中的 flatten()
:
>>> tuple(pt1.flatten())
(50, 50)
这应该可以解决您的问题。
>>> pt1 = np.array([[50, 50]])
>>> cv2.circle(img, tuple(pt1.flatten()), 5, 255, -1)
>>>