【发布时间】:2018-10-30 06:47:00
【问题描述】:
我试图在房间中模拟深度相机,我的相机能够在世界中移动和旋转,并且房间被模拟为围绕 (0,0,0) 的 3d 立方体 单击一个按钮,我想在图像中采样 N 个随机点并获取这些点与相机的距离(“现实世界”中的距离)。到目前为止,我已经设法创建了移动相机和立方体的场景 (Example)
我尝试使用 gluUnProject 来获取 3d 点
model_view = np.array(glGetDoublev(GL_MODELVIEW_MATRIX))
proj = np.array(glGetDoublev(GL_PROJECTION_MATRIX))
view = np.array(glGetDoublev(GL_VIEWPORT))
3d_point = gluUnProject(x,y, 0.0)
其中 x,y 是图像中像素的坐标,但是当我在知道其位置(立方体角)的像素上进行检查时,我得到的结果感觉像是随机的。
我对 openGL 很陌生,所以我可能会遗漏一些东西,从数学上讲,我想做的就是在像素坐标上应用投影和视图矩阵的逆矩阵,但这不起作用。
我在下面附上了房间模拟的代码。
提前致谢。
import pygame
from pygame.locals import *
import numpy as np
import random
from OpenGL.GL import *
from OpenGL.GLU import *
display = (800, 600)
import math
def get_cube_information():
vertices = (
(1, -1, -1),
(1, 1, -1),
(-1, 1, -1),
(-1, -1, -1),
(1, -1, 1),
(1, 1, 1, ),
(-1, -1, 1),
(-1, 1, 1),
)
edges = (
(0,1),
(0,3),
(0,4),
(2,1),
(2,3),
(2,7),
(6,3),
(6,4),
(6,7),
(5,1),
(5,4),
(5,7),
)
surfaces = (
(0,1,2,3),
(3,2,7,6),
(6,7,5,4),
(4,5,1,0),
(1,5,7,2),
(4,0,3,6),
)
colors = (
(1.000, 0.920, 0.000),
(0.000, 0.860, 0.000),
(1.000, 0.480, 0.000),
(1.000, 1.000, 1.000),
(0.900, 0.000, 0.000),
(0.000, 0.000, 0.950)
)
return vertices, edges, surfaces, colors
def Cube():
glBegin(GL_QUADS)
(vertices, edges, surfaces, colors) = get_cube_information()
for i, surface in enumerate(surfaces):
x = 0
color = colors[i]
for vertex in surface:
x += 1
glColor3fv(color)
glVertex3fv(vertices[vertex])
glEnd()
glBegin(GL_LINES)
for edge in edges:
for vertex in edge:
glVertex3fv(vertices[vertex])
glEnd()
def main():
pygame.init()
tx = 0
ty = 0
tz = 0
ry = 0
rx = 0
pygame.display.set_mode(display, DOUBLEBUF|OPENGL|RESIZABLE)
glMatrixMode(GL_PROJECTION)
gluPerspective(45, (display[0] / display[1]), 0.1, 50.0)
view_mat = np.matrix(np.identity(4), copy=False, dtype='float32')
glMatrixMode(GL_MODELVIEW)
glLoadIdentity()
glTranslatef(0, 0, 0)
glGetFloatv(GL_MODELVIEW_MATRIX, view_mat)
glLoadIdentity()
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
quit()
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_ESCAPE:
pygame.quit()
quit()
if event.key == pygame.K_a:
tx = 0.05
elif event.key == pygame.K_d:
tx = -0.05
elif event.key == pygame.K_w:
tz = 0.05
elif event.key == pygame.K_s:
tz = -0.05
elif event.key == pygame.K_RIGHT:
ry = 1.0
elif event.key == pygame.K_LEFT:
ry = -1.0
elif event.key == pygame.K_UP:
rx = -1.0
elif event.key == pygame.K_DOWN:
rx = 1.0
elif event.key == pygame.K_SPACE:
continue
elif event.type == pygame.KEYUP:
if event.key == pygame.K_a and tx > 0:
tx = 0
elif event.key == pygame.K_d and tx < 0:
tx = 0
elif event.key == pygame.K_w and tz > 0:
tz = 0
elif event.key == pygame.K_s and tz < 0:
tz = 0
elif event.key == pygame.K_RIGHT and ry > 0:
ry = 0.0
elif event.key == pygame.K_LEFT and ry < 0:
ry = 0.0
elif event.key == pygame.K_DOWN and rx > 0:
rx = 0.0
elif event.key == pygame.K_UP and rx < 0:
rx = 0.0
elif event.type == pygame.MOUSEBUTTONDOWN:
#here I want to sample the points and return their (x,y) in the image and their distance from the camera.
continue
glPushMatrix()
glLoadIdentity()
glTranslatef(tx, ty, tz)
glRotatef(ry, 0, 1, 0)
glRotatef(rx, 1, 0, 0)
glMultMatrixf(view_mat)
glGetFloatv(GL_MODELVIEW_MATRIX, view_mat)
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
Cube()
glPopMatrix()
pygame.display.flip()
pygame.time.wait(10)
main()
【问题讨论】:
-
This answer 可能有助于清除
gluUnProject的使用。看起来你还需要传入一个 z 坐标,你可以从深度缓冲区中获得它。 -
这个depth buffer got by glReadPixels is always 1 可能会让你感兴趣...