查找将3D局部坐标映射到全局坐标的转换矩阵

时间:2019-09-06 10:48:16

标签: opencv image-processing 3d homography

我正在为我的深度相机编码一种校准算法。该摄像机输出一个通道的2D图像,其中包含图像中每个对象的距离。

根据该图像,使用相机和失真矩阵,可以从相机的角度创建3D点云。现在,我希望将这些3D坐标转换为全局/世界坐标。但是,由于无法使用象棋盘这样的图案来校准相机,因此我需要另一种选择。

所以我在想:如果我提供一些地面点(在摄影机视角中),我将定义一个平面,该平面我知道在整体视角中Z坐标应接近零。因此,我应该如何继续找到使平面水平的转换矩阵。

Local coordinates ground plane, with an object on top

我尝试使用OpenCV的solvePnP,但没有给我正确的转换。我也曾考虑过使用OpenCV的estimateAffine3D,但我不知道全局坐标应映射到哪里,因为提供的接地点不需要位于任何特定的图案/形状上。

预先感谢

1 个答案:

答案 0 :(得分:0)

您需要的是通常称为外部校准:一种将3D摄像机参考系与“世界”参考系相关联的刚性转换。通常,这是通过在世界参照系中找到已知的 3D 点及其在图像中相应的 2D 投影来完成的。这就是SolvePNP所做的。

要在两组3D点之间找到最佳的旋转/平移,就将均方根误差最小化而言,解决方案是:

  1. 理论:https://igl.ethz.ch/projects/ARAP/svd_rot.pdf
  2. 更简单的解释:http://nghiaho.com/?page_id=671
  3. Python代码(来自简单的说明站点):http://nghiaho.com/uploads/code/rigid_transform_3D.py_

因此,如果要从摄像机参考系转换 3D 点,请执行以下操作:

  • 按照您的建议,定义一些在世界参考框架中具有已知位置的3D点,例如(但不一定)定义为Z = 0。将坐标放在Nx3矩阵 P 中。
  • 获取相机参考系中的相应3D点。将它们放在Nx3矩阵 Q 中。
  • 从上面第3点定义的文件中,调用 rigid_transform_3D(P,Q)。这将返回3x3矩阵 R 和3x1向量 t

然后,对于世界参考系 p 中的任何3D点,将其作为3x1向量,可以使用以下方法获得相应的摄像机点 q

q = R.dot(p)+t

编辑:未指定世界上点的3D位置时回答

实际上,要使此过程正常运行,您需要了解(或更好地指定)世界参考系中点的3D坐标。如评论中所述,您仅知道这些点在平面中,而在平面中没有坐标。

这是一个可能的解决方案:

  1. 在摄像机参考系中选取选定的3D点,我们将其称为 q' i

  2. 使平面适合这些点,例如,https://www.ilikebigbits.com/2015_03_04_plane_from_points.html中所述。其结果将是法线向量 n 。要完全指定平面,还需要选择一个点,例如 q' i 的质心(平均值)。

  3. 由于这些点肯定不是完全位于平面中,因此可以将它们投影到平面上,例如,如How to project a point onto a plane in 3D?中所述。我们将这些投影点称为 q i

  4. 这时,您有一组3D点 q i ,它们位于完美的平面上,该平面应与地平面紧密对应(在世界坐标系中z = 0)。但是,坐标在相机参考系中。

  5. 现在,我们需要指定此地平面中x和y轴的原点和方向。您似乎对此没有任何标准,因此可以选择将原点随意设置在相机中心“下方”,并将X轴与相机光轴对齐。为此:

  6. 将点(0,0,0)投影到平面中,就像在步骤4中所做的那样。将其称为 o 。将点(0,0,1)投影到平面中,并将其命名为 a 。计算向量 a-o ,对其进行归一化,并将其称为 i

  7. o 是世界参照系的原点,而 i 是世界参照系的X轴(以相机坐标表示)。致电 j = n x i (叉积)。 j 是Y轴,我们快完成了。

  8. 现在,通过将其投影到 i 上,获得世界参照系中的点 q i 的XY坐标,然后 j 。也就是说,在每个 q i i 之间进行点积运算以获得X值和每个 q < sub> i j 来获取Y值。 Z值全为0。将这些X,Y,0坐标称为 p i

  9. 使用这些 p i q i 值来估计 R < / strong>和 t ,就像答案的第一部分一样!

也许有一个更简单的解决方案。另外,我还没有测试过,但是我认为它应该可以工作。希望这会有所帮助。