理论
在计算机视觉估计中,从n个3D到2D点对应的相机姿势是基本且易于理解的问题。 该问题的最一般版本需要估计姿势的六个自由度和五个校准参数:焦距,主点,纵横比和歪斜。 使用众所周知的直接线性变换(DLT)算法,可以建立至少6个对应关系。 但是,对问题进行了若干简化,这些简化成为提高DLT准确性的不同算法的广泛列表。
最常见的简化是假设已知的校准参数,即所谓的Perspective- * n * -Point问题:
问题公式:给定在世界参考系中表示的3D点pi与其在图像上的2D投影ui之间的一组对应关系,我们寻求检索相机的姿势(R和t)w.r.t. 世界和焦距f。
OpenCV提供了四种不同的方法来解决返回R和t的Perspective- * n * -Point问题。 使用以下公式可以将3D点投影到图像平面:
代码
您可以在OpenCV源库的samples / cpp / tutorial_code / calib3d / real_time_pose_estimation /文件夹中找到本教程的源代码。
本教程包含两个主要程序:
注册模型
- 该应用程序专用于没有要检测的对象的3D纹理模型。 您可以使用此程序创建自己的纹理3D模型。 此程序仅适用于平面对象,如果要对具有复杂形状的对象建模,则应使用复杂的软件来创建它。
- 应用程序需要要注册的对象的输入图像及其3D网格。 我们还必须提供用于拍摄输入图像的相机的固有参数。 需要使用绝对路径或应用程序工作目录中的相对路径指定所有文件。 如果未指定任何文件,程序将尝试打开提供的默认参数。
- 应用程序开始从输入图像中提取ORB特征和描述符,然后使用网格和Möller-Trumbore交集算法计算找到的特征的3D坐标。 最后,3D点和描述符存储在具有YAML格式的文件中的不同列表中,每个行是不同的点。
模型检测
- 该应用的目的是在给定其3D纹理模型的情况下实时估计对象姿势。
- 应用程序开始以YAML文件格式加载3D纹理模型,其结构与模型注册程序中说明的结构相同。 从场景中,检测并提取ORB特征和描述符。 然后,使用cv :: FlannBasedMatcher和cv :: flann :: GenericIndex来进行场景描述符和模型描述符之间的匹配。 使用找到的匹配以及cv :: solvePnPRansac函数,计算摄像机的R和t。 最后,应用KalmanFilter以拒绝不良姿势。
- 如果您使用示例编译OpenCV,可以在opencv / build / bin / cpp-tutorial-pnp_detection`中找到它。 然后,您可以运行该应用程序并更改一些参数:
解释
- 读取3D纹理对象模型和对象网格。
- 为了加载纹理模型,我实现了类Model,它具有函数load(),它打开一个YAML文件,并使用相应的描述符获取存储的3D点。 您可以在samples / cpp / tutorial_code / calib3d / real_time_pose_estimation / Data / cookies_ORB.yml中找到3D纹理模型的示例。
- 在主程序中,模型加载如下:
- 为了读取模型网格,我实现了一个类Mesh,它具有一个函数load(),它打开一个* .ply文件并存储对象的3D点以及组合三角形。 您可以在samples / cpp / tutorial_code / calib3d / real_time_pose_estimation / Data / box.ply中找到模型网格的示例。
- 在主程序中,网格加载如下:
- 您还可以加载不同的模型和网格:
- 从相机或视频中获取输入。
- 要检测是必要的捕获视频。 通过传递它在机器中的绝对路径来完成加载录制的视频。 为了测试