从OpenGL

时间:2016-05-14 18:17:19

标签: opengl graphics computer-vision projection camera-calibration

我使用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]

如果我想“手动”投射模型点,我可以计算:

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不是0.0037371。这是一个缩放的正投影还是什么?

此外,为了“手动”投影模型顶点,我设法做了以下事情:

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不起作用?

1 个答案:

答案 0 :(得分:1)

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

Orthographic Projection

因此,使用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这样的库,我认为您会更好。在这种情况下,您可以使用精确的投影矩阵。