c_polygon_representation.h
Go to the documentation of this file.
1 /**************************************************************************************************
2  Software License Agreement (BSD License)
3 
4  Copyright (c) 2011-2013, LAR toolkit developers - University of Aveiro - http://lars.mec.ua.pt
5  All rights reserved.
6 
7  Redistribution and use in source and binary forms, with or without modification, are permitted
8  provided that the following conditions are met:
9 
10  *Redistributions of source code must retain the above copyright notice, this list of
11  conditions and the following disclaimer.
12  *Redistributions in binary form must reproduce the above copyright notice, this list of
13  conditions and the following disclaimer in the documentation and/or other materials provided
14  with the distribution.
15  *Neither the name of the University of Aveiro nor the names of its contributors may be used to
16  endorse or promote products derived from this software without specific prior written permission.
17 
18  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
19  IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
20  FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
21  CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22  DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
24  IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
25  OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 ***************************************************************************************************/
34 #ifndef _C_POLYGON_REPRESENTATION_H_
35 #define _C_POLYGON_REPRESENTATION_H_
36 
37 //####################################################################
40 //
41 #include <ros/ros.h>
42 //#include <pcl/point_cloud.h>
43 #include <sensor_msgs/PointCloud2.h>
44 //#include <pcl/point_types.h>
45 //#include <ros/ros.h>
46 // PCL specific includes
47 #include <pcl/ros/conversions.h>
48 #include <pcl/point_cloud.h>
49 #include <pcl/point_types.h>
50 
51 #include <signal.h>
52 
53 
54 #include <stdio.h>
55 #include <stdlib.h>
56 #include <string.h>
57 
58 #include "config.h"
59 #include "config_util.h"
60 #include "eventlog.h"
61 #include "lcmtypes_velodyne_t.h"
62 #include "lcmtypes_pose_t.h"
63 #include "small_linalg.h"
64 #include "velodyne.h"
65 
66 #include <visualization_msgs/Marker.h>
67 
68 #include <cmath>
69 
70 #include <iostream>
71 #include <pcl/ModelCoefficients.h>
72 #include <pcl/io/pcd_io.h>
73 #include <pcl/point_types.h>
74 #include <pcl/sample_consensus/method_types.h>
75 #include <pcl/sample_consensus/model_types.h>
76 #include <pcl/segmentation/sac_segmentation.h>
77 #include <pcl/features/normal_3d.h>
78 #include <pcl/ModelCoefficients.h>
79 #include <pcl/io/pcd_io.h>
80 #include <pcl/point_types.h>
81 #include <pcl/features/normal_3d.h>
82 #include <pcl/filters/extract_indices.h>
83 #include <pcl/filters/passthrough.h>
84 #include <pcl/sample_consensus/method_types.h>
85 #include <pcl/sample_consensus/model_types.h>
86 #include <pcl/segmentation/sac_segmentation.h>
87 #include <pcl/filters/project_inliers.h>
88 
89 #include <pcl/filters/extract_indices.h>
90 #include <pcl/surface/convex_hull.h>
91 #include <pcl/ModelCoefficients.h>
92 #include <pcl/point_types.h>
93 #include <pcl/io/pcd_io.h>
94 #include <pcl/features/normal_3d.h>
95 #include <pcl/filters/extract_indices.h>
96 #include <pcl/filters/voxel_grid.h>
97 #include <pcl/kdtree/kdtree.h>
98 #include <pcl/sample_consensus/method_types.h>
99 #include <pcl/sample_consensus/model_types.h>
100 #include <pcl/segmentation/sac_segmentation.h>
101 #include <pcl/segmentation/extract_clusters.h>
102 
103 #include <pcl/segmentation/extract_polygonal_prism_data.h>
104 
105 //#include "pcl_ros/transforms.h"
106 #include "pcl_ros/segmentation/extract_polygonal_prism_data.h"
107 
108 typedef pcl::PointXYZ PointT;
109 #define _NUM_POLYGONS_ 5
110 #define _NUM_CLUSTERS_ 5
111 
112 
113 
115 {
116  pcl::PointCloud<PointT>::Ptr cloud;
117  ros::Publisher publisher;
118  char advertising_name[1024];
120 
121 
122 //Define the polygon class
124 {
125  public:
126 
128  c_polygon_representation(const char* name, ros::NodeHandle *node);
129 
132 
137 
139  {
141  ppc->cloud->header.frame_id = "/sensor_frame";
142  ppc->cloud->height = 1; //1 since its and unordered pc
143  ppc->cloud->is_dense=0;
144  ppc->cloud->width = ppc->cloud->size();
145 
146  pcl::toROSMsg(*ppc->cloud, cloud_msg);
147  ppc->publisher.publish(cloud_msg);
148  }
149 
150  // ------------------------------------------------------------------------------
151  //utility functions
152  // ------------------------------------------------------------------------------
153 
154  int indices_extraction(pcl::PointIndices::Ptr ind,
155  pcl::PointCloud<PointT> *input_cloud,
156  pcl::PointCloud<PointT> *remove_cloud,
157  pcl::PointCloud<PointT>::Ptr copy_cloud,
158  pcl::PointCloud<pcl::Normal> *input_normals,
159  pcl::PointCloud<pcl::Normal> *remove_normals)
160  {
161  if (input_cloud!=NULL) //if an input cloud is given
162  {
163  pcl::ExtractIndices<PointT> extract; //Create the extraction object
164  extract.setInputCloud(input_cloud->makeShared());
165  extract.setIndices(ind);
166 
167  //Copy to copy_cloud if not NULL
168  if(copy_cloud!=NULL)
169  {
170  extract.setNegative(false);
171  extract.filter(*copy_cloud);
172  }
173 
174  //Remove from remove if not NULL
175  if(remove_cloud!=NULL)
176  {
177  extract.setNegative(true);
178  extract.filter(*remove_cloud);
179  }
180  }
181 
182  if (input_normals!=NULL)
183  {
184  pcl::ExtractIndices<pcl::Normal> extract_normals; //Create the normal extraction object
185  extract_normals.setInputCloud(input_normals->makeShared());
186  extract_normals.setIndices(ind);
187 
188  if (remove_normals!=NULL)
189  {
190  extract_normals.setNegative(true);
191  extract_normals.filter(*remove_normals);
192  }
193  }
194 
195 
196 
197  return 1;}
198 
199  //Computes a new polygon candidate using RANSAC from a given pc with normals, ::PointIndices and removes inliers from the input cloud and normals.
200  void compute_plane_candidate_from_pc(pcl::PointCloud<PointT> *input_cloud,
201  pcl::PointCloud<pcl::Normal> *input_normals,
202  double DistanceThreshold = 0.5,
203  double NormalDistanceWeight = 0.5,
204  int MaxIterations = 1000
205  );
206 
208  {
209  project_cloud_to_plane(raw.cloud->makeShared());
210  }
211 
212  void project_cloud_to_plane(pcl::PointCloud<PointT>::Ptr input_cloud)
213  {
214  // Project the model inliers
215  pcl::ProjectInliers<pcl::PointXYZ> projection;
216 
217  projection.setModelType(pcl::SACMODEL_NORMAL_PLANE);
218  projection.setInputCloud(raw.cloud->makeShared());
219  projection.setModelCoefficients(coefficients);
220  projection.filter(*projected.cloud);
221 
222  }
223 
225  {
226  // Create a Convex Hull representation of the projected inliers
227  pcl::ConvexHull<pcl::PointXYZ> chull;
228  chull.setInputCloud(projected.cloud->makeShared());
229  chull.reconstruct(*convex_hull.cloud);
230  }
231 
232 
234  pcl::PointCloud<PointT> *input_cloud,
235  double DistanceThreshold,
236  int MaxIterations);
237 
238 
239  void compute_convex_hull_inliers(pcl::PointCloud<PointT> *input_cloud, pcl::PointCloud<pcl::Normal> *input_normals)
240  {
241  //Create variables
242  pcl::ExtractPolygonalPrismData<PointT> epp;
243  pcl::PointCloud<PointT>::ConstPtr input_cloud_constptr;
244  input_cloud_constptr.reset (new pcl::PointCloud<PointT> (*input_cloud));
245  pcl::PointCloud<PointT>::ConstPtr convex_hull_constptr;
246  convex_hull_constptr.reset (new pcl::PointCloud<PointT> (*convex_hull.cloud));
247  pcl::PointIndices::Ptr ind = pcl::PointIndices::Ptr(new pcl::PointIndices);
248  pcl::ExtractIndices<PointT> extract; //Create the extraction object
249 
250  //Start processing
251  ROS_INFO("Extracting Convex Hull inliers");
252  ROS_INFO("Input cloud has %d points",(int)input_cloud->size());
253 
254 
255  //Set epp parameters
256  epp.setInputCloud(input_cloud_constptr);
257  epp.setInputPlanarHull(convex_hull_constptr);
258  epp.setHeightLimits(-0.2, 0.2);
259  epp.setViewPoint(0,0,0);
260 
261  //Segment
262  epp.segment(*ind);
263 
264 
265  indices_extraction(ind,
266  input_cloud,
267  input_cloud,
269  input_normals,
270  input_normals);
271 
272 
273  //Extract the plane inliers from the input cloud. Generate raw.cloud
274  //extract.setInputCloud(input_cloud->makeShared());
275  //extract.setIndices (boost::make_shared<const pcl::PointIndices> (ind));
276  //extract.setIndices (ind);
277  //extract.setNegative(false);
278  //extract.filter(*additional.cloud);
279 
280  //Remove the plane inliers from the input_cloud
281  //extract.setNegative(true);
282  //extract.filter(*input_cloud);
283 
284  //Remove plane inliers from the input_normals
285  //pcl::ExtractIndices<pcl::Normal> extract_normals;
286  //extract_normals.setNegative (true);
287  //extract_normals.setInputCloud(input_normals->makeShared());
289  //extract_normals.setIndices(ind);
290  //extract_normals.filter(*input_normals);
291 
292  (*raw.cloud) += (*additional.cloud);
293 
294  //segment_plane_from_point_cloud(&raw.cloud, 3.0, 100);
295 
296  //Setup segmentation parameters
297  pcl::SACSegmentation<PointT> segmentation; // Create the segmentation object
298 
299  segmentation.setOptimizeCoefficients(true);
300  segmentation.setModelType(pcl::SACMODEL_PLANE);
301  segmentation.setMethodType (pcl::SAC_RANSAC);
302  segmentation.setMaxIterations (100);
303  segmentation.setDistanceThreshold(333);
304 
305  ROS_INFO("Indices before %d ...",(int)raw.cloud->size());
306 
307  //Compute a plane candidate from the point cloud
308  segmentation.setInputCloud(input_cloud->makeShared());
309  segmentation.segment(*indices, *coefficients);
310 
311  if (indices->indices.size () == 0)
312  {
313  ROS_ERROR("Could not estimate a planar model for the given dataset."); return;
314  }
315 
316  ROS_INFO("Found %d inliers of polygon",(int)additional.cloud->size());
317  ROS_INFO("Removed %d points from input_cloud. Now has %d points",(int)additional.cloud->size(),(int)input_cloud->size());
318 
319 
320  ROS_INFO("Extracting Convex Hull inliers done ...");
321  }
322 
323 //Build the condition
324 //pcl::ConditionAnd<PointT>::Ptr range_cond (new pcl::ConditionAnd<PointT> ());
325 //range_cond->addComparison (pcl::FieldComparison<PointT>::Ptr (new pcl::FieldComparison<PointT>("z", pcl::ComparisonOps::LT, 2.0)));
326 //range_cond->addComparison (pcl::FieldComparison<PointT>::Ptr (new pcl::FieldComparison<PointT>("z", pcl::ComparisonOps::GT, 0.0)));
327 
328 //Build the filter
329 //pcl::ConditionalRemoval<PointT> range_filt;
330 //range_filt.setCondition (range_cond);
331 //range_filt.setKeepOrganized (false);
332 
333 
334 
335  // Variables for polyplane segmentation and representation
336  pcl::ModelCoefficients::Ptr coefficients;
337  pcl::PointIndices::Ptr indices;
339  //pcl::PointCloud<PointT> cluster[_NUM_CLUSTERS_];
340 
341  private:
342 
343 
344  //sprintf(str, "plg_%d",i);
345  //pub[i] = n.advertise<sensor_msgs::PointCloud2>(str, 1);
346  ros::NodeHandle *rosnode;
347  char polygon_name[1024];
348  sensor_msgs::PointCloud2 cloud_msg;
349 
350 
351 //void pcl::SampleConsensusModelPlane< PointT >::optimizeModelCoefficients ( const std::vector< int > & inliers,
352  //const Eigen::VectorXf & model_coefficients,
353  //Eigen::VectorXf & optimized_coefficients
354  //) [virtual]
355 
356 
357 
358 
360  void set_names(const char* s)
361  {
362  sprintf(polygon_name,"%s",s);
363  sprintf(raw.advertising_name,"%s/raw",s);
364  sprintf(additional.advertising_name,"%s/additional",s);
365  sprintf(projected.advertising_name,"%s/projected",s);
366  sprintf(convex_hull.advertising_name,"%s/convex_hull",s);
367  }
368 
369 
371  void allocate_space(void);
372 
373 
374 
375 };
376 #endif
377 
380 /*Previous 3 lines appended automatically on Sun Feb 5 19:40:16 WET 2012 */
t_polygon_point_cloud additional
sensor_msgs::PointCloud2 cloud_msg
pcl::PointCloud< PointT >::Ptr cloud
void compute_plane_candidate_from_pc(pcl::PointCloud< PointT > *input_cloud, pcl::PointCloud< pcl::Normal > *input_normals, double DistanceThreshold=0.5, double NormalDistanceWeight=0.5, int MaxIterations=1000)
int indices_extraction(pcl::PointIndices::Ptr ind, pcl::PointCloud< PointT > *input_cloud, pcl::PointCloud< PointT > *remove_cloud, pcl::PointCloud< PointT >::Ptr copy_cloud, pcl::PointCloud< pcl::Normal > *input_normals, pcl::PointCloud< pcl::Normal > *remove_normals)
pcl::PointIndices::Ptr indices
pcl::PointXYZ PointT
void project_cloud_to_plane(pcl::PointCloud< PointT >::Ptr input_cloud)
~c_polygon_representation()
Destructor. free space of Ptr objecs.
pcl::ModelCoefficients::Ptr coefficients
struct tag_t_polygon_point_cloud t_polygon_point_cloud
void compute_convex_hull_inliers(pcl::PointCloud< PointT > *input_cloud, pcl::PointCloud< pcl::Normal > *input_normals)
t_polygon_point_cloud convex_hull
void publish_polygon_point_cloud(t_polygon_point_cloud *ppc)
c_polygon_representation(const char *name, ros::NodeHandle *node)
Constructor. Allocate space for Ptr objecs.
void segment_plane_from_point_cloud(pcl::PointCloud< PointT > *input_cloud, double DistanceThreshold, int MaxIterations)
void set_names(const char *s)
set names


polygon_primitives_extraction
Author(s): Miguel Oliveira
autogenerated on Mon Mar 2 2015 01:32:41