Open3D中从Mesh生成RGBD图像转点云时报格式不支持错误咨询
错误成因
- 图像格式不匹配:
create_from_rgbd_image要求输入的RGBD图像中,颜色图格式为uint8(值范围0255)或`float32`(值范围01),深度图格式为uint16(单位毫米)或float32(单位米)。你通过capture_screen_float_buffer获取的颜色图是01范围的float32格式本身兼容,但`capture_depth_float_buffer`返回的是归一化到01的视口深度值,不是真实物理深度,格式不符合接口要求,触发了格式报错。 - 相机内参赋值错误:Open3D的
PinholeCameraIntrinsic内参矩阵为标准行优先3×3矩阵,格式为[[fx, 0, cx], [0, fy, cy], [0, 0, 1]],你代码中填写的矩阵第三行错误,属于矩阵转置后的写法,会导致后续投影计算异常。 - 导入拼写错误:代码首行
import open3D as o3d中D为大写,正确写法为import open3d as o3d,否则会直接触发模块导入报错。
解决方法
方法1:修正原代码格式问题
在创建RGBD图像前补充图像格式转换步骤,同时修正相机内参赋值即可,修改后完整有效代码如下:
import open3d as o3d import numpy as np def render_depth(cam_intrinsic, model): # load model actor = o3d.io.read_triangle_mesh(str(model)) actor.compute_vertex_normals() # create visualizer object vis = o3d.visualization.Visualizer() vis.create_window(width=1920, height=1061, visible=False) vis.add_geometry(actor) ctr = vis.get_view_control() # retrieve intrinsic camera settings parameters = o3d.io.read_pinhole_camera_parameters(cam_intrinsic) ctr.convert_from_pinhole_camera_parameters(parameters) vis.poll_events() vis.update_renderer() depth = vis.capture_depth_float_buffer(False) image = vis.capture_screen_float_buffer(False) vis.destroy_window() return depth, image def main(): # produce depth and color image, for creating RGBD image depth, color = render_depth('directory_to_camera_properties.json', 'model_directory.obj') # 转换颜色图为uint8格式 color_np = (np.asarray(color) * 255).astype(np.uint8) color = o3d.geometry.Image(color_np) # 转换深度图为真实物理深度,缩放系数根据场景实际深度范围调整,示例为最大深度10米 depth_np = np.asarray(depth).astype(np.float32) * 10 depth = o3d.geometry.Image(depth_np) # create RGBD image rgbd = o3d.geometry.RGBDImage.create_from_color_and_depth(color=color, depth=depth, convert_rgb_to_intensity=False, depth_trunc=10.0) # 修正相机内参赋值 cam = o3d.camera.PinholeCameraIntrinsic( width=1920, height=1061, fx=500, fy=918.8529534152894, cx=959.5, cy=530.0 ) actor = o3d.geometry.PointCloud.create_from_rgbd_image(rgbd, cam) # 翻转点云坐标系适配Open3D默认可视化视角 actor.transform([[1, 0, 0, 0], [0, -1, 0, 0], [0, 0, -1, 0], [0, 0, 0, 1]]) o3d.visualization.draw_geometries([actor]) if __name__ == '__main__': main()
方法2:直接从网格采样点云(更简便)
如果你的需求只是从三维网格生成对应点云,不需要走RGBD渲染中转,直接调用网格采样接口即可,不会出现格式报错问题:
actor = o3d.io.read_triangle_mesh('model_directory.obj') # 均匀采样10万个点,可根据需求调整采样数量 pcd = actor.sample_points_uniformly(number_of_points=100000) o3d.visualization.draw_geometries([pcd])
内容的提问来源于stack exchange,提问作者junfanbl
相关产品推荐
相关产品推荐

