1、简介
PCL 的 Euclidean Cluster Extraction(欧几里得聚类提取) 是一种基于欧几里得距离的点云聚类算法。它的目标是将点云数据分割成多个独立的簇(clusters),每个簇代表一个独立的物体或结构。该算法通过计算点与点之间的欧几里得距离,将距离小于给定阈值的点归为同一个簇。
1.1 欧几里得聚类提取的原理
-
基于距离的聚类:
- 算法通过计算点云中每个点与其邻近点之间的欧几里得距离来判断它们是否属于同一个簇。
- 如果两个点之间的距离小于设定的阈值(
ClusterTolerance
),则认为它们属于同一个簇。
-
使用 KdTree 加速搜索:
- 为了高效地查找每个点的邻近点,算法使用 KdTree 数据结构来组织点云数据。
- KdTree 是一种空间划分数据结构,可以快速找到某个点附近的点。
-
聚类条件:
- 每个簇需要满足一定的点数范围:
- 最小点数(
MinClusterSize
):少于该点数的簇会被丢弃。 - 最大点数(
MaxClusterSize
):超过该点数的簇会被分割或丢弃。
- 最小点数(
- 每个簇需要满足一定的点数范围:
1.2 PCL 中 EuclideanClusterExtraction 的关键参数
在 PCL 中,pcl::EuclideanClusterExtraction
类用于实现欧几里得聚类提取。以下是其关键参数:
-
setClusterTolerance
:- 设置聚类的距离阈值。
- 例如,
setClusterTolerance(0.02)
表示两点之间的距离小于 2cm 时,它们属于同一个簇。
-
setMinClusterSize
:- 设置每个簇的最小点数。
- 例如,
setMinClusterSize(100)
表示点数少于 100 的簇会被丢弃。
-
setMaxClusterSize
:- 设置每个簇的最大点数。
- 例如,
setMaxClusterSize(25000)
表示点数超过 25000 的簇会被分割或丢弃。
-
setSearchMethod
:- 设置用于搜索邻近点的数据结构,通常是 KdTree。
- 例如,
setSearchMethod(tree)
,其中tree
是一个 KdTree 对象。
-
setInputCloud
:- 设置输入的点云数据。
-
extract
:- 执行聚类提取,结果存储在
std::vector<pcl::PointIndices>
中,每个pcl::PointIndices
表示一个簇。
- 执行聚类提取,结果存储在
1.3 欧几里得聚类提取的步骤
-
构建 KdTree:
- 使用点云数据构建 KdTree,以便快速查找邻近点。
-
遍历点云:
- 遍历点云中的每个点,找到其邻近点。
- 如果邻近点与当前点的距离小于阈值,则将它们归为同一个簇。
-
递归扩展簇:
- 对于每个邻近点,继续查找其邻近点,直到没有新的点可以加入当前簇。
-
过滤簇:
- 根据设定的最小点数和最大点数,过滤掉不符合条件的簇。
-
输出结果:
- 将每个簇的点云索引存储在
std::vector<pcl::PointIndices>
中。
- 将每个簇的点云索引存储在
2、代码示例
2.1 cluster_extraction.cpp
这段代码适用于处理3D点云数据,特别是在场景中分割平面和物体的应用中,代码主要包括点云的读取、滤波、平面分割、聚类以及保存聚类结果等步骤:
#include <pcl/ModelCoefficients.h>
#include <pcl/point_types.h>
#include <pcl/io/pcd_io.h>
#include <pcl/filters/extract_indices.h>
#include <pcl/filters/voxel_grid.h>
#include <pcl/features/normal_3d.h>
#include <pcl/search/kdtree.h>
#include <pcl/sample_consensus/method_types.h>
#include <pcl/sample_consensus/model_types.h>
#include <pcl/segmentation/sac_segmentation.h>
#include <pcl/segmentation/extract_clusters.h>
#include <iomanip> // for setw, setfill
int
main ()
{
// 读取点云数据
pcl::PCDReader reader;
pcl::PointCloud<pcl::PointXYZ>