organized_segmentation.hpp
Go to the documentation of this file.
00001   /*
00002   * Software License Agreement  (BSD License)
00003   *
00004   *  Point Cloud Library  (PCL) - www.pointclouds.org
00005   *  Copyright  (c) 2012, Jeremie Papon.
00006   *
00007   *  All rights reserved.
00008   *
00009   *  Redistribution and use in source and binary forms, with or without
00010   *  modification, are permitted provided that the following conditions
00011   *  are met:
00012   *
00013   *   * Redistributions of source code must retain the above copyright
00014   *     notice, this list of conditions and the following disclaimer.
00015   *   * Redistributions in binary form must reproduce the above
00016   *     copyright notice, this list of conditions and the following
00017   *     disclaimer in the documentation and/or other materials provided
00018   *     with the distribution.
00019   *   * Neither the name of Willow Garage, Inc. nor the names of its
00020   *     contributors may be used to endorse or promote products derived
00021   *     from this software without specific prior written permission.
00022   *
00023   *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00024   *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00025   *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
00026   *  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
00027   *  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
00028   *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES  (INCLUDING,
00029   *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00030   *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00031   *  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00032   *  LIABILITY, OR TORT  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
00033   *  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00034   *  POSSIBILITY OF SUCH DAMAGE.
00035   *
00036   */
00037  
00038  #ifndef IMPL_ORGANIZED_SEGMENTATION_HPP_
00039  #define IMPL_ORGANIZED_SEGMENTATION_HPP_
00040  
00041  #include <pcl/apps/cloud_composer/tools/organized_segmentation.h>
00042  #include <pcl/apps/cloud_composer/impl/cloud_item.hpp>
00043  #include <pcl/apps/cloud_composer/items/normals_item.h>
00044  #include <pcl/point_cloud.h>
00045  
00046  #include <pcl/segmentation/organized_multi_plane_segmentation.h>
00047  #include <pcl/segmentation/plane_coefficient_comparator.h>
00048  #include <pcl/segmentation/euclidean_plane_coefficient_comparator.h>
00049  #include <pcl/segmentation/rgb_plane_coefficient_comparator.h>
00050  #include <pcl/segmentation/edge_aware_plane_comparator.h>
00051  #include <pcl/segmentation/euclidean_cluster_comparator.h>
00052  #include <pcl/segmentation/organized_connected_component_segmentation.h>
00053  
00054  
00055  template <typename PointT> QList <pcl::cloud_composer::CloudComposerItem*>
00056  pcl::cloud_composer::OrganizedSegmentationTool::performTemplatedAction (QList <const CloudComposerItem*> input_data)
00057  {
00058    QList <CloudComposerItem*> output;  
00059    
00060    foreach (const CloudComposerItem* input_item, input_data)
00061    {
00062      QVariant variant = input_item->data (ItemDataRole::CLOUD_TEMPLATED);
00063      if ( ! variant.canConvert <typename PointCloud<PointT>::Ptr> () )
00064      {  
00065        qWarning () << "Attempted to cast to template type which does not exist in this item! (input list)";
00066        return output;
00067      }
00068      typename PointCloud <PointT>::Ptr input_cloud = variant.value <typename PointCloud<PointT>::Ptr> ();
00069      if ( ! input_cloud->isOrganized ())
00070      {
00071        qCritical () << "Organized Segmentation requires an organized cloud!";
00072        return output;
00073      }
00074    }
00075    
00076    int min_inliers = parameter_model_->getProperty ("Min Inliers").toInt ();
00077    int min_plane_size = parameter_model_->getProperty ("Min Plane Size").toInt ();
00078    double angular_threshold = parameter_model_->getProperty ("Angular Threshold").toDouble ();
00079    double distance_threshold = parameter_model_->getProperty ("Distance Threshold").toDouble ();
00080    double cluster_distance_threshold = parameter_model_->getProperty ("Cluster Dist. Thresh.").toDouble ();
00081    int min_cluster_size = parameter_model_->getProperty ("Min Cluster Size").toInt ();
00082    
00083    foreach (const CloudComposerItem* input_item, input_data)
00084    {
00085      QList <CloudComposerItem*> normals_list = input_item->getChildren (CloudComposerItem::NORMALS_ITEM);
00086      //Get the normals cloud, we just use the first normals that were found if there are more than one
00087      pcl::PointCloud<pcl::Normal>::ConstPtr input_normals = normals_list.value(0)->data(ItemDataRole::CLOUD_TEMPLATED).value <pcl::PointCloud<pcl::Normal>::ConstPtr> ();
00088      
00089      QVariant variant = input_item->data (ItemDataRole::CLOUD_TEMPLATED);
00090      typename PointCloud <PointT>::Ptr input_cloud = variant.value <typename PointCloud<PointT>::Ptr> ();
00091      
00092      pcl::OrganizedMultiPlaneSegmentation<PointT, pcl::Normal, pcl::Label> mps;
00093      mps.setMinInliers (min_inliers);
00094      mps.setAngularThreshold (pcl::deg2rad (angular_threshold)); // convert to radians
00095      mps.setDistanceThreshold (distance_threshold); 
00096      mps.setInputNormals (input_normals);
00097      mps.setInputCloud (input_cloud);
00098      std::vector<pcl::PlanarRegion<PointT>, Eigen::aligned_allocator<pcl::PlanarRegion<PointT> > > regions;
00099      std::vector<pcl::ModelCoefficients> model_coefficients;
00100      std::vector<pcl::PointIndices> inlier_indices;  
00101      pcl::PointCloud<pcl::Label>::Ptr labels (new pcl::PointCloud<pcl::Label>);
00102      std::vector<pcl::PointIndices> label_indices;
00103      std::vector<pcl::PointIndices> boundary_indices;
00104      mps.segmentAndRefine (regions, model_coefficients, inlier_indices, labels, label_indices, boundary_indices);
00105      
00106      std::vector<bool> plane_labels;
00107      plane_labels.resize (label_indices.size (), false);
00108      for (size_t i = 0; i < label_indices.size (); i++)
00109      {
00110        if (label_indices[i].indices.size () > min_plane_size)
00111        {
00112          plane_labels[i] = true;
00113        }
00114      }
00115      typename PointCloud<PointT>::CloudVectorType clusters;
00116      
00117      typename EuclideanClusterComparator<PointT, pcl::Normal, pcl::Label>::Ptr euclidean_cluster_comparator = boost::make_shared <EuclideanClusterComparator<PointT, pcl::Normal, pcl::Label> > ();
00118      euclidean_cluster_comparator->setInputCloud (input_cloud);
00119      euclidean_cluster_comparator->setLabels (labels);
00120      euclidean_cluster_comparator->setExcludeLabels (plane_labels);
00121      euclidean_cluster_comparator->setDistanceThreshold (cluster_distance_threshold, false);
00122      
00123      pcl::PointCloud<pcl::Label> euclidean_labels;
00124      std::vector<pcl::PointIndices> euclidean_label_indices;
00125      pcl::OrganizedConnectedComponentSegmentation<PointT,pcl::Label> euclidean_segmentation (euclidean_cluster_comparator);
00126      euclidean_segmentation.setInputCloud (input_cloud);
00127      euclidean_segmentation.segment (euclidean_labels, euclidean_label_indices);
00128      
00129      pcl::IndicesPtr extracted_indices (new std::vector<int> ());
00130      for (size_t i = 0; i < euclidean_label_indices.size (); i++)
00131      {
00132        if (euclidean_label_indices[i].indices.size () >= min_cluster_size)
00133        {
00134          typename PointCloud<PointT>::Ptr cluster = boost::make_shared <PointCloud<PointT> >();
00135          pcl::copyPointCloud (*input_cloud,euclidean_label_indices[i].indices,*cluster);
00136          qDebug () << "Found cluster with size " << cluster->width;
00137          QString name = input_item->text () + tr ("- Clstr %1").arg (i);
00138          CloudItem*  new_cloud_item = CloudItem::createCloudItemFromTemplate<PointT>(name,cluster);
00139          output.append (new_cloud_item);
00140          extracted_indices->insert (extracted_indices->end (), euclidean_label_indices[i].indices.begin (), euclidean_label_indices[i].indices.end ());
00141          
00142        }    
00143      }
00144      
00145      for (size_t i = 0; i < label_indices.size (); i++)
00146      {
00147        if (label_indices[i].indices.size () >= min_plane_size)
00148        {
00149          typename PointCloud<PointT>::Ptr plane = boost::make_shared <PointCloud<PointT> >();
00150          pcl::copyPointCloud (*input_cloud,label_indices[i].indices,*plane);
00151          qDebug () << "Found plane with size " << plane->width;
00152          QString name = input_item->text () + tr ("- Plane %1").arg (i);
00153          CloudItem*  new_cloud_item = CloudItem::createCloudItemFromTemplate<PointT>(name,plane);
00154          output.append (new_cloud_item);
00155          extracted_indices->insert (extracted_indices->end (), label_indices[i].indices.begin (), label_indices[i].indices.end ());
00156          
00157        }    
00158      }
00159      typename PointCloud<PointT>::Ptr leftovers = boost::make_shared <PointCloud<PointT> >();
00160      if (extracted_indices->size () == 0)
00161        pcl::copyPointCloud (*input_cloud,*leftovers);
00162      else
00163      {
00164        pcl::ExtractIndices<PointT> filter;
00165        filter.setInputCloud (input_cloud);
00166        filter.setIndices (extracted_indices);
00167        filter.setNegative (true);
00168        filter.filter (*leftovers);
00169      }
00170      CloudItem*  leftover_cloud_item = CloudItem::createCloudItemFromTemplate<PointT>(input_item->text(),leftovers);
00171      output.append (leftover_cloud_item);
00172    }
00173    
00174    
00175    
00176    
00177    return output;
00178    
00179  }
00180  
00181  
00182  #define PCL_INSTANTIATE_performTemplatedAction(T) template PCL_EXPORTS void pcl::cloud_composer::OrganizedSegmentationTool::performTemplatedAction<T> (QList <const CloudComposerItem*>);
00183  
00184  
00185  
00186  #endif //IMPL_TRANSFORM_CLOUDS_HPP_


pcl
Author(s): Open Perception
autogenerated on Wed Aug 26 2015 15:27:28