繁体   English   中英

使用OpenCV的solvePnP功能进行外部摄像机校准

[英]Extrinsic Camera Calibration Using OpenCV's solvePnP Function

我目前正在使用称为3DSlicer的医学成像程序开发增强现实应用程序。 我的应用程序在Slicer环境中作为模块运行,旨在提供使用外部跟踪系统来扩展Slicer中显示的摄像机供稿所需的工具。

当前,一切都已正确配置,因此我剩下要做的就是自动计算摄像机的外部矩阵,我决定使用OpenCV的solvePnP()函数进行此计算。 不幸的是,这给我带来了一些困难,因为我没有获得正确的结果。

我的跟踪系统配置如下:

  • 光学跟踪器的安装方式使得可以看到整个场景。
  • 跟踪标记牢固地附加到指针工具,相机和我们已为其获取虚拟表示的模型上。
  • 指针工具的笔尖已使用枢轴校准进行注册。 这意味着使用指针记录的任何值都指示指针尖端的位置。
  • 模型和指针都具有3D虚拟表示,可以增强实时视频源,如下所示。
  • 指针和摄像机标记(此后称为C)分别返回一个均质变换,以描述它们相对于模型上附加的标记的位置(此后称为M)。 作为原点的模型标记不会返回任何变换。

正确增强环境的描述。手动调整了Extrinsic以证明过程是正确的,但是不准确。

我获得了两组点,一个2D和一个3D。 2D点是像素坐标中棋盘角的坐标,而3D点是相对于M的相同角对应的世界坐标。这些是使用openCV的2维点的detectChessboardCorners()函数和3点的指针记录的维。 然后,我将3D点从M空间转换为C空间,方法是将它们乘以C逆。 这样做是因为solvePnP()函数要求相对于相机的世界坐标系描述3D点,在这种情况下为C,而不是M。

完成所有这些操作后,我将点集传递到solvePnp() 但是,我得到的转换是完全不正确的。 老实说,我对自己做错了事感到茫然。 令我感到困惑的是,OpenCV使用的坐标格式与OpenGL不同,而3DSlicer正是基于此格式的。 如果有人能在这件事上提供一些帮助,我将非常感谢。

此外,如果有任何不清楚的地方,请不要犹豫。 这是一个相当大的项目,所以我很难将所有内容都提炼出来。 我完全希望阅读此书的人可能会感到困惑。

谢谢!

更新#1:事实证明我是个白痴。 我记录共线点只是因为我太急于记录整个棋盘。 当然,这意味着最小二乘回归几乎有无限的解,因为我仅将解锁定为2维! 我的价值观现在更接近于我的基本事实,实际上,旋转专栏似乎是正确的,除了它们完全乱七八糟。 我不确定是什么原因导致的,但是似乎我的旋转矩阵已镜像到中心列。 除此之外,我的翻译成分在应该为正数时为负,尽管其幅度似乎是正确的。 所以现在我基本上以所有错误的顺序获得了所有正确的值。

镜像/旋转歧义。

基本上,您需要通过施加以下约束来重新定位坐标系:(1)场景位于相机的前面,(2)棋盘格轴的方向如您所愿。 归结为将校正后的变换乘以适当的(“手工构建”)旋转和/或镜像。

基本问题是,除非使用颜色信息,否则即使看到所有拐角,所使用的校准目标也至少具有180度旋转模糊度。 如果错过一些角落,事情可能会变得更加奇怪。

正如我上面所建议的,您通常可以在场景中使用有关摄像机方向的先验信息来解决这种歧义。 但是,在更具动态性的情况下,如果在目标可能仅部分可见的情况下需要进一步的自动化程度,则最好使用可以单独识别每个小角点的目标。 我最喜欢的是Matsunaga和Kanatani的“ 2D条码”,它使用具有独特交叉比例的正方形长度序列。 请看这里的论文。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM