我使用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,并且它不会收敛。 :(
所以这是我的问题:
答案 0 :(得分:1)
正交投影不会使用深度缩小更远的点。但是,它会缩放点以适应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这样的库,我认为您会更好。在这种情况下,您可以使用精确的投影矩阵。