从 pybullet 理解视图和投影矩阵

Mik*_*e W 3 python graphics computer-vision

在 Pybullet 中渲染图像时,必须使用getCameraImage视图投影矩阵作为输入的函数(pybullet 也具有生成这些矩阵的函数)。理论上,投影矩阵应该是 P = K[R|t],它可以重写为 P = [M|-MC],因此理论上我们可以使用 M 的 RQ 分解,其中 R 是上三角矩阵。因此,我们可以从投影矩阵中恢复 K 和 [R|t](请记住,RQ 分解中的 R 不是 R|t 中的 R)。但是,当我使用时,scipy.linalg.rq结果不是有效的 K(固有)矩阵。

有人可以解释一下投影矩阵是如何精确定义的以及pybullet中的视图矩阵是什么?我们如何使用这些矩阵检索内在和外在参数?

Mik*_*e W 6

因此 pybullet 通常使用视场(以拉德为单位的 FOV)构建投影矩阵(源代码):

在此输入图像描述

固有矩阵定义为

在此输入图像描述

p_x 和 p_y 是主点,通常是图像的中心。所以有一些区别:

  1. 尺寸。Pybullet 添加第三行(不是第四行)和第四列来保留深度信息。
  2. 忽略第三行,元素 2,2(零索引)不是 1。
  3. Pybullet 使用 0 倾斜参数。
  4. 它不使用焦距(它是,但它是根据 FOV 计算的)。
  5. Pybullet 假设 p_x = p_y = 0

首先,pybullet 使用 OpenGL 的表示法,因此它使用主列顺序(了解更多)。这意味着索引时的第一个元素是列而不是行。因此,应转置 pybullet 的实际投影矩阵。

其次,将 FOV 转换为焦距 f 的完整方程为:

在此输入图像描述

因此 pybullet 将焦距乘以 2/h。原因是因为 pybullet 使用标准化设备坐标(NDC),它将值剪辑在 [-1,1] 之间(将 x 除以宽度将其剪辑为 [0,1] 并将其乘以 2 将其剪辑在 [0,2] 之间如果主点位于图像 1,1 的中间点,则将其剪裁为 [-1,1])。因此 pybullet 的焦距是使用 NDC 的正确焦距。

投影矩阵第三列中的非零值用于映射 OpenGL 中的 z 值,因此我们可以忽略它们。

K 矩阵中的 k、l 是 mm/px 的比率,如果我们使用 pybullet,我们可以说 k=l=1。

一些有用的资源是[1][2][3]