solvePnP和calibrateCamera在OpenCV中有什么区别?

14

calibrateCamera()函数提供rvectvecdistCoeffcameraMatrix,而solvePnP()函数则将cameraMatrixdistCoeff作为输入,并提供rvectvec作为输出。这两个函数之间有什么区别?

3个回答

25

cv::calibrateCamera(...)

该函数从标定板的多个视图中估计单目相机的以下参数。该标定板的几何形状通常是已知的(例如棋盘):

  • 线性内参数: 以像素为单位的焦距(基本上是缩放因子),主点理论上应在图像中心,有时还有x和y轴之间的偏斜系数(但通常为零)。
  • 非线性内参数: 前面提到的参数构成线性相机矩阵,但在从三维相机转换到二维图像平面的变换中还有一些非线性参数,即镜头畸变。
  • 外参数: 三维世界坐标系与三维相机坐标系之间的变换矩阵。

上述参数的估计通常基于二维-三维对应。该算法检测图像(例如棋盘)中的一些2D点,并指定相应的3D物体点(已知3D几何形状)。在最简单的情况下它执行以下步骤(可以根据 cv::calibrateCamera(..., int flags, ...) 的标志而有所不同):

  • 计算线性内参数,并将非线性内参数视为零。
  • 根据近似的内参数估计初始相机姿态(外参数)。这是使用 cv::solvePnP(...)完成的。
  • 执行Levenberg-Marquardt优化算法,以最小化检测到的2D图像点与3D物体点的2D投影之间的重投影误差。这是使用 cv::projectPoints(...) 完成的。

cv::solvePnP(...)

在这里,我已经隐含回答了cv::solvePnP(...)的角色,因为它是cv::calibrateCamera(...)的一部分。一旦你有了相机的内参,你可以假设这些参数永远不会改变(除非你改变光学或变焦)。另一方面,外参可以更改,例如你可以旋转相机或将其放置到另一个位置。你应该看到在这种情况下,改变物体姿态到相机的场景非常相似。而这正是cv::solvePnP(...)所用的。

该函数给出了以下物体姿态的估计:

  • 模型坐标系中一组三维物体点(也可以是三维世界),
  • 它们在图像平面上的二维投影,
  • 线性和非线性内参参数。

cv::solvePnP(...)的输出是一个旋转向量(rvec)和一个平移向量(tvec),将三维物体点从模型坐标系变换到三维相机坐标系。


1
很好的解释。我可以直接使用calibrateCamera()返回的rvecs / tvecs吗? - Chao
另一个问题:对于校准模式的多个视图,必须保持完全相同的位置才能使字坐标系不变吗? - Chao
我很抱歉,我仍然不理解calibrateCamera中的rvecs/tvecs和solvePnP中的rvecs/tvecs之间的区别。 - Carpetfizz
请问如何从单应性矩阵中获取objectPoints和imagePoints以供solvePnP()方法使用? - Nuibb

6

calibrateCamera (文档) 会估算给定相机的内参系数(即相机矩阵和畸变系数)。该函数需要您提供 N 组 2D-3D 对应,这些对应与以不同视角拍摄的 N 张图像相关联(通常是 N=30,请参见有关此主题的教程)。该函数返回所考虑相机的相机矩阵和畸变系数。虽然这些通常不使用,但外参参数(即位置和方向)也被估计,因此该函数为每个输入图像返回一对rvectvec

solvePnP(文档) 会估算给定相机图像的外参参数。该函数需要您提供一个与已知内参参数的相机拍摄的单个图像相关联的 2D-3D 对应关系集。该函数返回一对rvectvec,对应于输入图像。


3

calibrateCamera()可以提供rvec、tvec、distCoeff和cameraMatrix。distCoeff跟图像畸变有关,而cameraMatrix则提供了图像的中心(Cx和Cy)和焦距(Fx和Fy)(投影中心),这些被称为内参数。除非你改变相机的光圈/对焦,否则它们将保持不变。[它还提供了rvec和tvec,我现在还不知道它们有什么可能的用途。这些是相机在现实世界中的位置。rvec和tvec也被称为外参数]

solvePnP()以cameraMatrix和distCoeff作为输入,并提供了rvec和tvec。利用Cx、Cy、Fx和Fy,它可以估计相机的当前位置,即外参数。换句话说,首先使用calibrateCamera()来获取CameraMatrix和distCoeff。将它们用于solvePNP(),它会告诉你随着相机移动到你的真实世界对象(带有一些标记,如你所预期)的旋转(rvec)和平移(tvec)。


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