1.概述

1.1传统欧式聚类分割算法

        欧式聚类算法(Euclidean Clustering)是一种将点云数据分割成不同聚类(簇)的算法。它是点云分割中的一种常用方法,旨在将距离比较近的点分为同一簇,从而识别出不同的物体或结构。这个算法主要适用于包含较小噪音和具有一定距离差异的点云数据。基本思想:
(1)选择一个种子点(Seed Point)作为当前簇的起始点。
(2) 遍历所有未分类的点,计算它们与种子点的距离。如果距离小于设定的阈值,将其归为同一簇。
(3) 对于同一簇中的点,重复步骤2,将与当前簇内任一点距离小于阈值的点加入簇。
(4) 切换到下一个未分类的点,作为新的种子点,继续重复步骤2和3。
(5) 当所有点都被分类为某个簇,聚类过程结束。

常用的点云分割方法包括以下几种:

    基于几何特征的方法:这类方法主要通过计算点云的几何特征,如点的法线、曲率、曲率变化等来进行分割。常用的算法包括基于曲率阈值的分割、基于区域生长的分割等。

    基于聚类的方法:这类方法通过将点云中的点进行聚类来实现分割。常用的聚类算法包括K-means、DBSCAN和MeanShift等。聚类算法可以根据点的位置和特征将相似的点分到同一类别,从而实现分割。

    基于图论的方法:这类方法将点云看作是一个图,其中点是图的节点,点之间的关系(如距离或相似性)是图的边。通过在图上进行分割算法,如最小割和谱聚类等,可以实现点云的分割。

    基于深度学习的方法:近年来,深度学习在点云分割领域取得了很大的进展。深度学习模型可以通过学习点云的表示和特征,实现点云的自动分割。常用的深度学习模型包括PointNet、PointNet++、PointCNN和DGCNN等。

    这些方法在点云分割领域都有广泛的应用,并且各有特点和适用场景。根据具体的应用需求和点云数据的特点,选择适合的方法进行分割。

1.2改进的欧式聚类分割算法

       传统欧式聚类法分割实时性好,但容易出现欠分割与过分割的现象。针对这个问题,本文对传统的欧式聚类算法进行改进,利用平滑的阈值作为分割条件对分割过程进行限制,在保留较好的实时性的基础上,防止错误聚类情况。

       平滑度参数是用来描述物体表面的变化程度。

        当查询点位于光滑面上时,邻域点对称分布,因此平滑度 c 较小; 但是当查询点位于边缘时,领域内只有一个方向存在点,此时的平滑度 c 较大。因此,通过判断平滑度的大小,可以分辨查询点是否为边缘点。

2.代码实现

import open3d as o3d
import numpy as np
import os

# ------------------------------
# 1. 读取PCD点云文件
# ------------------------------
pcd = o3d.io.read_point_cloud("input.pcd")  # 替换为你的PCD文件路径
print("原始点云点数:", len(pcd.points))

# ------------------------------
# 2. 预处理(去噪)
# ------------------------------
# 使用统计滤波去除离群点
cl, ind = pcd.remove_statistical_outlier(nb_neighbors=20, std_ratio=2.0)
pcd = pcd.select_by_index(ind)
print("去噪后点数:", len(pcd.points))

# ------------------------------
# 3. 执行欧式聚类分割
# ------------------------------
# 将点云转换为数组
points = np.asarray(pcd.points)

# 使用Open3D的DBSCAN算法(基于欧式距离)
labels = np.array(pcd.cluster_dbscan(eps=0.02, min_points=50, print_progress=True))
max_label = labels.max()
print(f"发现 {max_label + 1} 个聚类")

# ------------------------------
# 4. 可视化聚类结果(不同颜色)
# ------------------------------
colors = np.random.rand(max_label + 1, 3)  # 随机颜色
colors[0] = [0, 0, 0]  # 噪声点设为黑色
pcd.colors = o3d.utility.Vector3dVector(colors[labels])

# 显示结果
o3d.visualization.draw_geometries([pcd])

# ------------------------------
# 5. 保存聚类结果(可选)
# ------------------------------
output_dir = "clusters"
os.makedirs(output_dir, exist_ok=True)

# 为每个聚类保存单独的PCD文件
for i in range(0, max_label + 1):
    cluster = pcd.select_by_index(np.where(labels == i)[0])
    o3d.io.write_point_cloud(f"{output_dir}/cluster_{i}.pcd", cluster)

3.结果输出

场景1:传统欧式聚类

 场景1:改进的欧式聚类

 场景2:传统欧式聚类

场景2:改进的欧式聚类 

 

Logo

DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。

更多推荐