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

带自定义标签的Tensor点云执行voxel_down_sample报错求解

问题

尝试对带有uint8类型物体类别标注的点云执行voxel_down_sample操作,移除自定义属性时下采样可正常运行,添加标签后则报错。

示例代码:

import open3d as o3d

device = o3d.core.Device("CPU:0")
pcd = o3d.t.geometry.PointCloud(device)
pcd.point.positions = o3d.core.Tensor([[0,0,0],[1,1,1],[2,2,2]], device=device)
pcd.point.labels = o3d.core.Tensor([0,1,2], o3d.core.uint8, device=device)

pcd_ds = pcd.voxel_down_sample(voxel_size=3)

注释掉pcd.point.labels = ...行时下采样正常,保留则触发错误:

RuntimeError                              Traceback (most recent call last)
Cell In[10], line 6
      3 pcd.point.positions = o3d.core.Tensor([[0,0,0],[1,1,1],[2,2,2]], device=device)
      4 pcd.point.labels = o3d.core.Tensor([0,1,2], o3d.core.uint8, device=device)
----> 6 pcd_ds = pcd.voxel_down_sample(voxel_size=3)

RuntimeError: [Open3D Error] (void open3d::core::kernel::BinaryEW(const open3d::core::Tensor&, const open3d::core::Tensor&, open3d::core::Tensor&, open3d::core::kernel::BinaryEWOpCode)) /root/Open3D/cpp/open3d/core/kernel/BinaryEW.cpp:49: The broadcasted input shape [1, 1] does not match the output shape [1].

版本信息:Python 3.11,Open3D 0.18

能否实现带有自定义属性的点云体素下采样?


解决方案

可以实现带自定义属性的点云体素下采样,问题根源在于Open3D默认对自定义属性采用均值聚合,而uint8类型的均值计算会触发类型不兼容或广播错误。以下是两种可行的解决方式:

方法1:用voxel_down_sample_and_trace手动处理标签

该方法能获取每个体素对应的原始点索引,可根据业务需求(如取众数、第一个点的标签等)手动聚合标签:

import open3d as o3d
import numpy as np

device = o3d.core.Device("CPU:0")
pcd = o3d.t.geometry.PointCloud(device)
pcd.point.positions = o3d.core.Tensor([[0,0,0],[1,1,1],[2,2,2]], device=device)
pcd.point.labels = o3d.core.Tensor([0,1,2], o3d.core.uint8, device=device)

voxel_size = 3
# 执行下采样并获取体素-原始点的索引映射
downpcd, indices, inv_indices = pcd.voxel_down_sample_and_trace(voxel_size, pcd.get_min_bound(), pcd.get_max_bound())

# 手动聚合标签:以每个体素内出现次数最多的标签为例
labels_np = pcd.point.labels.numpy()
down_labels = []
for idx_group in indices:
    if not idx_group.size:
        down_labels.append(0)
    else:
        count = np.bincount(labels_np[idx_group])
        down_labels.append(np.argmax(count))

# 将聚合后的标签赋值给下采样点云
downpcd.point.labels = o3d.core.Tensor(down_labels, dtype=o3d.core.uint8, device=device)

方法2:转换标签类型后执行下采样

若标签允许用浮点型临时表示,可先将uint8转为float32,下采样后再转回uint8:

import open3d as o3d

device = o3d.core.Device("CPU:0")
pcd = o3d.t.geometry.PointCloud(device)
pcd.point.positions = o3d.core.Tensor([[0,0,0],[1,1,1],[2,2,2]], device=device)
# 将标签转为float32规避类型问题
pcd.point.labels = o3d.core.Tensor([0,1,2], o3d.core.float32, device=device)

# 执行下采样
pcd_ds = pcd.voxel_down_sample(voxel_size=3)
# 转回uint8(均值可能产生小数,需取整)
pcd_ds.point.labels = pcd_ds.point.labels.to(o3d.core.uint8)

补充说明

Open3D的voxel_down_sample对自定义属性默认执行均值聚合,但uint8类型的均值计算会因内部类型转换和广播逻辑触发错误。上述两种方法分别通过手动聚合或类型转换规避了问题,可根据标签的业务逻辑选择合适的聚合规则(众数、中位数、首个点标签等)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 22:22:45