PCL Point Cloud Segmentation (1)

Source: Internet
Author: User
Tags rand
Point Cloud Segmentation is based on the characteristics of space, geometry and texture to divide the point cloud, so that the same division within the point cloud has similar characteristics, point cloud effective segmentation is often the premise of many applications, such as reverse work, the CAD field of parts of the different scanning surface segmentation, and then to better the hole repair surface reconstruction, Feature description and extraction, and then the retrieval based on 3D content, combined reuse and so on.

Case analysis

Simple planar segmentation with a set of point cloud data:

Planar_segmentation.cpp

#include <iostream> #include <pcl/ModelCoefficients.h> #include <pcl/io/pcd_io.h> #include <pcl/ point_types.h> #include <pcl/sample_consensus/method_types.h>//Random parameter estimation method header file #include <pcl/sample_ consensus/model_types.h>//Model definition header file #include <pcl/segmentation/sac_segmentation.h>//header file for class based on sample consistency segmentation int Mai

  n (int argc, char** argv) {PCL::P OINTCLOUD&LT;PCL::P ointxyz>::P TR Cloud (New PCL::P OINTCLOUD&LT;PCL::P ointxyz>);
  Fill Point cloud Cloud->width = 15;
  Cloud->height = 1;

  Cloud->points.resize (Cloud->width * cloud->height); Generate data, fill the x, Y coordinates of the point cloud with random numbers, all on a plane with Z 1 for (size_t i = 0; i < cloud->points.size (); ++i) {cloud->points[i].
    x = 1024x768 * RAND ()/(Rand_max + 1.0f);
    CLOUD-&GT;POINTS[I].Y = 1024x768 * RAND ()/(Rand_max + 1.0f);
  CLOUD-&GT;POINTS[I].Z = 1.0;
  }//set several outliers, i.e. reset the z-values of several points to deviate from the plane cloud->points[0].z = 2.0 of z 1;
  Cloud->points[3].z =-2.0;

  CLOUD-&GT;POINTS[6].Z = 4.0; STD::Cerr << "Point cloud Data:" << cloud->points.size () << "points" << Std::endl; Print for (size_t i = 0; i < cloud->points.size (); ++i) Std::cerr << "" << Cloud->points[i] . x << "" << cloud->points[i].y << "<< Cloud
  ->points[i].z << Std::endl; The model factor object that is required to create the tessellation, coefficients and the point Index collection object for the stored point inliers pcl::modelcoefficients::P TR coefficients (new PCL::
  modelcoefficients);
  PCL::P ointindices::P tr inliers (new PCL::P ointindices);
  Create a Segmented object PCL::SACSEGMENTATION&LT;PCL::P ointxyz> seg;
  Optional configuration, set model coefficients need to optimize seg.setoptimizecoefficients (true);   The necessary configuration, sets the model type of the segmentation, uses the stochastic parameter estimation method, the distance threshold value, the input point cloud Seg.setmodeltype (Pcl::sacmodel_plane);      Set Model type Seg.setmethodtype (PCL::SAC_RANSAC);    Set the random sampling consistency method type Seg.setdistancethreshold (0.01); Setting the distance threshold, the distance threshold determines the condition that the point is considered to be an inside point,//the distance maximum of the point to the estimated model, Seg.setinputcloud(cloud);

  The coefficients coefficients seg.segment (*inliers, *coefficients) of the inliers and the storage plane model are obtained by the result of the segmentation implementation.
    if (inliers->indices.size () = = 0) {pcl_error ("Could not estimate a planar model for the given dataset.");
  Return (-1); 
                                      }//Print out plane model Std::cerr << "model coefficients:" << coefficients->values[0] << "" << Coefficients->values[1] << << Co EFFICIENTS-&GT;VALUES[2] << "<< coefficients->values[3" <<

  Std::endl;
  Std::cerr << "Model inliers:" << inliers->indices.size () << Std::endl; for (size_t i = 0; i < inliers->indices.size (); ++i) Std::cerr << inliers->indices[i] << "" << cloud->points[inliers->indices[i]].x << "" << C Loud->points[inliers->indices[i]]. Y << "" << cloud->points[inliers->indices[i]].z <&lt ;

  Std::endl;
return (0); }

The results are as follows: The data to be printed is manually added point cloud data, not all in the Z-1 plane, through the processing of the segmented object to extract all the inner points, that is, filter out the point set Z is not equal to 1

(2) to realize the segmentation of cylinder model: using random sampling consistency estimation to extract a cylinder model from a point cloud with noise.

New File Cylinder_segmentation.cpp

#include <pcl/ModelCoefficients.h> #include <pcl/io/pcd_io.h> #include <pcl/point_types.h> # Include <pcl/filters/extract_indices.h> #include <pcl/filters/passthrough.h> #include <pcl/features/ normal_3d.h> #include <pcl/sample_consensus/method_types.h> #include <pcl/sample_consensus/model_

types.h> #include <pcl/segmentation/sac_segmentation.h> typedef PCL::P OINTXYZ Pointt;                    int main (int argc, char** argv) {//All the objects needed PCL::P Cdreader Reader;             PCD file Read Object PCL::P assthrough<pointt> Pass;  Pass-through Filter object Pcl::normalestimation<pointt, pcl::normal> ne;    Normal Estimation object Pcl::sacsegmentationfromnormals<pointt, pcl::normal> seg;            Split Object PCL::P cdwriter writer;      PCD file Read Object pcl::extractindices<pointt> extract;    Point extracting object pcl::extractindices<pcl::normal> extract_normals; Point extract Object Pcl::search::kdtree<pointt>::P tr tree (new pcl::search::kdtree<

  Pointt> ());
  Datasets PCL::P ointcloud<pointt>::P TR Cloud (New PCL::P ointcloud<pointt>);
  PCL::P ointcloud<pointt>::P tr cloud_filtered (new PCL::P ointcloud<pointt>);
  PCL::P ointcloud<pcl::normal>::P tr cloud_normals (new PCL::P ointcloud<pcl::normal>);
  PCL::P ointcloud<pointt>::P tr Cloud_filtered2 (new PCL::P ointcloud<pointt>);
  PCL::P ointcloud<pcl::normal>::P tr cloud_normals2 (new PCL::P ointcloud<pcl::normal>); Pcl::modelcoefficients::P tr coefficients_plane (new pcl::modelcoefficients), Coefficients_cylinder (New PCL::
  modelcoefficients);

  PCL::P ointindices::P tr Inliers_plane (new PCL::P ointindices), Inliers_cylinder (new PCL::P ointindices);
  Read in the Cloud data reader.read ("TABLE_SCENE_MUG_STEREO_TEXTURED.PCD", *cloud);

  Std::cerr << "Pointcloud has:" << cloud->points.size () << "data points." << Std::endl; A pass-through filter that filters out points in the z-axis (0,1.5) range and stores the remaining points in the Cloud_filtered object pass.Setinputcloud (Cloud);
  Pass.setfilterfieldname ("Z");
  Pass.setfilterlimits (0, 1.5);
  Pass.filter (*cloud_filtered);  Std::cerr << "Pointcloud after filtering have:" << cloud_filtered->points.size () << "data points."

  << Std::endl;
  The filtered point cloud is estimated by normal, and the data Ne.setsearchmethod (tree) is prepared for the subsequent normal-based segmentation;
  Ne.setinputcloud (cloud_filtered);
  Ne.setksearch (50);

  Ne.compute (*cloud_normals);
  Create the segmentation object for the planar 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);
  Gets the coefficients of the plane model and the interior point of the plane seg.segment (*inliers_plane, *coefficients_plane);

  Std::cerr << "Plane coefficients:" << *coefficients_plane << Std::endl; Extracting a segmented plane from a point cloudPoint set Extract.setinputcloud (cloud_filtered);
  Extract.setindices (Inliers_plane);

  Extract.setnegative (FALSE);
  Store a split-point cloud file on a flat surface PCL::P ointcloud<pointt>::P tr Cloud_plane (new PCL::P ointcloud<pointt> ());
  Extract.filter (*cloud_plane); Std::cerr << "Pointcloud representing the planar component:" << cloud_plane->points.size () << "dat
  A points. "<< Std::endl;

  Writer.write ("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.setinputcloud (cloud_normals);
  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   );  Set the optimization Seg.setmodeltype (Pcl::sacmodel_cylinder) to the estimation model; Set the split model to cylindrical SEG.SEtmethodtype (PCL::SAC_RANSAC);       Parameter estimation method Seg.setnormaldistanceweight (0.1);              Set the surface normal weight coefficient seg.setmaxiterations (10000);         Sets the maximum number of iterations 10000 seg.setdistancethreshold (0.05);             Sets the distance within the point to the model to allow maximum seg.setradiuslimits (0, 0.1);
  Sets the radius range of the estimated cylinder model seg.setinputcloud (CLOUD_FILTERED2);

  Seg.setinputnormals (CLOUD_NORMALS2);
  Obtain the cylinder inliers and coefficients seg.segment (*inliers_cylinder, *coefficients_cylinder);

  Std::cerr << "Cylinder coefficients:" << *coefficients_cylinder << Std::endl;
  Write the cylinder inliers to disk extract.setinputcloud (CLOUD_FILTERED2);
  Extract.setindices (Inliers_cylinder);
  Extract.setnegative (FALSE);
  PCL::P ointcloud<pointt>::P tr Cloud_cylinder (new PCL::P ointcloud<pointt> ());
  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->points.size () &l
      t;< "data points." << Std::endl;
  Writer.write ("Table_scene_mug_stereo_textured_cylinder.pcd", *cloud_cylinder, false);
} return (0); }

The results of the test printing are as follows

The result of the original point cloud visualization. There are planes, cups, and other objects in the three-dimensional scene.

Create a split plane and a cylindrical point cloud, and view the results as follows

(3) The European clustering extraction is realized in PCL. Segmentation of a scene composed of three-dimensional point clouds

#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/kdtree/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>/************************************************************************** The point cloud data is opened, and the point cloud is filtered and re-sampled, then the point cloud is segmented by the plane segmentation model to extract all the point sets on the plane in the point cloud and save it ******************************************** /int main (int argc, char** argv) {//Read in the Cloud data PCL::P Cdreader Reade
  R PCL::P OINTCLOUD&LT;PCL::P ointxyz>::P TR Cloud (New PCL::P OINTCLOUD&LT;PCL::P ointxyz>), Cloud_f (New PCL::
  POINTCLOUD&LT;PCL::P ointxyz>);
Reader.read ("TABLE_SCENE_LMS400.PCD", *cloud);  Std::cout << "Pointcloud before filtering has:" << cloud->points.size () << "data points." &LT;&L T Std::endl; *//Create The filtering Object:downsample the dataset using a leaf size of 1cm PCL::VOXELGRID&LT;PCL::P OINTXYZ&G T
  Vg
  PCL::P OINTCLOUD&LT;PCL::P ointxyz>::P tr cloud_filtered (new PCL::P OINTCLOUD&LT;PCL::P ointxyz>);
  Vg.setinputcloud (Cloud);
  Vg.setleafsize (0.01f, 0.01f, 0.01f);
  Vg.filter (*cloud_filtered);  Std::cout << "Pointcloud after filtering have:" << cloud_filtered->points.size () << "data points." << Std::endl;
  *//Create plane model split objects and set parameters PCL::SACSEGMENTATION&LT;PCL::P ointxyz> seg;
  PCL::P ointindices::P tr inliers (new PCL::P ointindices);
  Pcl::modelcoefficients::P TR coefficients (new pcl::modelcoefficients);
  
  PCL::P OINTCLOUD&LT;PCL::P ointxyz>::P tr Cloud_plane (new PCL::P OINTCLOUD&LT;PCL::P ointxyz> ());
  PCL::P cdwriter writer;
  Seg.setoptimizecoefficients (TRUE); Seg.setmodeLType (Pcl::sacmodel_plane);       Segmentation model Seg.setmethodtype (PCL::SAC_RANSAC);                Stochastic parameter estimation method seg.setmaxiterations (100);           The maximum number of iterations seg.setdistancethreshold (0.02);
  Set the threshold int i=0, nr_points = (int) cloud_filtered->points.size (); while (Cloud_filtered->points.size () > 0.3 * nr_points) {//Segment the largest planar component from the RE
    Maining 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 data
      Set. "<< Std::endl;
    Break
    } PCL::EXTRACTINDICES&LT;PCL::P ointxyz> 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:" <&Lt

    Cloud_plane->points.size () << "data points." << Std::endl;
    Remove the plane point, extract the remaining point cloud extract.setnegative (true);
    Extract.filter (*cloud_f);
  *cloud_filtered = *cloud_f;  }//Creating the Kdtree object for the search method of the extraction PCL::SEARCH::KDTREE&LT;PCL::P ointxyz>::P TR
  Tree (new PCL::SEARCH::KDTREE&LT;PCL::P ointxyz>);

  Tree->setinputcloud (cloud_filtered);
  STD::VECTOR&LT;PCL::P ointindices> cluster_indices;   PCL::EUCLIDEANCLUSTEREXTRACTION&LT;PCL::P ointxyz> EC;                     European Cluster Object Ec.setclustertolerance (0.02);                 Set search radius of 2cm ec.setminclustersize (100) for neighbor search;               The minimum number of points required to set a cluster is ec.setmaxclustersize (25000);                    The maximum number of points required to set a cluster is 25000 ec.setsearchmethod (tree);
  Set the search mechanism for Point clouds ec.setinputcloud (cloud_filtered);           Ec.extract (cluster_indices);
  Extract the cluster from the point cloud and save the point Cloud Index in cluster_indices//iterate through the Access Point Cloud Index cluster_indices until all cluster int j = 0 is divided; for (std::veCTOR&LT;PCL::P Ointindices>::const_iterator it = Cluster_indices.begin (); It! = Cluster_indices.end ();
    ++it) {PCL::P OINTCLOUD&LT;PCL::P ointxyz>::P tr Cloud_cluster (new PCL::P OINTCLOUD&LT;PCL::P ointxyz>); for (Std::vector<int>::const_iterator pit = It->indices.begin (); Pit! = It->indices.end (); ++pit) c Loud_cluster->points.push_back (cloud_filtered->p

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.