从 OpenGL 获取相机矩阵

Get camera matrix from OpenGL

我使用带有 透视相机 的 OpenGL 渲染 3D 网格模型 – gluPerspective(fov, aspect, near, far)。

然后我在计算机视觉算法中使用渲染图像。

在某些时候,该算法需要相机矩阵 K(以及模型上的几个顶点及其相应的投影)以估计相机位置:旋转矩阵 R和平移向量t。我可以使用解决 Perspective-n-Point 问题的任何算法来估计 R 和 t。

我从 OpenGL 投影矩阵构造 K(查看如何 here

K = [fX, 0, pX | 0, fY, pY | 0, 0, 1]

如果我想投影模型点 'by hand' 我可以计算:

X_proj = K*(R*X_model + t) x_pixel = X_proj[1] / X_proj[3] y_pixel = X_proj[2] / X_proj[3]

无论如何,我在 PnP 算法中传递了这个相机矩阵,它工作得很好。


但后来我不得不将透视投影更改为 正交投影。 据我了解,在使用正交投影时,相机矩阵变为:

K = [1, 0, 0 | 0, 1, 0 | 0, 0, 0]

所以我将 gluPerspective 更改为 glOrtho。按照同样的方法,我从 OpenGL 投影矩阵构造 K,结果发现 fX 和 fY 不是 1,而是 0.0037371。这是比例正交投影还是什么?

此外,为了投影模型顶点 'by hand' 我设法做到了以下几点:

X_proj = K*(R*X_model + t) x_pixel = X_proj[1] + width / 2 y_pixel = X_proj[2] + height / 2

这不是我所期望的(加上宽度和高度除以 2 似乎很奇怪...)。我试图将这个相机矩阵传递给 POSIT 算法来估计 R 和 t,但它没有收敛。 :(

所以这是我的问题:

  1. 如何从 OpenGL 获取正交相机矩阵?
  2. 如果我的做法是正确的,那么它是正字法吗?为什么 POSIT 不起作用?

正交投影不会使用深度来缩小更远的点。但是,它将缩放点以适应 NDC 内,这意味着它将缩放值以适应范围 [-1,1] 内。 来自 Wikipedia 的矩阵显示了这意味着什么:

因此,数字不是 1 是正确的。

对于您的手动计算方式,我认为它没有按比例缩小到屏幕坐标,所以这是错误的。正如我所说,投影矩阵的输出将在 [-1,1] 范围内,如果你想获得像素坐标,我相信你应该做类似的事情:

X_proj = K*(R*X_model + t)
x_pixel = X_proj[1]*width/2 + width / 2
y_pixel = X_proj[2]*height/2 + height / 2

无论如何,我认为如果您将现代 OpenGL 与 GLM 这样的库一起使用会更好。在这种情况下,您手头有使用的精确投影矩阵。