【发布时间】:2020-03-26 11:21:36
【问题描述】:
我正在使用 pyBullet,它是 bullet3 物理引擎的 python 包装器,我需要从虚拟相机创建点云。
该引擎使用基本的 OpenGL 渲染器,我能够从 OpenGL 深度缓冲区获取值
img = p.getCameraImage(imgW, imgH, renderer=p.ER_BULLET_HARDWARE_OPENGL)
rgbBuffer = img[2]
depthBuffer = img[3]
现在我有了带有深度值的 width*height 数组。我怎样才能从中获得世界坐标?我尝试使用点(宽度、高度、深度缓冲区(宽度、高度))保存 .ply 点云,但这不会创建看起来像场景中的对象的点云。
我还尝试用近远平面校正深度:
depthImg = float(depthBuffer[h, w])
far = 1000.
near = 0.01
depth = far * near / (far - (far - near) * depthImg)
但结果也是一些奇怪的点云。如何从深度缓冲区中的数据创建逼真的点云?有可能吗?
我在 c++ 中做了类似的事情,但我使用了 glm::unproject
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);
编辑:
基于 Rabbid76 的回答,我使用了 PyGLM,它有效,我现在能够获取 XYZ 世界坐标来创建点云,但点云中的深度值看起来失真,我是否正确地从深度缓冲区获取深度?
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")
【问题讨论】:
-
使用PyGLM。 (
glm.unProject(...)) -
不知何故我错过了,明天试试,然后我会更新/关闭这个问题,谢谢
-
似乎 PyGLM unProject 工作,但我不确定我是否正确获取深度值,我更新了问题
-
好的,所以我正确地获取了这些值,问题在于巨大的近/远值,看起来他们需要非常紧密地“拥抱”对象以获得正确的深度值
-
我想做和你一样的事情,从 pybullet 合成相机获取点云。我不熟悉
pcl也不熟悉opengl。你能分享一个最小的工作示例吗?或者澄清一下你如何选择步长、模型是projGLM=pybullet.computeProjectionMatrixFOV(..)和viewport=pybullet.computeViewMatrix(..)
标签: python c++ opengl depth-buffer