solvePnPRansac 返回的 rvecs 和 tvecs 为零值

2 投票
2 回答
2228 浏览
提问于 2025-04-18 07:52

我想找出我相机的旋转和位移向量。

但是,文档中的solvePnPRansac方法给出的结果都是零矩阵;它只返回了角点的值。

 print corners
[[[ 372.48184204   80.71842194]]
 [[ 374.40280151  103.50676727]]
 [[ 377.49230957  128.53459167]]
      ... so on till ..
 [[ 204.40803528  168.18978882]]
 [[ 203.94168091  193.23649597]]
 [[ 204.39024353  220.48114014]]
 [[ 204.54725647  248.10583496]]]

我使用了文档中的代码,并根据我的棋盘进行了修改。

criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 30, 0.001)
objp = np.zeros((7*7,3), np.float32)
objp[:,:2] = np.mgrid[0:7,0:7].T.reshape(-1,2)
axis = np.float32([[3,0,0], [0,3,0], [0,0,-3]]).reshape(-1,3)

for fname in glob.glob('../Right*.jpg'):
      img = cv2.imread(fname)
      gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
      ret, corners = cv2.findChessboardCorners(gray, (7,7),None)
      print ret,corners #ret is true and corners returns an array
      if ret == True:
        # Find the rotation and translation vectors.
         rvecs, tvecs , inliers = cv2.solvePnPRansac(objp, corners, mtx, dist)

rvecstvecs的结果都是[0,0,0][0,0,0]

2 个回答

0

我遇到了同样的问题——在调用solvePnPRansac之后,rvec和tvec的值都是零。我找到了一种解决办法——用solvePnP来代替solvePnPRansac。对于我用的四个点,这个方法效果很好。不过我的程序是用C++写的,不是Python。在这里有一些我在开发过程中用到的信息,链接是http://docs.opencv.org/trunk/doc/py_tutorials/py_calib3d/py_pose/py_pose.html,不过我想你可能已经知道了。希望这对你有帮助。

1

我在用Python的solvePnPRansac时遇到了同样的问题。solvePnPRansac相比于solvePnP的不同之处在于,它会根据你提供的一组点中选择4个或更多的点来计算rvec和tvec。这个选择是为了确保得到的投影能够很好地适应所有给定的点。如果你选择的点无法得到一个足够好的结果,这个函数就会返回零。

你可以把“reprojectError”的值调高(默认是8)。这样做会允许更大的重投影误差,虽然结果可能不太好,但总比没有结果要好(当然,如果你追求高精度的话就不适合)。比如,你可以试试:

rvecs, tvecs , inliers = cv2.solvePnPRansac(objp, corners, mtx, dist,reprojectionError=10)

最后,补充一下,如果你把reprojectError的值调得很高,以至于所有点都能被考虑进来,并且还能得到一个可以接受的结果,那么你的结果就和使用solvePnP时是一样的。

撰写回答