共计 2049 个字符,预计需要花费 6 分钟才能阅读完成。
背景与痛点
点云聚类是自动驾驶感知系统的核心环节,直接影响障碍物检测的准确性。欧几里得聚类通过计算点之间的欧氏距离,将空间上相邻的点归为同一物体。但在实际应用中,开发者常遇到以下问题:
- 过分割:单一物体被拆分成多个小聚类(如卡车货箱和车头分离)
- 欠分割:不同物体被合并(如紧密停放的车辆群)
- 噪声敏感:雨雪、灰尘等环境噪声产生虚假聚类
算法原理
欧几里得聚类的数学表达:
d(p_i,p_j) = \sqrt{(x_i-x_j)^2 + (y_i-y_j)^2 + (z_i-z_j)^2} < ε
其中 ε 为 cluster_tolerance 参数。相比 DBSCAN,它无需密度参数,更适合规则形状的障碍物检测。

(图示:绿色点云通过距离阈值 ε 聚合成独立物体)
代码实战
C++ 实现(ROS2 Humble)
#include <pcl/segmentation/extract_clusters.h>
#include <pcl/kdtree/kdtree.h>
void euclideanCluster(
const pcl::PointCloud<pcl::PointXYZ>::Ptr& cloud,
float tolerance = 0.5,
int min_size = 20,
int max_size = 10000) {pcl::search::KdTree<pcl::PointXYZ>::Ptr tree(new pcl::search::KdTree<pcl::PointXYZ>);
tree->setInputCloud(cloud);
std::vector<pcl::PointIndices> cluster_indices;
pcl::EuclideanClusterExtraction<pcl::PointXYZ> ec;
ec.setClusterTolerance(tolerance); // 单位:米
ec.setMinClusterSize(min_size); // 最少点数
ec.setMaxClusterSize(max_size); // 最大点数
ec.setSearchMethod(tree);
ec.setInputCloud(cloud);
ec.extract(cluster_indices);
// 输出聚类结果
for (const auto& indices : cluster_indices) {pcl::PointCloud<pcl::PointXYZ>::Ptr cluster(new pcl::PointCloud<pcl::PointXYZ>);
pcl::copyPointCloud(*cloud, indices, *cluster);
// 发送到 ROS2 话题...
}
}
关键参数说明:
| 参数名 | 推荐值 | 作用 |
|——–|——–|——|
| cluster_tolerance | 0.3-1.0m | 距离阈值,越大聚类越宽松 |
| min_cluster_size | 10-50 点 | 过滤噪声形成的小聚类 |
| max_cluster_size | 5000+ 点 | 防止内存溢出 |
性能优化
- KD-Tree 加速:
- 使用
pcl::search::KdTree替代默认线性搜索 -
构建复杂度 O(n log n),查询复杂度 O(log n)
-
多线程处理:
#pragma omp parallel for for (int i = 0; i < cloud->size(); ++i) {// 并行化点云预处理} -
体素滤波预处理(Voxel Grid Filter):
- 先降采样到 0.1-0.3m 分辨率
- 可减少 50% 以上计算量
避坑指南
- 未做坐标变换:
- 必须将点云统一到车辆坐标系(base_link)
-
使用
tf2_ros::Buffer进行坐标转换 -
忽略地面点过滤:
- 推荐先使用
pcl::SACSegmentation移除地面 -
否则会导致地面点参与聚类
-
动态物体漏检:
- 对连续帧做跟踪匹配
-
使用
autoware_perception_msgs::DynamicObject消息类型 -
内存泄漏:
- 避免在回调函数中频繁 new/delete
-
使用
std::make_shared管理点云内存 -
参数固化:
- 不同雷达(Velodyne/OUSTER)需重新调参
- 建议保存为 ROS2 参数文件
延伸思考
- 多雷达适配:
- Velodyne HDL-64E:增大
cluster_tolerance(点密度低) -
OUSTER OS1-128:减小阈值(高线数雷达点密集)
-
进阶方案:
- 结合语义分割(如 PointNet++)提升聚类准确性
- 使用 GPU 加速(CUDA 版本的 PCL)
延伸阅读
- 《Segmentation of 3D Lidar Data in Non-flat Urban Environments》- IEEE 2009
- 《Real-Time Euclidean Cluster Extraction for Mobile Robots》- IROS 2015
- 《Autoware on Board: Enabling Autonomous Vehicles》- Springer 2018
正文完
