基于3D激光点云的障碍物检测与跟踪---(2)点云聚类
一、为什么要进行聚类(Clustering)
经过滤波、地面与障碍物点云分割后,这些点云混杂在同一个坐标空间,如果不进行聚类,就无法区分每个目标的范围与形状。
因此,我们的目标是:
将点云分成若干独立的“簇(Cluster)”,每个簇对应一个物体。
二、聚类算法原理 —— 欧式聚类(Euclidean Cluster Extraction)
2.1 基本思想
欧式聚类(Euclidean Cluster Extraction)是 PCL中最常用的聚类算法,核心思想是:
若两个点之间的欧式距离小于给定阈值,则它们属于同一个簇。
2.2 算法流程
- 构建 KD-Tree以加速邻域查询;
- 从任意未访问的点开始,搜索其邻域内所有距离小于阈值的点;
- 将这些点加入同一个簇;
- 对每个新加入的点重复步骤 2;
- 当没有更多邻点可加入时,当前簇结束;
- 继续处理下一个未访问点。
KdTree 是一种加速最近邻搜索的数据结构,聚类算法在计算“点之间的距离是否小于阈值”时会频繁使用它
2.3 算法复杂度
若使用暴力搜索(O(N²))会非常慢;
KD-Tree 将邻近搜索加速为 O(N·logN),使其可以实时处理十万级点云。
三、聚类核心代码
// 构建 KD 树加速搜索tree->setInputCloud(cloud);ec.setClusterTolerance(cluster_tolerance); // 聚类距离阈值ec.setMinClusterSize(min_size); // 聚类最小点云数量ec.setMaxClusterSize(max_size); // 聚类最大点云数量ec.setSearchMethod(tree);ec.setInputCloud(cloud);ec.extract(cluster_indices);
四、参数解析与调优建议
参数 | 含义 | 典型值(自动驾驶场景) | 调整效果 |
---|---|---|---|
cluster_tolerance | 点间聚类距离阈值 | 0.3 ~ 0.8 m | 越小越容易分裂簇 |
min_size | 最小簇点数 | 10 ~ 30 | 去除噪声小簇 |
max_size | 最大簇点数 | 10000 | 防止大簇占用全部点 |
🚀 一般根据激光雷达的点间距与障碍物密度调节
cluster_tolerance
。
比如:64线激光常取 0.5m 左右。
五、聚类后的障碍物特征提取
得到每个簇后,通常会进一步计算:
- 几何中心(Centroid)
- 体积尺寸(Bounding Box)
- 朝向角(通过 PCA 求主方向)
核心代码(轴对齐包围盒 AABB):
PointT min_pt, max_pt; // 点云簇在 X/Y/Z 三个方向的最小值和最大值
Eigen::Vector3f position((max_pt.x + min_pt.x) / 2,(max_pt.y + min_pt.y) / 2,(max_pt.z + min_pt.z) / 2);
Eigen::Vector3f dimension(max_pt.x - min_pt.x,max_pt.y - min_pt.y,max_pt.z - min_pt.z);
可用于绘制障碍物边界框或作为后续跟踪输入。
六、效果总结
阶段 | 点云数量 | 内容 | 效果 |
---|---|---|---|
滤波后 | ~35,000 | 含多类障碍物与噪声 | 无法直接区分物体 |
聚类后 | 各簇独立 | 每簇对应一个障碍物 | 可计算包围盒与分类 |
七、总结与展望
步骤 | 方法 | 主要目标 |
---|---|---|
1️⃣ 体素下采样 | VoxelGrid | 降低点云数量 |
2️⃣ ROI 区域裁剪 | CropBox | 保留感兴趣区域 |
3️⃣ 地面分割 | RANSAC | 去除地面点 |
4️⃣ 欧式聚类 | EuclideanClusterExtraction | 提取单个障碍物 |
经过聚类处理后,我们可以:
- 计算每个障碍物的三维包围盒;
- 进行目标跟踪、识别或动态检测;