所以我尝试用python中的Open3D库创建一个点云,最后,它基本上只是here中引用的2行,但是当我运行代码(见下文)时,我得到的只是一个白屏弹出。我已经在Jupyter笔记本中运行了它,但是从控制台以python脚本运行它并没有改变任何东西,也没有引发错误。我应该提到我在Blender中创建了图像并将其保存为OpenExr,这意味着深度值范围在0到4之间(对于背景,我将其截断为4)。您可以在下面看到它们是正确的图像,我也可以将它们转换为Open3D图片并显示它们而没有问题。
colour = o3d.geometry.Image(np.array(img_array[:, :, :3]))
#depth = o3d.geometry.Image(np.array(img_array[:, :, 3]*1000).astype('uint16'))
depth = o3d.geometry.Image(np.array(img_array[:, :, 3]))
o3d.draw_geometries([depth])
pinhole_cam = o3d.open3d.camera.PinholeCameraIntrinsic(width= 1280, height=720, cx=640,cy=360,fx=500,fy=500)
rgbd = o3d.create_rgbd_image_from_color_and_depth(colour, depth, convert_rgb_to_intensity = False, depth_scale=1000)
pcd = o3d.create_point_cloud_from_rgbd_image(rgbd, pinhole_cam)
o3d.draw_geometries([pcd])
[我认为这可能与针孔相机的参数有关。 Tbh,我不知道什么是合适的参数,只是cy,cy应该是图像的中心,fx,fy应该是是明智的。因为我的深度值是以Blender米为单位,但是Open3D显然期望以毫米为单位,所以缩放应该有意义。
如果您能帮助我调试它,我将不胜感激。但是,如果您要向我指出一个更好的工作库,以便从图像创建3D点云,我也不介意。我在Open3D中找到的文档充其量是缺乏的。
您误解了depth_scale
的含义。
使用此行:depth = o3d.geometry.Image(np.array(img_array[:, :, 3]*1000).astype('uint16'))
Open3D documentation表示深度值将首先被缩放,然后被截断。实际上,这意味着深度图像中的像素值将首先除以该数字而不是相乘,如您在Open3D source:]中所见
(我想这就是Open3D在文档中没有清楚指出的原因),因为浮点图像不那么常见。您无法将std::shared_ptr<Image> Image::ConvertDepthToFloatImage( double depth_scale /* = 1000.0*/, double depth_trunc /* = 3.0*/) const { // don't need warning message about image type // as we call CreateFloatImage auto output = CreateFloatImage(); for (int y = 0; y < output->height_; y++) { for (int x = 0; x < output->width_; x++) { float *p = output->PointerAt<float>(x, y); *p /= (float)depth_scale; if (*p >= depth_trunc) *p = 0.0f; } } return output; }
实际上,我们通常认为深度图像中的值应该是整数
1.34
米存储在.png图像中,因为它们会失去精度。结果,我们将1340
存储在深度图像中,以后的过程将首先将其转换回1.34
。关于深度图像的相机固有特性,我想在创建Blender时,它会包含配置参数。我对Blender不熟悉,所以不再赘述。 但是,如果您不了解一般的相机内部特性,则可能需要看一下this
。