jja*_*per 7 python math opencv computer-vision triangulation
概括
我正在尝试对两张图像中的点进行三角测量,但根本没有得到准确的结果。
细节
这就是我正在做的:
测量现实世界坐标中的 16 个物点。
确定每幅图像 16 个物点的像素坐标。
使用 cv2.solvePnP() 获取每个摄像机的 tvec 和 rvec。
使用 cv2.projectPoints 验证 tvecs 和 rvecs 是否将给定的 3D 点重新投影到正确的图像坐标(它确实有效)。例如:
img_point_right = cv2.projectPoints(np.array([[0,0,39]], np.float),
right_rvecs,
right_tvecs,
right_intrinsics,
right_distortion)
Run Code Online (Sandbox Code Playgroud)
验证完毕后,使用以下公式获取旋转矩阵:
left_rotation, jacobian = cv2.Rodrigues(left_rvecs)
right_rotation, jacobian = cv2.Rodrigues(right_rvecs)
Run Code Online (Sandbox Code Playgroud)
然后是投影矩阵:
RT = np.zeros((3,4))
RT[:3, :3] = left_rotation
RT[:3, 3] = left_translation.transpose()
left_projection = np.dot(left_intrinsics, RT)
RT = np.zeros((3,4))
RT[:3, :3] = right_rotation
RT[:3, 3] = right_translation.transpose()
right_projection = np.dot(right_intrinsics, RT)
Run Code Online (Sandbox Code Playgroud)
在进行三角测量之前,使用 cv2.unactorPoints 取消扭曲点。例如:
left_undist = cv2.undistortPoints(left_points,
cameraMatrix=left_intrinsics,
distCoeffs=left_distortion)
Run Code Online (Sandbox Code Playgroud)
对点进行三角测量。例如:
# Transpose to get into OpenCV's 2xN format.
left_points_t = np.array(left_undist[0]).transpose()
right_points_t = np.array(right_undist[0]).transpose()
# Note, I take the 0th index of each points matrix to get rid of the extra dimension,
# although it doesn't affect the output.
triangulation = cv2.triangulatePoints(left_projection, right_projection, left_points_t, right_points_t)
homog_points = triangulation.transpose()
euclid_points = cv2.convertPointsFromHomogeneous(tri_homog)
Run Code Online (Sandbox Code Playgroud)
不幸的是,当我得到最后一步的输出时,尽管我试图重现具有正 Z 位置的 3D 点,但我的点甚至没有正 Z 方向。
作为参考,正 Z 为向前,正 Y 为向下,正 X 为右。
例如,3D 点(0, 0, 39)(想象一下您面前 39 英尺处的一个点)给出的三角测量输出为(4.47, -8.77, -44.81)
问题
这是对点进行三角测量的有效方法吗?
如果是这样, cv2.triangulatePoints 是否不是一种对点进行三角测量的好方法以及替代方案的任何建议?
感谢您的帮助。
jja*_*per 10
好吧,事实证明,如果我undistortPoints在调用函数之前不调用该函数triangulatePoints,那么我会得到合理的结果。这是因为undistortPoints在执行不失真时使用内在参数对点进行归一化,但随后我仍然使用triangulatePoints考虑内在参数的投影矩阵进行调用。
然而,通过不扭曲点,然后调用使用单位矩阵作为内在矩阵构建的投影矩阵,我可以获得更好的结果。triangulatePoints
问题解决了!