本教程学习使用pcl::EuclideanClusterExtraction类进行欧几里得聚类提取。
欧几里得聚类原理:
聚类方法需要将一个无组织的点云模型p划分为更小的部分,从而大大减少了p的整体处理时间。
一种简单的欧几里德意义上的数据聚类方法可以通过使用固定宽度的盒子或一般的八叉树数据结构来实现。
然而,在更一般的意义上,我们可以利用最近邻并实现本质上类似于洪水填充算法的聚类技术。
假设有一个点云,有一张桌子和上面的物体。我们希望找到并分割位于平面上的单个物体点簇。假设我们使用 Kd 树结构来寻找最近的邻居,那么算法步骤将是:
1、为输入点云数据集p创建一个 Kd 树表示;
2、建立一个空的集群列表c,以及一个需要检查q的点的队列;
3、然后,对于p中的每一点,执行以下步骤:
- 将点添加到当前队列q;
- 对于每一个q中的点:
- 寻找半径为r球面的点邻域集合;
- 对于每个邻居,检查该点是否已被处理,如果未处理,则将其添加到q;
- 处理完q中的所有点的列表后,把q添加到群集列表c中,并重置q为空列表
4、当p中的所有点被处理完后并且都已经属于点集群c的一部分,算法停止。
源码:
创建 cluster_extraction.cpp 文件
1#include <pcl/ModelCoefficients.h>
2#include <pcl/point_types.h>
3#include <pcl/io/pcd_io.h>
4#include <pcl/filters/extract_indices.h>
5#include <pcl/filters/voxel_grid.h>
6#include <pcl/features/normal_3d.h>
7#include <pcl/search/kdtree.h>
8#include <pcl/sample_consensus/method_types.h>
9#include <pcl/sample_consensus/model_types.h>
10#include <pcl/segmentation/sac_segmentation.h>
11#include <pcl/segmentation/extract_clusters.h>
12
13
14int
15main ()
16{
17 // Read in the cloud data
18 pcl::PCDReader reader;
19 pcl::PointCloud<pcl::PointXYZ>::Ptr cloud (new pcl::PointCloud<pcl::PointXYZ>), cloud_f (new pcl::PointCloud<pcl::PointXYZ>);
20 reader.read ("table_scene_lms400.pcd", *cloud);
21 std::cout << "PointCloud before filtering has: " << cloud->size () << " data points." << std::endl; //*
22
23 // Create the filtering object: downsample the dataset using a leaf size of 1cm
24 pcl::VoxelGrid<pcl::PointXYZ> vg;
25 pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_filtered (new pcl::PointCloud<pcl::PointXYZ>);
26 vg.setInputCloud (cloud);
27 vg.setLeafSize (0.01f, 0.01f, 0.01f);
28 vg.filter (*cloud_filtered);
29 std::cout << "PointCloud after filtering has: " << cloud_filtered->size () << " data points." << std::endl; //*
30
31 // Create the segmentation object for the planar model and set all the parameters
32 pcl::SACSegmentation<pcl::PointXYZ> seg;
33 pcl::PointIndices::Ptr inliers (new pcl::PointIndices);
34 pcl::ModelCoefficients::Ptr coefficients (new pcl::ModelCoefficients);
35 pcl::PointCloud<pcl::PointXYZ>