【问题标题】:Understanding the view and projection matrix from pybullet从 pybullet 理解视图和投影矩阵
【发布时间】:2020-02-27 10:21:47
【问题描述】:
当在 Pybullet 中渲染图像时,必须使用 getCameraImage 将 view 和 projection 矩阵作为输入(pybullet 也具有生成这些矩阵的功能)。理论上,投影矩阵应该是 P = K[R|t],它可以重写为 P = [M|-MC],因此我们可以在理论上使用 M 的 RQ 分解,其中 R 是上三角矩阵。所以我们可以从投影矩阵中恢复 K 和 [R|t](请记住,来自 RQ 分解的 R 不是来自 R|t 的 R)。但是当我使用例如 scipy.linalg.rq 时,结果不是有效的 K(内在)矩阵。
有人可以解释一下投影矩阵是如何精确定义的,pybullet 中的视图矩阵是什么?以及我们如何使用这些矩阵检索内在和外在参数?
【问题讨论】:
标签:
python
graphics
computer-vision
【解决方案1】:
所以pybullet通常使用视场(FOV in rads)来构造投影矩阵(source code)
而内在矩阵被定义为
p_x 和 p_y 是主要点,通常是图像的中心。所以有一些区别:
- 尺寸。 Pybullet 添加第三行(不是第四行)和第四列以保留深度信息。
- 忽略第三行,元素 2,2(零索引)不是 1。
- Pybullet 使用 0 偏斜参数。
- 它没有使用焦距(它是但它是从 FOV 计算的)。
- Pybullet 假设 p_x = p_y = 0
首先,pybullet 使用 OpenGL 的符号,因此它使用主列顺序 (read more)。表示索引时的第一个元素是列而不是行。因此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]。