PCL 基于欧几里得聚类的点云分割
这个程序可以提取出PCL点云里的欧式聚类从而分割点云。先看一下输入点云是一张桌子程序运行后会提取出欧几里得聚类如下图所示桌子本来是立体的现在只有个截面了下面是同时显示输入点云和输出点云的结果作为对比粉色的是输入点云其他颜色的是输出点云。输入table_scene_lms400.pcd PCL点云输出cloud_cluster_000X.pcd X个 PCL点云代码#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 () { // Read in the cloud data pcl::PCDReader reader; pcl::PointCloudpcl::PointXYZ::Ptr cloud (new pcl::PointCloudpcl::PointXYZ), cloud_f (new pcl::PointCloudpcl::PointXYZ); reader.read (table_scene_lms400.pcd, *cloud); std::cout PointCloud before filtering has: cloud-size () data points. std::endl; //* // Create the filtering object: downsample the dataset using a leaf size of 1cm pcl::VoxelGridpcl::PointXYZ vg; pcl::PointCloudpcl::PointXYZ::Ptr cloud_filtered (new pcl::PointCloudpcl::PointXYZ); vg.setInputCloud (cloud); vg.setLeafSize (0.01f, 0.01f, 0.01f); vg.filter (*cloud_filtered); std::cout PointCloud after filtering has: cloud_filtered-size () data points. std::endl; //* // Create the segmentation object for the planar model and set all the parameters pcl::SACSegmentationpcl::PointXYZ seg; pcl::PointIndices::Ptr inliers (new pcl::PointIndices); pcl::ModelCoefficients::Ptr coefficients (new pcl::ModelCoefficients); pcl::PointCloudpcl::PointXYZ::Ptr cloud_plane (new pcl::PointCloudpcl::PointXYZ ()); pcl::PCDWriter writer; seg.setOptimizeCoefficients (true); seg.setModelType (pcl::SACMODEL_PLANE); seg.setMethodType (pcl::SAC_RANSAC); seg.setMaxIterations (100); seg.setDistanceThreshold (0.02); int nr_points (int) cloud_filtered-size (); while (cloud_filtered-size () 0.3 * nr_points) { // Segment the largest planar component from the remaining cloud seg.setInputCloud (cloud_filtered); seg.segment (*inliers, *coefficients); if (inliers-indices.size () 0) { std::cout Could not estimate a planar model for the given dataset. std::endl; break; } // Extract the planar inliers from the input cloud pcl::ExtractIndicespcl::PointXYZ extract; extract.setInputCloud (cloud_filtered); extract.setIndices (inliers); extract.setNegative (false); // Get the points associated with the planar surface extract.filter (*cloud_plane); std::cout PointCloud representing the planar component: cloud_plane-size () data points. std::endl; // Remove the planar inliers, extract the rest extract.setNegative (true); extract.filter (*cloud_f); *cloud_filtered *cloud_f; } // Creating the KdTree object for the search method of the extraction pcl::search::KdTreepcl::PointXYZ::Ptr tree (new pcl::search::KdTreepcl::PointXYZ); tree-setInputCloud (cloud_filtered); std::vectorpcl::PointIndices cluster_indices; pcl::EuclideanClusterExtractionpcl::PointXYZ ec; ec.setClusterTolerance (0.02); // 2cm ec.setMinClusterSize (100); ec.setMaxClusterSize (25000); ec.setSearchMethod (tree); ec.setInputCloud (cloud_filtered); ec.extract (cluster_indices); int j 0; for (const auto cluster : cluster_indices) { pcl::PointCloudpcl::PointXYZ::Ptr cloud_cluster (new pcl::PointCloudpcl::PointXYZ); for (const auto idx : cluster.indices) { cloud_cluster-push_back((*cloud_filtered)[idx]); } //* cloud_cluster-width cloud_cluster-size (); cloud_cluster-height 1; cloud_cluster-is_dense true; std::cout PointCloud representing the Cluster: cloud_cluster-size () data points. std::endl; std::stringstream ss; ss std::setw(4) std::setfill(0) j; writer.writepcl::PointXYZ (cloud_cluster_ ss.str () .pcd, *cloud_cluster, false); //* j; } return (0); }参考Euclidean Cluster Extraction — Point Cloud Library 0.0 documentation