首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >从OpenGL深度缓冲区获取世界坐标

从OpenGL深度缓冲区获取世界坐标
EN

Stack Overflow用户
提问于 2019-12-02 02:58:36
回答 1查看 1.1K关注 0票数 4

我使用的是pyBullet,它是bullet3物理引擎的python包装器,我需要从虚拟相机创建点云。

这个引擎使用基本的OpenGL渲染器,并且我能够从OpenGL深度缓冲区获得值

代码语言:javascript
复制
img = p.getCameraImage(imgW, imgH, renderer=p.ER_BULLET_HARDWARE_OPENGL)
rgbBuffer = img[2]
depthBuffer = img[3]

现在我有了带有深度值的width*height数组。我怎么才能从中得到世界坐标呢?我尝试用点(宽度,高度,depthBuffer(宽度,高度))保存.ply点云,但这不会创建看起来像场景中对象的点云。

我还试着用near far plane校正深度:

代码语言:javascript
复制
depthImg = float(depthBuffer[h, w])
far = 1000.
near = 0.01
depth = far * near / (far - (far - near) * depthImg)

但由此产生的结果也是一些奇怪的点云。如何从深度缓冲区中的数据创建逼真的点云?这有可能吗?

我在c++中做了类似的事情,但在那里我使用了glm::unproject

代码语言:javascript
复制
for (size_t i = 0; i < height; i = i = i+density) {
        for (size_t j = 0; j < width; j = j = j+density) {

            glm::vec3 win(i, j, depth);
            glm::vec4 position(glm::unProject(win, identity, projection, viewport), 0.0);

编辑:

基于我使用PyGLM的Rabbid76回答,我现在可以获得XYZ世界坐标来创建点云,但是点云中的深度值看起来失真了,我是否正确地从深度缓冲区中获取深度?

代码语言:javascript
复制
    for h in range(0, imgH, stepX):
       for w in range(0, imgW, stepY):
          depthImg = float(np.array(depthBuffer)[h, w])
          far = 1000.
          near = 0.01
          depth = far * near / (far - (far - near) * depthImg)
          win = glm.vec3(h, w, depthBuffer[h][w])
          position = glm.unProject(win, model, projGLM, viewport)
          f.write(str(position[0]) + " " + str(position[1]) + " " + str(depth) + "\n")
EN

回答 1

Stack Overflow用户

发布于 2020-06-07 23:00:42

这是我的解决方案。我们只需要知道视图矩阵和投影矩阵是如何工作的。在pybullet中有computeProjectionMatrixFOV和computeViewMatrix函数。简而言之,http://www.songho.ca/opengl/gl_projectionmatrix.htmlhttp://ksimek.github.io/2012/08/22/extrinsic/,point_in_world =http://www.songho.ca/opengl/gl_projectionmatrix.html(projection_matrix* viewMatrix) * NDC_pos

glm.unProject是另一种解决方案

代码语言:javascript
复制
    stepX = 10
    stepY = 10        
    pointCloud = np.empty([np.int(img_height/stepY), np.int(img_width/stepX), 4])
    projectionMatrix = np.asarray(projection_matrix).reshape([4,4],order='F')
    viewMatrix = np.asarray(view_matrix).reshape([4,4],order='F')
    tran_pix_world = np.linalg.inv(np.matmul(projectionMatrix, viewMatrix))
    for h in range(0, img_height, stepY):
        for w in range(0, img_width, stepX):
            x = (2*w - img_width)/img_width
            y = -(2*h - img_height)/img_height  # be careful! deepth and its corresponding position
            z = 2*depth_np_arr[h,w] - 1
            pixPos = np.asarray([x, y, z, 1])
            position = np.matmul(tran_pix_world, pixPos)

            pointCloud[np.int(h/stepY),np.int(w/stepX),:] = position / position[3]
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/59128880

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档