Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
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
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));
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_