Advertisement
SUGIYAMA

☆don_segmantation

Jan 29th, 2014
82
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 6.20 KB | None | 0 0
  1. /**
  2.  * @file don_segmentation.cpp
  3.  * Difference of Normals Example for PCL Segmentation Tutorials.
  4.  *
  5.  * @author Yani Ioannou
  6.  * @date 2012-09-24
  7.  */
  8. #include <string>
  9.  
  10. #include <pcl/point_types.h>
  11. #include <pcl/io/pcd_io.h>
  12. #include <pcl/search/organized.h>
  13. #include <pcl/search/kdtree.h>
  14. #include <pcl/features/normal_3d_omp.h>
  15. #include <pcl/filters/conditional_removal.h>
  16. #include <pcl/segmentation/extract_clusters.h>
  17.  
  18. #include <pcl/features/don.h>
  19.  
  20. using namespace pcl;
  21. using namespace std;
  22.  
  23. int
  24. main (int argc, char *argv[])
  25. {
  26.   ///The smallest scale to use in the DoN filter.
  27.   double scale1;
  28.  
  29.   ///The largest scale to use in the DoN filter.
  30.   double scale2;
  31.  
  32.   ///The minimum DoN magnitude to threshold by
  33.   double threshold;
  34.  
  35.   ///segment scene into clusters with given distance tolerance using euclidean clustering
  36.   double segradius;
  37.  
  38.   if (argc < 6)
  39.   {
  40.     cerr << "usage: " << argv[0] << " inputfile smallscale largescale threshold segradius" << endl;
  41.     exit (EXIT_FAILURE);
  42.   }
  43.  
  44.   /// the file to read from.
  45.   string infile = argv[1];
  46.   /// small scale
  47.   istringstream (argv[2]) >> scale1;
  48.   /// large scale
  49.   istringstream (argv[3]) >> scale2;
  50.   istringstream (argv[4]) >> threshold;   // threshold for DoN magnitude
  51.   istringstream (argv[5]) >> segradius;   // threshold for radius segmentation
  52.  
  53.   // Load cloud in blob format
  54.   pcl::PCLPointCloud2 blob;
  55.   pcl::io::loadPCDFile (infile.c_str (), blob);
  56.   pcl::PointCloud<PointXYZRGB>::Ptr cloud (new pcl::PointCloud<PointXYZRGB>);
  57.   pcl::fromPCLPointCloud2 (blob, *cloud);
  58.  
  59.   // Create a search tree, use KDTreee for non-organized data.
  60.   pcl::search::Search<PointXYZRGB>::Ptr tree;
  61.   if (cloud->isOrganized ())
  62.   {
  63.     tree.reset (new pcl::search::OrganizedNeighbor<PointXYZRGB> ());
  64.   }
  65.   else
  66.   {
  67.     tree.reset (new pcl::search::KdTree<PointXYZRGB> (false));
  68.   }
  69.  
  70.   // Set the input pointcloud for the search tree
  71.   tree->setInputCloud (cloud);
  72.  
  73.   if (scale1 >= scale2)
  74.   {
  75.     cerr << "Error: Large scale must be > small scale!" << endl;
  76.     exit (EXIT_FAILURE);
  77.   }
  78.  
  79.   // Compute normals using both small and large scales at each point
  80.   pcl::NormalEstimationOMP<PointXYZRGB, PointNormal> ne;
  81.   ne.setInputCloud (cloud);
  82.   ne.setSearchMethod (tree);
  83.  
  84.   /**
  85.    * NOTE: setting viewpoint is very important, so that we can ensure
  86.    * normals are all pointed in the same direction!
  87.    */
  88.   ne.setViewPoint (std::numeric_limits<float>::max (), std::numeric_limits<float>::max (), std::numeric_limits<float>::max ());
  89.  
  90.   // calculate normals with the small scale
  91.   cout << "Calculating normals for scale..." << scale1 << endl;
  92.   pcl::PointCloud<PointNormal>::Ptr normals_small_scale (new pcl::PointCloud<PointNormal>);
  93.  
  94.   ne.setRadiusSearch (scale1);
  95.   ne.compute (*normals_small_scale);
  96.  
  97.   // calculate normals with the large scale
  98.   cout << "Calculating normals for scale..." << scale2 << endl;
  99.   pcl::PointCloud<PointNormal>::Ptr normals_large_scale (new pcl::PointCloud<PointNormal>);
  100.  
  101.   ne.setRadiusSearch (scale2);
  102.   ne.compute (*normals_large_scale);
  103.  
  104.   // Create output cloud for DoN results
  105.   PointCloud<PointNormal>::Ptr doncloud (new pcl::PointCloud<PointNormal>);
  106.   copyPointCloud<PointXYZRGB, PointNormal>(*cloud, *doncloud);
  107.  
  108.   cout << "Calculating DoN... " << endl;
  109.   // Create DoN operator
  110.   pcl::DifferenceOfNormalsEstimation<PointXYZRGB, PointNormal, PointNormal> don;
  111.   don.setInputCloud (cloud);
  112.   don.setNormalScaleLarge (normals_large_scale);
  113.   don.setNormalScaleSmall (normals_small_scale);
  114.  
  115.   if (!don.initCompute ())
  116.   {
  117.     std::cerr << "Error: Could not intialize DoN feature operator" << std::endl;
  118.     exit (EXIT_FAILURE);
  119.   }
  120.  
  121.   // Compute DoN
  122.   don.computeFeature (*doncloud);
  123.  
  124.   // Save DoN features
  125.   pcl::PCDWriter writer;
  126.   writer.write<pcl::PointNormal> ("don.pcd", *doncloud, false);
  127.  
  128.   // Filter by magnitude
  129.   cout << "Filtering out DoN mag <= " << threshold << "..." << endl;
  130.  
  131.   // Build the condition for filtering
  132.   pcl::ConditionOr<PointNormal>::Ptr range_cond (
  133.     new pcl::ConditionOr<PointNormal> ()
  134.     );
  135.   range_cond->addComparison (pcl::FieldComparison<PointNormal>::ConstPtr (
  136.                                new pcl::FieldComparison<PointNormal> ("curvature", pcl::ComparisonOps::GT, threshold))
  137.                              );
  138.   // Build the filter
  139.   pcl::ConditionalRemoval<PointNormal> condrem (range_cond);
  140.   condrem.setInputCloud (doncloud);
  141.  
  142.   pcl::PointCloud<PointNormal>::Ptr doncloud_filtered (new pcl::PointCloud<PointNormal>);
  143.  
  144.   // Apply filter
  145.   condrem.filter (*doncloud_filtered);
  146.  
  147.   doncloud = doncloud_filtered;
  148.  
  149.   // Save filtered output
  150.   std::cout << "Filtered Pointcloud: " << doncloud->points.size () << " data points." << std::endl;
  151.  
  152.   writer.write<pcl::PointNormal> ("don_filtered.pcd", *doncloud, false);
  153.  
  154.   // Filter by magnitude
  155.   cout << "Clustering using EuclideanClusterExtraction with tolerance <= " << segradius << "..." << endl;
  156.  
  157.   pcl::search::KdTree<PointNormal>::Ptr segtree (new pcl::search::KdTree<PointNormal>);
  158.   segtree->setInputCloud (doncloud);
  159.  
  160.   std::vector<pcl::PointIndices> cluster_indices;
  161.   pcl::EuclideanClusterExtraction<PointNormal> ec;
  162.  
  163.   ec.setClusterTolerance (segradius);
  164.   ec.setMinClusterSize (100);
  165.   ec.setMaxClusterSize (1000000);
  166.   ec.setSearchMethod (segtree);
  167.   ec.setInputCloud (doncloud);
  168.   ec.extract (cluster_indices);
  169.  
  170.   int j = 0;
  171.   for (std::vector<pcl::PointIndices>::const_iterator it = cluster_indices.begin (); it != cluster_indices.end (); ++it, j++)
  172.   {
  173.     pcl::PointCloud<PointNormal>::Ptr cloud_cluster_don (new pcl::PointCloud<PointNormal>);
  174.     for (std::vector<int>::const_iterator pit = it->indices.begin (); pit != it->indices.end (); pit++)
  175.     {
  176.       cloud_cluster_don->points.push_back (doncloud->points[*pit]);
  177.     }
  178.  
  179.     cloud_cluster_don->width = int (cloud_cluster_don->points.size ());
  180.     cloud_cluster_don->height = 1;
  181.     cloud_cluster_don->is_dense = true;
  182.  
  183.     //Save cluster
  184.     cout << "PointCloud representing the Cluster: " << cloud_cluster_don->points.size () << " data points." << std::endl;
  185.     stringstream ss;
  186.     ss << "don_cluster_" << j << ".pcd";
  187.     writer.write<pcl::PointNormal> (ss.str (), *cloud_cluster_don, false);
  188.   }
  189. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement