如何在OpenCV中估计两个摄像机的位置?

5

我有两张图像中的对应点集。我已经估计出了基本矩阵,它编码了相机之间的变换:

E, mask = cv2.findEssentialMat(points1, points2, 1.0)

我随后提取了旋转和平移组件:

points, R, t, mask = cv2.recoverPose(E, points1, points2)

但是我应该如何获取两个相机的矩阵,以便使用cv2.triangulatePoints生成一个小的点云呢?


你到底尝试了什么? - DisappointedByUnaccountableMod
@barny 我能想到的唯一可能是你无法获取相机的位置,因此你必须假设一个相机是3x4的零矩阵,而另一个相机是R | t。 - nickponline
问题的标题和被接受的答案不匹配。可能应该将标题更改为如何从两个视图估计相机姿态。估计相机位置至少需要一个步骤,其中一个相机被假定在原点,另一个相机的相对位置被估计。 - abggcv
1个回答

12
这是我做的事情:
输入:
pts_l - set of n 2d points in left image. nx2 numpy float array
pts_r - set of n 2d points in right image. nx2 numpy float array

K_l - Left Camera matrix. 3x3 numpy float array
K_r - Right Camera matrix. 3x3 numpy float array

代码:

# Normalize for Esential Matrix calaculation
pts_l_norm = cv2.undistortPoints(np.expand_dims(pts_l, axis=1), cameraMatrix=K_l, distCoeffs=None)
pts_r_norm = cv2.undistortPoints(np.expand_dims(pts_r, axis=1), cameraMatrix=K_r, distCoeffs=None)

E, mask = cv2.findEssentialMat(pts_l_norm, pts_r_norm, focal=1.0, pp=(0., 0.), method=cv2.RANSAC, prob=0.999, threshold=3.0)
points, R, t, mask = cv2.recoverPose(E, pts_l_norm, pts_r_norm)

M_r = np.hstack((R, t))
M_l = np.hstack((np.eye(3, 3), np.zeros((3, 1))))

P_l = np.dot(K_l,  M_l)
P_r = np.dot(K_r,  M_r)
point_4d_hom = cv2.triangulatePoints(P_l, P_r, np.expand_dims(pts_l, axis=1), np.expand_dims(pts_r, axis=1))
point_4d = point_4d_hom / np.tile(point_4d_hom[-1, :], (4, 1))
point_3d = point_4d[:3, :].T

输出:

point_3d - nx3 numpy array

1
谢谢Yonathan,你上面提到的pts_l和pts_r是正确的吗?pts_l是左图像中的2D点,是一个nx3的numpy浮点数组。pts_r是右图像中的2D点,也是一个nx3的numpy浮点数组。 - Salih Karagoz
1
是的。但请注意,我更喜欢始终指定左边和右边,而不是数字。这样减少混淆的机会。 - Yonatan Simson
1
不好意思,如果这是一个愚蠢的问题,但是你如何得到K_LK_R - jihan1008
1
@jihan1008 你需要使用已校准的相机数据或自己对相机进行校准。如何校准内参?请参考以下链接:https://opencv-python-tutroals.readthedocs.io/en/latest/py_tutorials/py_calib3d/py_calibration/py_calibration.html - Yonatan Simson
1
好的,明白了。谢谢! - Radwa Khattab
显示剩余4条评论

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