与平面分割类似,关于理论的东西不多阐释了,直接上代码:
- #include
- #include
-
- #include
// 模型系数的定义 - #include
- #include
// 各种点云数据类型 - #include
// 包含用于采样一致性算法的不同方法的定义,如RANSAC、MSAC等 - #include
// 包含用于采样一致性算法的不同模型的定义,如平面、球体、圆柱体 - #include
// 包含用于分割点云的采样一致性算法(SACSegmentation)的定义,用于识别点云的几何模型 - #include
// 包含用于从点云中提取特定索引的函数和类,用于根据索引提取点云中的子集 - #include
// 包含了用于可视化点云的函数和类,用于在3D视窗中现实点云数据 -
- #include
// 估计法线 - #include
// 直通滤波 -
-
- typedef pcl::PointXYZ PointT;
-
- int main(){
-
- // All the objectss needed
- pcl::PCDReader reader;
- pcl::PassThrough
pass; - pcl::NormalEstimation
ne; - pcl::SACSegmentationFromNormals
seg; -
- pcl::PCDWriter writer;
- pcl::ExtractIndices
extract; - pcl::ExtractIndices
extract_normals; - pcl::search::KdTree
::Ptr tree (new pcl::search::KdTree()) ; -
-
- // Datasets
- pcl::PointCloud
::Ptr cloud (new pcl::PointCloud) ; - pcl::PointCloud
::Ptr cloud_filtered (new pcl::PointCloud) ; - pcl::PointCloud
::Ptr cloud_filtered2 (new pcl::PointCloud) ; -
- pcl::PointCloud
::Ptr cloud_normals (new pcl::PointCloud) ; - pcl::PointCloud
::Ptr cloud_normals2 (new pcl::PointCloud) ; -
- pcl::ModelCoefficients::Ptr coefficients_plane (new pcl::ModelCoefficients), coefficients_cylinder (new pcl::ModelCoefficients);
- pcl::PointIndices::Ptr inliers_plane (new pcl::PointIndices), inliers_cylinder (new pcl::PointIndices);
-
- // Read in the cloud data
- reader.read("/home/lrj/work/pointCloudData/table_scene_mug_stereo_textured.pcd", *cloud);
- std::cerr << "PointCloud has: " << cloud->size() << " data points." << std::endl;
-
- // Build a passthrough filter to remove spurious NaNs and scene background
- pass.setInputCloud(cloud);
- pass.setFilterFieldName("z");
- pass.setFilterLimits(0, 1.5);
- pass.filter(*cloud_filtered);
- std::cerr << "PointCloud after filtering has: " << cloud_filtered->size() << " data points.\n";
-
- // Estimate point normals
- ne.setSearchMethod(tree);
- ne.setInputCloud(cloud_filtered);
- ne.setKSearch(50);
- ne.compute(*cloud_normals);
-
- // Create the segmentation object for the plannar model and set all the parameters
- seg.setOptimizeCoefficients(true);
- seg.setModelType(pcl::SACMODEL_NORMAL_PLANE);
- seg.setNormalDistanceWeight(0.1);
- seg.setMethodType(pcl::SAC_RANSAC);
- seg.setMaxIterations(100);
- seg.setDistanceThreshold(0.03);
- seg.setInputCloud(cloud_filtered);
- seg.setInputNormals(cloud_normals);
- // Obtain the plane inliers anda coefficients
- seg.segment(*inliers_plane, *coefficients_plane);
- std::cerr << "Plane coefficients: " << *coefficients_plane << std::endl;
-
- // Extract the planar inliers from the input cloud
- extract.setInputCloud(cloud_filtered);
- extract.setIndices(inliers_plane);
- extract.setNegative(false);
-
- // Wirte the planar inliers to disk
- pcl::PointCloud
::Ptr cloud_plane(new pcl::PointCloud()) ; - extract.filter(*cloud_plane);
- std::cerr << "PointCloud representing the planar component: " << cloud_plane->size() << " data points." << std::endl;
- writer.write("/home/lrj/work/pointCloudData/table_scene_mug_stereo_textured_plane.pcd", *cloud_plane, false);
-
- // Remove the planar inliers, extract the rest
- extract.setNegative(true);
- extract.filter(*cloud_filtered2);
-
- extract_normals.setNegative(true);
- extract_normals.setIndices(inliers_plane);
- extract_normals.filter(*cloud_normals2);
-
- // Create the segmentation object for cylinder segmentation and set all the parameters
- seg.setOptimizeCoefficients(true);
- seg.setMethodType(pcl::SACMODEL_CYLINDER);
- seg.setMethodType(pcl::SAC_RANSAC);
- seg.setNormalDistanceWeight(0.1);
- seg.setMaxIterations(10000);
- seg.setDistanceThreshold(0.05);
- seg.setRadiusLimits(0, 0.01);
- seg.setInputCloud(cloud_filtered2);
- seg.setInputNormals(cloud_normals2);
-
- // Obtain the cylinder inliers and coefficients
- seg.segment(*inliers_cylinder, *coefficients_cylinder);
- std::cerr << "Cylinder cofficients: " << *coefficients_cylinder << std::endl;
-
- // Write the cylinder inliers to disk
- extract.setInputCloud(cloud_filtered2);
- extract.setIndices(inliers_cylinder);
- extract.setNegative(false);
- pcl::PointCloud
::Ptr cloud_cylinder (new pcl::PointCloud ()) ; - extract.filter(*cloud_cylinder);
-
- if(cloud_cylinder->points.empty())
- std::cerr << "Can't find the cylindrical component." << std::endl;
- else
- {
- std::cerr << "PointCloud representing the cylindrical component: " << cloud_cylinder->size() << " data points.\n";
- writer.write("/home/lrj/work/pointCloudData/table_scene_mug_stereo_textured_cylinder.pcd", *cloud_cylinder, false);
- }
-
-
- return(0);
-
- }