cv2.triangulatePoints 不是很准确吗?

jja*_*per 7 python math opencv computer-vision triangulation

概括

我正在尝试对两张图像中的点进行三角测量,但根本没有得到准确的结果。

细节

这就是我正在做的:

  1. 测量现实世界坐标中的 16 个物点。

  2. 确定每幅图像 16 个物点的像素坐标。

  3. 使用 cv2.solvePnP() 获取每个摄像机的 tvec 和 rvec。

  4. 使用 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)
  5. 验证完毕后,使用以下公式获取旋转矩阵:

    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)
  6. 在进行三角测量之前,使用 cv2.unactorPoints 取消扭曲点。例如:

    left_undist = cv2.undistortPoints(left_points, 
                                       cameraMatrix=left_intrinsics,
                                       distCoeffs=left_distortion)
    
    Run Code Online (Sandbox Code Playgroud)
  7. 对点进行三角测量。例如:

    # 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

问题解决了!