如何使用鱼眼相机参数解决PnP问题?

3

我发现OpenCV的solvePnP()函数假设你的相机参数来自针孔模型。但是我使用了cv.fisheye模块对我的相机进行了校准,因此我想知道如何使用从这个fisheye模块获取的参数和solvePnP一起使用。

我该如何在solvePnP()中使用我的鱼眼相机参数?

1个回答

6
根据 docs.opencv.org,你可以从 cv::fisheye::calibrate() 获得 {K, D, rvecs, tvecs}。
你可以使用 cv.fisheye.undistortPoints() 从输入坐标 distorted 中消除 K 和 D 的影响,详见 here
所以程序应该是:
  1. undistorted = cv.fisheye.undistortPoints(distorted,K,D)
  2. cv.solvePnP(objPoints, undistorted,I,D),其中 I=np.eye(3),D=np.zeros((1,5))
祝你好运。

我怎样才能确信这会起作用呢?我看到在内部,solvePnP使用的是cv.undistortPoints而不是cv.fisheye.undistortPoints。我尝试使用相同的参数评估这两个函数,它们返回不同的结果(即使使用np.eye(3)和np.zeros((1,5))作为相机参数)。这些函数需要使用相同的输出来识别相机矩阵吗? - off99555
1
看起来解决方案是有效的。虽然我不明白为什么它有效。我的证明方法是通过实验。这个想法是从物体姿态到图像点,然后再回到物体姿态。看看物体姿态是否被保留。我生成了一个随机的rvectvec,做了imgpoints = cv.fisheye.projectPoints(objectPoints,rvec,tvec,K,D),然后使用imgpoints做了如答案所述的solvePnP。通过实验得到的输出rvectvec与原始旋转和平移非常接近(有1e-7的误差)。所以这是通过实验证明它有效的! - off99555
很高兴听到它能正常工作。cv.fishey中的相机模型使用了不同的镜头畸变模型,与docs.opencv.org中发现的不同,因此应该使用cv.fisheye.undistortPoints()来消除畸变效果。 - Yongduek Seo
我知道你应该使用cv.fisheye.undistortPoints()来消除畸变效果。但我不明白为什么cv.undistortPoints(imgpoints, np.eye(3), np.zeros(4))不等于cv.fisheye.undistortPoints(imgpoints, np.eye(3), np.zeros(4))。第一个函数对我来说很有意义,它返回与imgpoints相同的值。但第二个函数返回了我不理解的不同的东西。为什么它们都没有返回imgpoints - off99555
有趣的是探究为什么。原因很简单,就是由于OpenCV中鱼眼镜头畸变模型的计算过程,这也让我非常好奇;这与正常的针孔投影情况相当不同。相关的stackoverflow问答可以在此处找到。 - Yongduek Seo
太好了!这帮助我理解了鱼眼相机模型,以及为什么我们应该使用空的“I”和“D”参数通过无畸变图像来解决PnP问题。再次感谢! - Yuanhui

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