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

Open3D中体素下采样DBSCAN聚类后标签映射回原始PCD的方法

问题:如何将体素下采样后的DBSCAN聚类标签映射回原始点云?

DBSCAN聚类对内存消耗极高,因此希望先对点云进行体素下采样,完成聚类计算后,再将得到的聚类结果近似关联回原始点云。以下是标准的体素下采样及聚类代码:

# examples/Python/Basic/pointcloud.py
import numpy as np
import open3d as o3d

if __name__ == "__main__":
    print("Load a ply point cloud, print it, and render it")
    pcd = o3d.io.read_point_cloud("../../TestData/fragment.ply")
    print(pcd)
    print(np.asarray(pcd.points))
    o3d.visualization.draw_geometries([pcd])

    print("Downsample the point cloud with a voxel of 0.05")
    downpcd = pcd.voxel_down_sample(voxel_size=0.05)
    o3d.visualization.draw_geometries([downpcd])

    # Then this could be clustered via dbscan
    labels = np.array(
            downpcd.cluster_dbscan(eps=0.05, min_points=30, print_progress=True))

请问如何将这些labels映射回原始PCD(pcd)?


解决方案

要实现标签映射,核心是在体素下采样时记录每个原始点对应的下采样点索引。Open3D提供的voxel_down_sample_and_trace函数可同时完成下采样并保留原始点与下采样点的对应关系,具体实现步骤如下:

1. 替换下采样函数,保留对应关系

用voxel_down_sample_and_trace替代普通的voxel_down_sample,该函数返回三个关键值:

  • 下采样后的点云(downpcd)
  • 每个原始点对应的下采样点索引数组(correspondences)
  • 每个体素内的原始点数量数组(voxel_counts)

2. 对下采样点云执行DBSCAN聚类

这一步与原代码逻辑一致,得到下采样点的聚类标签。

3. 将下采样点的标签映射到原始点

根据correspondences数组,将每个原始点对应的下采样点标签直接赋值给它即可。

完整代码示例

import numpy as np
import open3d as o3d
import matplotlib.pyplot as plt

if __name__ == "__main__":
    # 加载原始点云
    pcd = o3d.io.read_point_cloud("../../TestData/fragment.ply")
    
    # 体素下采样并记录原始点与下采样点的对应关系
    voxel_size = 0.05
    downpcd, correspondences, voxel_counts = pcd.voxel_down_sample_and_trace(
        voxel_size=voxel_size,
        min_bound=pcd.get_min_bound(),
        max_bound=pcd.get_max_bound()
    )
    
    # 对下采样点云执行DBSCAN聚类
    down_labels = np.array(
        downpcd.cluster_dbscan(eps=0.05, min_points=30, print_progress=True)
    )
    
    # 将标签映射回原始点云
    original_labels = np.full(len(pcd.points), -1, dtype=np.int32)
    for idx, corr in enumerate(correspondences):
        if corr != -1:
            original_labels[idx] = down_labels[corr]
    
    # 可视化验证:给原始点云按标签上色
    max_label = original_labels.max()
    color_map = plt.get_cmap("tab20")(original_labels / (max_label if max_label != -1 else 1))
    pcd.colors = o3d.utility.Vector3dVector(color_map[:, :3])
    o3d.visualization.draw_geometries([pcd])

说明

  • 映射逻辑为:同一个体素内的所有原始点,共享该体素中心(下采样点)的聚类标签,这是一种符合需求的近似关联方式。
  • 若下采样点被标记为噪声(标签为-1),则对应的所有原始点也会被标记为噪声。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.22 06:30:24