PyOpenGL-获取绘制图像的深度图

时间:2018-08-27 09:21:30

标签: python python-3.x opengl pyopengl

我从特定角度(使用视图和投影矩阵)绘制了特定场景。我使用了三角形的VBO,所以一个。 我可以使用以下方法获取图像的RGB:

data = glReadPixels(0, 0, width, height, GL_RGB, GL_UNSIGNED_BYTE)
data = np.frombuffer(data, dtype=np.uint8).reshape(width, height, 3)[::-1]
cv2.imwrite(r"c:\temp\image1.png", data)

但是获取深度图会得到一些奇怪的结果,其中大部分包含255:

data2 = glReadPixels(0, 0, width, height, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE)
data2 = np.frombuffer(data2, dtype=np.uint8).reshape(width, height)[::-1]
cv2.imwrite(r"c:\temp\image2.png", data2)

我尝试替换GL_UNSIGNED_BYTE-> GL_FLOATuint8-> float32

但这没有帮助

1 个答案:

答案 0 :(得分:1)

如果深度图被读取到GL_UNSIGNED_BYTE缓冲区中,则深度图由1.0初始化,导致255。请注意,深度图在[0.0,1.0]范围内,如果将其读取到GL_UNSIGNED_BYTE,则此范围将映射到[0,255]。

在透视投影时,z坐标没有线性映射到深度缓冲区。深度值迅速增加,靠近远平面的几何形状将导致深度值为255。

如果深度值在[0.0,1.0]范围内,并且您要计算视图(眼睛)空间 z 坐标,则必须将深度值转换为归一化的设备 z 坐标拳头(z_ndc):

z_ndc = 2.0 * depth - 1.0;

可以通过以下公式将该坐标转换为眼部空间 z 坐标(z_eye):

z_eye = 2.0 * n * f / (f + n - z_ndc * (f - n));

其中n是近平面,f是远平面。

请注意,此转换仅适用于透视投影。

在正交投影中, z 坐标线性映射到深度。因此,向后转换要简单得多:

z_eye = depth * (f-n) + n; 

另请参阅How to render depth linearly in modern OpenGL with gl_FragCoord.z in fragment shader?