You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Open3D从RGBD图像创建点云时遭遇不支持的图像格式错误

问题分析与解决

报错Unsupported image format的核心原因有两个:

  1. RGB图与深度图尺寸不匹配:GLPN生成深度图时去掉了16像素的padding,导致深度图尺寸(968x968)远小于输入RGB图的1000x1000,Open3D要求两者尺寸完全一致。
  2. 深度图格式错误:代码中将深度图归一化到0-255并转为uint8,丢失了真实深度信息,且这种格式不符合Open3D对深度图的预期(需为表示实际距离的数值类型,如uint16或float32)。

修改步骤

1. 修正深度图尺寸,确保与输入图像一致

在GenerateDepthMap函数末尾添加resize逻辑,将处理后的深度图还原为输入图像的尺寸:

def GenerateDepthMap(input_image):
    # 原有加载模型与推理代码不变
    padding = 16
    output = predicted_depth.squeeze().cpu().numpy() * 1000.0
    output = output[padding:-padding, padding:-padding]
    
    # 新增:resize回输入图像的尺寸
    output = cv2.resize(output, input_image.size, interpolation=cv2.INTER_LINEAR)
    return output

2. 修正深度图的数据类型与处理逻辑

在GeneratePointcloud3D函数中,去掉错误的归一化操作,将深度图转为uint16(存储毫米级深度值,符合Open3D要求):

def GeneratePointcloud3D(input_image, depth_map):
    width, height = input_image.size
    input_image = np.array(input_image)

    # 修改:直接转为uint16,保留真实深度值(毫米级)
    depth_map = depth_map.astype(np.uint16)

    depth_3d = o3d.geometry.Image(depth_map)
    image_3d = o3d.geometry.Image(input_image)
    # 新增depth_scale参数,深度值为毫米级,设置为1.0表示每个单位对应1毫米
    rgbd_image = o3d.geometry.RGBDImage.create_from_color_and_depth(
        image_3d, depth_3d, 
        depth_scale=1.0,
        convert_rgb_to_intensity=False
    )

    # 原有相机设置与点云生成代码不变
    camera_intrinsic = o3d.camera.PinholeCameraIntrinsic()
    camera_intrinsic.set_intrinsic(width, height, 500, 500, width / 2, height / 2)
    pointcloud = o3d.geometry.PointCloud.create_from_rgbd_image(rgbd_image, camera_intrinsic)

    return pointcloud

3. 可选优化:调整相机内参

如果生成的点云比例不符合预期,可以根据实际相机参数调整内参中的焦距(当前代码设置为500,可按需修改)。

完整修改后的核心代码片段

def GenerateDepthMap(input_image):
    feature_extractor = GLPNImageProcessor.from_pretrained("vinvino02/glpn-nyu")
    model = GLPNForDepthEstimation.from_pretrained("vinvino02/glpn-nyu")

    inputs = feature_extractor(images=input_image, return_tensors="pt")

    with torch.no_grad():
        outputs = model(**inputs)
        predicted_depth = outputs.predicted_depth

    padding = 16
    output = predicted_depth.squeeze().cpu().numpy() * 1000.0
    output = output[padding:-padding, padding:-padding]
    # 还原为输入图像尺寸
    output = cv2.resize(output, input_image.size, interpolation=cv2.INTER_LINEAR)
    return output

def GeneratePointcloud3D(input_image, depth_map):
    width, height = input_image.size
    input_image = np.array(input_image)

    # 转换为uint16存储毫米级深度
    depth_map = depth_map.astype(np.uint16)

    depth_3d = o3d.geometry.Image(depth_map)
    image_3d = o3d.geometry.Image(input_image)
    rgbd_image = o3d.geometry.RGBDImage.create_from_color_and_depth(
        image_3d, depth_3d,
        depth_scale=1.0,
        convert_rgb_to_intensity=False
    )

    camera_intrinsic = o3d.camera.PinholeCameraIntrinsic()
    camera_intrinsic.set_intrinsic(width, height, 500, 500, width / 2, height / 2)
    pointcloud = o3d.geometry.PointCloud.create_from_rgbd_image(rgbd_image, camera_intrinsic)

    return pointcloud

内容的提问来源于stack exchange,提问作者nowsqwhat

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.24 10:28:18