organized_multi_plane_segmentation_nodelet.cpp
Go to the documentation of this file.
1 // -*- mode: C++ -*-
2 /*********************************************************************
3  * Software License Agreement (BSD License)
4  *
5  * Copyright (c) 2013, Ryohei Ueda and JSK Lab
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  *
12  * * Redistributions of source code must retain the above copyright
13  * notice, this list of conditions and the following disclaimer.
14  * * Redistributions in binary form must reproduce the above
15  * copyright notice, this list of conditions and the following
16  * disclaimer in the documentation and/or other materials provided
17  * with the distribution.
18  * * Neither the name of the JSK Lab nor the names of its
19  * contributors may be used to endorse or promote products derived
20  * from this software without specific prior written permission.
21  *
22  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
25  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
26  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
27  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
28  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
29  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
30  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
32  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
33  * POSSIBILITY OF SUCH DAMAGE.
34  *********************************************************************/
35 
37 #include "jsk_recognition_msgs/ModelCoefficientsArray.h"
38 #include <pcl/segmentation/impl/organized_multi_plane_segmentation.hpp>
39 #include <pcl/filters/extract_indices.h>
40 #include <pcl/kdtree/kdtree_flann.h>
41 #include <set>
42 #include <Eigen/StdVector>
43 #include <pcl/surface/convex_hull.h>
44 #include <pcl/filters/project_inliers.h>
45 #include <pcl/features/integral_image_normal.h>
46 
49 
50 #include <boost/format.hpp>
51 #include <pcl/common/centroid.h>
52 #include <visualization_msgs/Marker.h>
54 
55 #include <pcl/sample_consensus/method_types.h>
56 #include <pcl/sample_consensus/model_types.h>
57 #include <pcl/segmentation/sac_segmentation.h>
58 #include <pcl/surface/convex_hull.h>
59 
60 #include <jsk_topic_tools/color_utils.h>
61 
62 namespace jsk_pcl_ros
63 {
64 
66  {
67  ConnectionBasedNodelet::onInit();
68  previous_checked_connection_status_for_plane_ = jsk_topic_tools::NOT_SUBSCRIBED;
69  previous_checked_connection_status_for_normal_ = jsk_topic_tools::NOT_SUBSCRIBED;
70  pcl::console::setVerbosityLevel(pcl::console::L_ERROR);
72  // prepare diagnostics
75  diagnostic_updater_->setHardwareID(getName());
77  getName() + "::NormalEstimation",
78  boost::bind(
80  this,
81  _1));
83  getName() + "::PlaneSegmentation",
84  boost::bind(
86  this,
87  _1));
88  double vital_rate;
89  pnh_->param("vital_rate", vital_rate, 1.0);
91  new jsk_topic_tools::VitalChecker(1 / vital_rate));
93  new jsk_topic_tools::VitalChecker(1 / vital_rate));
94  estimate_normal_ = true;
95  pnh_->getParam("estimate_normal", estimate_normal_);
97  // prepare publishers
99  pub_ = advertise<jsk_recognition_msgs::ClusterPointIndices>(*pnh_, "output", 1);
100  polygon_pub_ = advertise<jsk_recognition_msgs::PolygonArray>(*pnh_, "output_polygon", 1);
102  = advertise<jsk_recognition_msgs::ModelCoefficientsArray>(*pnh_, "output_coefficients", 1);
103  org_pub_ = advertise<jsk_recognition_msgs::ClusterPointIndices>(*pnh_, "output_nonconnected", 1);
105  = advertise<jsk_recognition_msgs::PolygonArray>(*pnh_, "output_nonconnected_polygon", 1);
107  = advertise<jsk_recognition_msgs::ModelCoefficientsArray>(*pnh_,
108  "output_nonconnected_coefficients", 1);
109 
110  refined_pub_ = advertise<jsk_recognition_msgs::ClusterPointIndices>(*pnh_,
111  "output_refined", 1);
113  = advertise<jsk_recognition_msgs::PolygonArray>(*pnh_, "output_refined_polygon", 1);
115  = advertise<jsk_recognition_msgs::ModelCoefficientsArray>(*pnh_,
116  "output_refined_coefficients", 1);
117 
119  = advertise<visualization_msgs::Marker>(*pnh_,
120  "debug_connection_map", 1);
121 
122  if (estimate_normal_) {
124  = advertise<sensor_msgs::PointCloud2>(*pnh_, "output_normal", 1);
125  }
126 
127  srv_ = boost::make_shared <dynamic_reconfigure::Server<Config> > (*pnh_);
128  dynamic_reconfigure::Server<Config>::CallbackType f =
129  boost::bind (
131  srv_->setCallback (f);
132 
133  diagnostics_timer_ = pnh_->createTimer(
134  ros::Duration(1.0),
136  this,
137  _1));
138  onInitPostProcess();
139  }
140 
142  const std::vector<pcl::ModelCoefficients>& coefficients,
143  std::vector<pcl::ModelCoefficients>& output_coefficients)
144  {
145  output_coefficients.resize(coefficients.size());
146  for (size_t i = 0; i < coefficients.size(); i++) {
147  pcl::ModelCoefficients plane_coefficient = coefficients[i];
148  jsk_recognition_utils::Plane plane(coefficients[i].values);
149 
150  Eigen::Vector3f p = plane.getPointOnPlane();
151  Eigen::Vector3f n = plane.getNormal();
152  if (p.dot(n) < 0) {
153  output_coefficients[i] = plane_coefficient;
154  }
155  else {
156  jsk_recognition_utils::Plane flip = plane.flip();
157  pcl::ModelCoefficients new_coefficient;
158  flip.toCoefficients(new_coefficient.values);
159  output_coefficients[i] = new_coefficient;
160  }
161  }
162  }
163 
165  {
166  sub_ = pnh_->subscribe("input", 1,
168  }
169 
171  {
172  sub_.shutdown();
173  }
174 
175  void OrganizedMultiPlaneSegmentation::configCallback(Config &config, uint32_t level)
176  {
177  boost::mutex::scoped_lock lock(mutex_);
178  min_size_ = config.min_size;
179  angular_threshold_ = config.angular_threshold;
180  distance_threshold_ = config.distance_threshold;
181  max_curvature_ = config.max_curvature;
182  connect_plane_angle_threshold_ = config.connect_plane_angle_threshold;
183  connect_distance_threshold_ = config.connect_distance_threshold;
184  max_depth_change_factor_ = config.max_depth_change_factor;
185  normal_smoothing_size_ = config.normal_smoothing_size;
186  depth_dependent_smoothing_ = config.depth_dependent_smoothing;
187  estimation_method_ = config.estimation_method;
188  border_policy_ignore_ = config.border_policy_ignore;
189  publish_normal_ = config.publish_normal;
190  ransac_refine_coefficients_ = config.ransac_refine_coefficients;
192  = config.ransac_refine_outlier_distance_threshold;
193  min_refined_area_threshold_ = config.min_refined_area_threshold;
194  max_refined_area_threshold_ = config.max_refined_area_threshold;
195  //concave_alpha_ = config.concave_alpha;
196  }
197 
199  const pcl::PointCloud<PointT>::Ptr& input,
200  const std::vector<pcl::ModelCoefficients>& model_coefficients,
201  const std::vector<pcl::PointIndices>& boundary_indices,
203  {
204  NODELET_DEBUG("size of model_coefficients: %lu", model_coefficients.size());
205  if (model_coefficients.size() == 0) {
206  return; // do nothing
207  }
208 
209  if (model_coefficients.size() == 1) {
210  connection_map[0]= std::vector<int>();
211  return;
212  }
213 
214  pcl::ExtractIndices<PointT> extract;
215  extract.setInputCloud(input);
216  for (size_t i = 0; i < model_coefficients.size(); i++) {
217  // initialize connection_map[i]
218  connection_map[i] = std::vector<int>();
219  connection_map[i].push_back(i);
220  for (size_t j = i + 1; j < model_coefficients.size(); j++) {
221  // check if i and j can be connected
222  pcl::ModelCoefficients a_coefficient = model_coefficients[i];
223  pcl::ModelCoefficients b_coefficient = model_coefficients[j];
224  Eigen::Vector3f a_normal(a_coefficient.values[0], a_coefficient.values[1], a_coefficient.values[2]);
225  Eigen::Vector3f b_normal(b_coefficient.values[0], b_coefficient.values[1], b_coefficient.values[2]);
226  double a_distance = a_coefficient.values[3];
227  double b_distance = b_coefficient.values[3];
228  // force to check the coefficients is normalized
229  if (a_normal.norm() != 1.0) {
230  a_distance = a_distance / a_normal.norm();
231  a_normal = a_normal / a_normal.norm();
232  }
233  if (b_normal.norm() != 1.0) {
234  b_distance = b_distance / b_normal.norm();
235  b_normal = b_normal / b_normal.norm();
236  }
237  double theta = fabs(acos(a_normal.dot(b_normal)));
238  NODELET_DEBUG("%lu - %lu angle: %f", i, j, theta);
239  if (theta > M_PI / 2.0) {
240  theta = M_PI - theta;
241  }
242  if (theta > connect_plane_angle_threshold_) {
243  continue;
244  }
245  // the planes are near enough as a plane formula.
246 
247  // compute the distance between two boundaries.
248  // if they are near enough, we can regard these two map should connect
249 #if ( PCL_MAJOR_VERSION >= 1 && PCL_MINOR_VERSION >= 12 )
250  pcl::PointIndices::Ptr a_indices
251  = std::make_shared<pcl::PointIndices>(boundary_indices[i]);
252  pcl::PointIndices::Ptr b_indices
253  = std::make_shared<pcl::PointIndices>(boundary_indices[j]);
254 #else
255  pcl::PointIndices::Ptr a_indices
256  = boost::make_shared<pcl::PointIndices>(boundary_indices[i]);
257  pcl::PointIndices::Ptr b_indices
258  = boost::make_shared<pcl::PointIndices>(boundary_indices[j]);
259 #endif
260  pcl::PointCloud<PointT> a_cloud, b_cloud;
261  extract.setIndices(a_indices);
262  extract.filter(a_cloud);
263  extract.setIndices(b_indices);
264  extract.filter(b_cloud);
265  if (a_cloud.points.size() > 0) {
266  pcl::KdTreeFLANN<PointT> kdtree;
267  kdtree.setInputCloud(a_cloud.makeShared());
268  bool foundp = false;
269  for (size_t pi = 0; pi < b_cloud.points.size(); pi++) {
270  PointT p = b_cloud.points[pi];
271  std::vector<int> k_indices;
272  std::vector<float> k_sqr_distances;
273  if (kdtree.radiusSearch(
274  p, connect_distance_threshold_, k_indices, k_sqr_distances, 1) > 0) {
275  NODELET_DEBUG("%lu - %lu connected", i, j);
276  foundp = true;
277  break;
278  }
279  }
280  if (foundp) {
281  connection_map[i].push_back(j);
282  }
283  }
284  }
285  }
286  }
287 
289  const std::vector<pcl::PointIndices>& inlier_indices,
290  const std_msgs::Header& header,
291  jsk_recognition_msgs::ClusterPointIndices& output_indices)
292  {
293  for (size_t i = 0; i < inlier_indices.size(); i++) {
294  pcl::PointIndices inlier = inlier_indices[i];
295  PCLIndicesMsg one_indices;
296  one_indices.header = header;
297  one_indices.indices = inlier.indices;
298  output_indices.cluster_indices.push_back(one_indices);
299  }
300  }
301 
303  const pcl::PointCloud<PointT>& input,
304  geometry_msgs::Polygon& polygon)
305  {
306  for (size_t i = 0; i < input.points.size(); i++) {
307  geometry_msgs::Point32 point;
308  point.x = input.points[i].x;
309  point.y = input.points[i].y;
310  point.z = input.points[i].z;
311  polygon.points.push_back(point);
312  }
313  }
314 
316  const pcl::PointCloud<PointT>::Ptr& input,
317  const std_msgs::Header& header,
318  const std::vector<pcl::PointIndices>& inlier_indices,
319  const std::vector<pcl::PointIndices>& boundary_indices,
320  const std::vector<pcl::ModelCoefficients>& model_coefficients,
321  const jsk_recognition_utils::IntegerGraphMap& connection_map,
322  std::vector<pcl::PointIndices>& output_indices,
323  std::vector<pcl::ModelCoefficients>& output_coefficients,
324  std::vector<pcl::PointCloud<PointT> >& output_boundary_clouds)
325  {
326  std::vector<std::set<int> > cloud_sets;
327  NODELET_DEBUG("connection_map:");
328  for (jsk_recognition_utils::IntegerGraphMap::const_iterator it = connection_map.begin();
329  it != connection_map.end();
330  ++it) {
331  int from_index = it->first;
332  std::stringstream ss;
333  ss << "connection map: " << from_index << " [";
334  for (size_t i = 0; i < it->second.size(); i++) {
335  ss << i << ", ";
336  }
337  NODELET_DEBUG("%s", ss.str().c_str());
338  }
339 
340  jsk_recognition_utils::buildAllGroupsSetFromGraphMap(connection_map, cloud_sets);
341  connected_plane_num_counter_.add(cloud_sets.size());
342  for (size_t i = 0; i < cloud_sets.size(); i++) {
343  pcl::PointIndices one_indices;
344  pcl::PointIndices one_boundaries;
345  std::vector<float> new_coefficients;
346  new_coefficients.resize(4, 0);
347  for (std::set<int>::iterator it = cloud_sets[i].begin();
348  it != cloud_sets[i].end();
349  ++it) {
350  NODELET_DEBUG("%lu includes %d", i, *it);
351  new_coefficients = model_coefficients[*it].values;
352  pcl::PointIndices inlier = inlier_indices[*it];
353  pcl::PointIndices boundary_inlier = boundary_indices[*it];
354  // append indices...
355  one_indices = *jsk_recognition_utils::addIndices(one_indices, inlier);
356  one_boundaries = *jsk_recognition_utils::addIndices(one_boundaries, boundary_inlier);
357  }
358  if (one_indices.indices.size() == 0) {
359  continue;
360  }
361  // normalize coefficients
362  double norm = sqrt(new_coefficients[0] * new_coefficients[0]
363  + new_coefficients[1] * new_coefficients[1]
364  + new_coefficients[2] * new_coefficients[2]);
365  new_coefficients[0] /= norm;
366  new_coefficients[1] /= norm;
367  new_coefficients[2] /= norm;
368  new_coefficients[3] /= norm;
369 
370  // take the average of the coefficients
371  pcl::ModelCoefficients pcl_new_coefficients;
372  pcl_new_coefficients.values = new_coefficients;
373  // estimate concave hull
374 #if ( PCL_MAJOR_VERSION >= 1 && PCL_MINOR_VERSION >= 12 )
375  pcl::PointIndices::Ptr indices_ptr
376  = std::make_shared<pcl::PointIndices>(one_boundaries);
377  pcl::ModelCoefficients::Ptr coefficients_ptr
378  = std::make_shared<pcl::ModelCoefficients>(pcl_new_coefficients);
379 #else
380  pcl::PointIndices::Ptr indices_ptr
381  = boost::make_shared<pcl::PointIndices>(one_boundaries);
382  pcl::ModelCoefficients::Ptr coefficients_ptr
383  = boost::make_shared<pcl::ModelCoefficients>(pcl_new_coefficients);
384 #endif
386  = jsk_recognition_utils::convexFromCoefficientsAndInliers<PointT>(
387  input, indices_ptr, coefficients_ptr);
388  if (convex) {
389  pcl::PointCloud<PointT> chull_output;
390  convex->boundariesToPointCloud<PointT>(chull_output);
391  output_indices.push_back(one_indices);
392  output_coefficients.push_back(pcl_new_coefficients);
393  output_boundary_clouds.push_back(chull_output);
394  }
395  else {
396  NODELET_ERROR("failed to build convex");
397  }
398  }
399 
400  }
401 
403  // simple PCL wrapper
406  pcl::PointCloud<PointT>::Ptr input,
407  pcl::PointCloud<pcl::Normal>::Ptr normal,
408  PlanarRegionVector& regions,
409  std::vector<pcl::ModelCoefficients>& model_coefficients,
410  std::vector<pcl::PointIndices>& inlier_indices,
411  pcl::PointCloud<pcl::Label>::Ptr& labels,
412  std::vector<pcl::PointIndices>& label_indices,
413  std::vector<pcl::PointIndices>& boundary_indices)
414  {
416  pcl::OrganizedMultiPlaneSegmentation<PointT, pcl::Normal, pcl::Label> mps;
417  mps.setMinInliers(min_size_);
418  mps.setAngularThreshold(angular_threshold_);
419  mps.setDistanceThreshold(distance_threshold_);
420  mps.setMaximumCurvature(max_curvature_);
421  mps.setInputCloud(input);
422  mps.setInputNormals(normal);
423  {
424  jsk_topic_tools::ScopedTimer timer = plane_segmentation_time_acc_.scopedTimer();
425  mps.segmentAndRefine(
426  regions, model_coefficients, inlier_indices,
427  labels, label_indices, boundary_indices);
428  }
429  }
430 
432  const std_msgs::Header& header,
433  const pcl::PointCloud<PointT>::Ptr input,
434  ros::Publisher& indices_pub,
435  ros::Publisher& polygon_pub,
437  const std::vector<pcl::PointIndices>& inlier_indices,
438  const std::vector<pcl::PointCloud<PointT> >& boundaries,
439  const std::vector<pcl::ModelCoefficients>& model_coefficients)
440  {
441  jsk_recognition_msgs::ClusterPointIndices indices;
442  jsk_recognition_msgs::ModelCoefficientsArray coefficients_array;
443  jsk_recognition_msgs::PolygonArray polygon_array;
444  indices.header = header;
445  polygon_array.header = header;
446  coefficients_array.header = header;
447 
449  // publish inliers
451  pclIndicesArrayToClusterPointIndices(inlier_indices, header, indices);
452  indices_pub.publish(indices);
453 
455  // boundaries as polygon
457  for (size_t i = 0; i < boundaries.size(); i++) {
458  geometry_msgs::PolygonStamped polygon;
459  pcl::PointCloud<PointT> boundary_cloud = boundaries[i];
460  pointCloudToPolygon(boundary_cloud, polygon.polygon);
461  polygon.header = header;
462  polygon_array.polygons.push_back(polygon);
463  }
464  polygon_pub.publish(polygon_array);
465 
467  // publish coefficients
469  for (size_t i = 0; i < model_coefficients.size(); i++) {
470  PCLModelCoefficientMsg coefficient;
471  coefficient.values = model_coefficients[i].values;
472  coefficient.header = header;
473  coefficients_array.coefficients.push_back(coefficient);
474  }
475  coefficients_pub.publish(coefficients_array);
476  }
477 
479  const std_msgs::Header& header,
480  const pcl::PointCloud<PointT>::Ptr input,
481  ros::Publisher& indices_pub,
482  ros::Publisher& polygon_pub,
484  const std::vector<pcl::PointIndices>& inlier_indices,
485  const std::vector<pcl::PointIndices>& boundary_indices,
486  const std::vector<pcl::ModelCoefficients>& model_coefficients)
487  {
488  // convert boundary_indices into boundary pointcloud
489  std::vector<pcl::PointCloud<PointT> > boundaries;
490  pcl::ExtractIndices<PointT> extract;
491  extract.setInputCloud(input);
492  for (size_t i = 0; i < boundary_indices.size(); i++) {
493  pcl::PointCloud<PointT> boundary_cloud;
494  pcl::PointIndices boundary_one_indices = boundary_indices[i];
495 #if ( PCL_MAJOR_VERSION >= 1 && PCL_MINOR_VERSION >= 12 )
496  pcl::PointIndices::Ptr indices_ptr = std::make_shared<pcl::PointIndices>(boundary_indices[i]);
497 #else
498  pcl::PointIndices::Ptr indices_ptr = boost::make_shared<pcl::PointIndices>(boundary_indices[i]);
499 #endif
500  extract.setIndices(indices_ptr);
501  extract.filter(boundary_cloud);
502  boundaries.push_back(boundary_cloud);
503  }
504 
506  header, input, indices_pub, polygon_pub, coefficients_pub,
507  inlier_indices, boundaries, model_coefficients);
508  }
509 
512  const pcl::PointCloud<PointT>::Ptr cloud,
513  const std::vector<pcl::PointIndices>& inliers,
514  const std_msgs::Header& header)
515  {
517  // visualize connection as lines
519  visualization_msgs::Marker connection_marker;
520  connection_marker.type = visualization_msgs::Marker::LINE_LIST;
521  connection_marker.scale.x = 0.01;
522  connection_marker.header = header;
523  connection_marker.pose.orientation.w = 1.0;
524  connection_marker.color = jsk_topic_tools::colorCategory20(0);
525 
527  // first, compute centroids for each clusters
530  for (size_t i = 0; i < inliers.size(); i++) {
531 #if ( PCL_MAJOR_VERSION >= 1 && PCL_MINOR_VERSION >= 12 )
532  pcl::PointIndices::Ptr target_inliers
533  = std::make_shared<pcl::PointIndices>(inliers[i]);
534 #else
535  pcl::PointIndices::Ptr target_inliers
536  = boost::make_shared<pcl::PointIndices>(inliers[i]);
537 #endif
538  pcl::PointCloud<PointT>::Ptr target_cloud (new pcl::PointCloud<PointT>);
539  Eigen::Vector4f centroid;
540  pcl::ExtractIndices<PointT> ex;
541  ex.setInputCloud(cloud);
542  ex.setIndices(target_inliers);
543  ex.filter(*target_cloud);
544  pcl::compute3DCentroid(*target_cloud, centroid);
545  Eigen::Vector3f centroid_3f(centroid[0], centroid[1], centroid[2]);
546  centroids.push_back(centroid_3f);
547  }
548 
549  for (jsk_recognition_utils::IntegerGraphMap::iterator it = connection_map.begin();
550  it != connection_map.end();
551  ++it) {
552  // from = i
553  int from_index = it->first;
554  std::vector<int> the_connection_map = connection_map[from_index];
555  for (size_t j = 0; j < the_connection_map.size(); j++) {
556  int to_index = the_connection_map[j];
557  //std::cout << "connection: " << from_index << " --> " << to_index << std::endl;
558  Eigen::Vector3f from_point = centroids[from_index];
559  Eigen::Vector3f to_point = centroids[to_index];
560  geometry_msgs::Point from_point_ros, to_point_ros;
561  jsk_recognition_utils::pointFromVectorToXYZ<Eigen::Vector3f, geometry_msgs::Point>(
562  from_point, from_point_ros);
563  jsk_recognition_utils::pointFromVectorToXYZ<Eigen::Vector3f, geometry_msgs::Point>(
564  to_point, to_point_ros);
565  connection_marker.points.push_back(from_point_ros);
566  connection_marker.points.push_back(to_point_ros);
567  connection_marker.colors.push_back(jsk_topic_tools::colorCategory20(from_index));
568  connection_marker.colors.push_back(jsk_topic_tools::colorCategory20(from_index));
569  }
570  }
571  pub_connection_marker_.publish(connection_marker);
572  }
573 
575  pcl::PointCloud<PointT>::Ptr input,
576  pcl::PointCloud<pcl::Normal>::Ptr normal,
577  const std_msgs::Header& header)
578  {
579  PlanarRegionVector regions;
580  std::vector<pcl::ModelCoefficients> model_coefficients;
581  std::vector<pcl::PointIndices> inlier_indices;
582  pcl::PointCloud<pcl::Label>::Ptr labels (new pcl::PointCloud<pcl::Label>());
583  std::vector<pcl::PointIndices> label_indices;
584  std::vector<pcl::PointIndices> boundary_indices;
586  // segment planes based on pcl's organized multi plane
587  // segmentation.
589  segmentOrganizedMultiPlanes(input, normal, regions, model_coefficients,
590  inlier_indices, labels, label_indices,
591  boundary_indices);
592  std::vector<pcl::ModelCoefficients> fixed_model_coefficients;
593  forceToDirectOrigin(model_coefficients, fixed_model_coefficients);
594  model_coefficients = fixed_model_coefficients;
595 
596  original_plane_num_counter_.add(regions.size());
598  header, input,
600  inlier_indices, boundary_indices, model_coefficients);
601 
603  // segmentation by PCL organized multiplane segmentation
604  // is not enough. we "connect" planes like graph problem.
607  connectPlanesMap(input, model_coefficients, boundary_indices, connection_map);
608  publishMarkerOfConnection(connection_map, input, inlier_indices, header);
609  std::vector<pcl::PointIndices> output_nonrefined_indices;
610  std::vector<pcl::ModelCoefficients> output_nonrefined_coefficients;
611  std::vector<pcl::PointCloud<PointT> > output_nonrefined_boundary_clouds;
613  inlier_indices,
614  boundary_indices,
615  model_coefficients,
616  connection_map,
617  output_nonrefined_indices,
618  output_nonrefined_coefficients,
619  output_nonrefined_boundary_clouds);
620  std::vector<pcl::ModelCoefficients> fixed_output_nonrefined_coefficients;
621  forceToDirectOrigin(output_nonrefined_coefficients, fixed_output_nonrefined_coefficients);
622  output_nonrefined_coefficients = fixed_output_nonrefined_coefficients;
624  header, input,
626  output_nonrefined_indices,
627  output_nonrefined_boundary_clouds,
628  output_nonrefined_coefficients);
630  // refine coefficients based on RANSAC
633  std::vector<pcl::PointIndices> refined_inliers;
634  std::vector<pcl::ModelCoefficients> refined_coefficients;
635  std::vector<jsk_recognition_utils::ConvexPolygon::Ptr> refined_convexes;
637  input, output_nonrefined_indices, output_nonrefined_coefficients,
638  refined_inliers, refined_coefficients, refined_convexes);
639  std::vector<pcl::PointCloud<PointT> > refined_boundary_clouds;
640  for (size_t i = 0; i < refined_convexes.size(); i++) {
641  pcl::PointCloud<PointT> refined_boundary;
642  refined_convexes[i]->boundariesToPointCloud(refined_boundary);
643  refined_boundary_clouds.push_back(refined_boundary);
644  }
645  std::vector<pcl::ModelCoefficients> fixed_refined_coefficients;
646  forceToDirectOrigin(refined_coefficients, fixed_refined_coefficients);
647  refined_coefficients = fixed_refined_coefficients;
649  header, input,
651  refined_inliers, refined_boundary_clouds, refined_coefficients);
652  }
653  }
654 
656  const pcl::PointCloud<PointT>::Ptr input,
657  const std::vector<pcl::PointIndices>& input_indices,
658  const std::vector<pcl::ModelCoefficients>& input_coefficients,
659  std::vector<pcl::PointIndices>& output_indices,
660  std::vector<pcl::ModelCoefficients>& output_coefficients,
661  std::vector<jsk_recognition_utils::ConvexPolygon::Ptr>& output_convexes)
662  {
663  jsk_topic_tools::ScopedTimer timer
664  = ransac_refinement_time_acc_.scopedTimer();
665  for (size_t i = 0; i < input_indices.size(); i++) {
666 #if ( PCL_MAJOR_VERSION >= 1 && PCL_MINOR_VERSION >= 12 )
667  pcl::PointIndices::Ptr input_indices_ptr
668  = std::make_shared<pcl::PointIndices>(input_indices[i]);
669 #else
670  pcl::PointIndices::Ptr input_indices_ptr
671  = boost::make_shared<pcl::PointIndices>(input_indices[i]);
672 #endif
673  Eigen::Vector3f normal(input_coefficients[i].values[0],
674  input_coefficients[i].values[1],
675  input_coefficients[i].values[2]);
676  normal.normalize();
678  // run RANSAC
680  pcl::SACSegmentation<PointT> seg;
681  seg.setOptimizeCoefficients (true);
682  seg.setModelType (pcl::SACMODEL_PERPENDICULAR_PLANE);
683  seg.setMethodType (pcl::SAC_RANSAC);
684  seg.setDistanceThreshold (ransac_refine_outlier_distance_threshold_);
685  seg.setInputCloud(input);
686  seg.setIndices(input_indices_ptr);
687  seg.setMaxIterations (10000);
688  seg.setAxis(normal);
689  seg.setEpsAngle(pcl::deg2rad(20.0));
690  pcl::PointIndices::Ptr refined_inliers (new pcl::PointIndices);
691  pcl::ModelCoefficients::Ptr refined_coefficients(new pcl::ModelCoefficients);
692  seg.segment(*refined_inliers, *refined_coefficients);
693  if (refined_inliers->indices.size() > 0) {
695  // compute boundaries from convex hull of
697  jsk_recognition_utils::ConvexPolygon::Ptr convex = jsk_recognition_utils::convexFromCoefficientsAndInliers<PointT>(
698  input, refined_inliers, refined_coefficients);
699  if (convex) {
700  // check area threshold
701  double area = convex->area();
702  if (area > min_refined_area_threshold_ &&
704  output_convexes.push_back(convex);
705  output_indices.push_back(*refined_inliers);
706  output_coefficients.push_back(*refined_coefficients);
707  }
708  }
709  }
710  }
711  }
712 
713  void OrganizedMultiPlaneSegmentation::estimateNormal(pcl::PointCloud<PointT>::Ptr input,
714  pcl::PointCloud<pcl::Normal>::Ptr output)
715  {
716  jsk_topic_tools::ScopedTimer timer = normal_estimation_time_acc_.scopedTimer();
717  pcl::IntegralImageNormalEstimation<PointT, pcl::Normal> ne;
718  if (estimation_method_ == 0) {
719  ne.setNormalEstimationMethod (ne.AVERAGE_3D_GRADIENT);
720  }
721  else if (estimation_method_ == 1) {
722  ne.setNormalEstimationMethod (ne.COVARIANCE_MATRIX);
723  }
724  else if (estimation_method_ == 2) {
725  ne.setNormalEstimationMethod (ne.AVERAGE_DEPTH_CHANGE);
726  }
727  else {
728  NODELET_FATAL("unknown estimation method, force to use COVARIANCE_MATRIX: %d",
730  ne.setNormalEstimationMethod (ne.COVARIANCE_MATRIX);
731  }
732 
733  if (border_policy_ignore_) {
734  ne.setBorderPolicy(pcl::IntegralImageNormalEstimation<PointT, pcl::Normal>::BORDER_POLICY_IGNORE);
735  }
736  else {
737  ne.setBorderPolicy(pcl::IntegralImageNormalEstimation<PointT, pcl::Normal>::BORDER_POLICY_MIRROR);
738  }
739 
740  ne.setMaxDepthChangeFactor(max_depth_change_factor_);
741  ne.setNormalSmoothingSize(normal_smoothing_size_);
742  ne.setDepthDependentSmoothing(depth_dependent_smoothing_);
743  ne.setInputCloud(input);
744  ne.compute(*output);
745  }
746 
748  (const sensor_msgs::PointCloud2::ConstPtr& msg)
749  {
750  boost::mutex::scoped_lock lock(mutex_);
751 
752  // if estimate_normal_ is true, we run integral image normal estimation
753  // before segmenting planes
754  pcl::PointCloud<PointT>::Ptr input(new pcl::PointCloud<PointT>());
755  pcl::PointCloud<pcl::Normal>::Ptr normal(new pcl::PointCloud<pcl::Normal>());
757 
758  if (estimate_normal_) {
760  estimateNormal(input, normal);
761  // publish normal to ros
762  if (publish_normal_) {
763  sensor_msgs::PointCloud2 normal_ros_cloud;
764  pcl::toROSMsg(*normal, normal_ros_cloud);
765  normal_ros_cloud.header = msg->header;
766  normal_pub_.publish(normal_ros_cloud);
767  }
768  }
769  else {
770  pcl::fromROSMsg(*msg, *normal);
771  }
772 
773  segmentFromNormals(input, normal, msg->header);
774  diagnostic_updater_->update();
775  }
776 
779  {
781  if (connection_status_ == jsk_topic_tools::SUBSCRIBED) {
782  if (previous_checked_connection_status_for_normal_ != connection_status_) {
783  // Poke when start subscribing.
785  }
786  bool alivep = normal_estimation_vital_checker_->isAlive();
787  if (alivep) {
788  stat.summary(diagnostic_msgs::DiagnosticStatus::OK, "NormalEstimation running");
789  jsk_topic_tools::addDiagnosticInformation(
790  "Time to estimate normal", normal_estimation_time_acc_, stat);
791  // normal estimation parameters
792  if (estimation_method_ == 0) {
793  stat.add("Estimation Method", "AVERAGE_3D_GRADIENT");
794  }
795  else if (estimation_method_ == 1) {
796  stat.add("Estimation Method", "COVARIANCE_MATRIX");
797  }
798  else if (estimation_method_ == 2) {
799  stat.add("Estimation Method", "AVERAGE_DEPTH_CHANGE");
800  }
801  if (border_policy_ignore_) {
802  stat.add("Border Policy", "ignore");
803  }
804  else {
805  stat.add("Border Policy", "mirror");
806  }
807  stat.add("Max Depth Change Factor", max_depth_change_factor_);
808  stat.add("Normal Smoothing Size", normal_smoothing_size_);
810  stat.add("Depth Dependent Smooting", "Enabled");
811  }
812  else {
813  stat.add("Depth Dependent Smooting", "Disabled");
814  }
815  if (publish_normal_) {
816  stat.add("Publish Normal", "Enabled");
817  }
818  else {
819  stat.add("Publish Normal", "Disabled");
820  }
821  }
822  else {
823  stat.summary(diagnostic_msgs::DiagnosticStatus::ERROR,
824  (boost::format("NormalEstimation not running for %f sec")
825  % normal_estimation_vital_checker_->deadSec()).str());
826  }
827  } else { // Not SUBSCRIBED
828  stat.summary(diagnostic_msgs::DiagnosticStatus::OK,
829  "NormalEstimation is not subscribed");
830  }
832  }
833  else {
834  stat.summary(diagnostic_msgs::DiagnosticStatus::OK,
835  "NormalEstimation is not activated");
836  }
837  }
838 
841  {
842  if (connection_status_ == jsk_topic_tools::SUBSCRIBED) {
843  if (previous_checked_connection_status_for_plane_ != connection_status_) {
844  // Poke when start subscribing.
846  }
847  bool alivep = plane_segmentation_vital_checker_->isAlive();
848  if (alivep) {
849  stat.summary(diagnostic_msgs::DiagnosticStatus::OK,
850  "PlaneSegmentation running");
851  jsk_topic_tools::addDiagnosticInformation(
852  "Time to segment planes", plane_segmentation_time_acc_, stat);
854  jsk_topic_tools::addDiagnosticInformation(
855  "Time to refine by RANSAC", ransac_refinement_time_acc_, stat);
856  }
857  stat.add("Minimum Inliers", min_size_);
858  stat.add("Angular Threshold (rad)", angular_threshold_);
859  stat.add("Angular Threshold (deg)", angular_threshold_ / M_PI * 180.0);
860  stat.add("Distance Threshold", distance_threshold_);
861  stat.add("Max Curvature", max_curvature_);
863  stat.add("Use RANSAC refinement", "True");
864  stat.add("RANSAC refinement distance threshold",
866  }
867  else {
868  stat.add("Use RANSAC refinement", "False");
869  }
870 
871  stat.add("Number of original segmented planes (Avg.)",
873  stat.add("Number of connected segmented planes (Avg.)",
875  }
876  else {
877  stat.summary(diagnostic_msgs::DiagnosticStatus::ERROR,
878  (boost::format("PlaneSegmentation not running for %f sec")
879  % plane_segmentation_vital_checker_->deadSec()).str());
880  }
881  } else { // Not SUBSCRIBED
882  stat.summary(diagnostic_msgs::DiagnosticStatus::OK,
883  "PlaneSegmentation is not subscribed");
884  }
886  }
887 
889  const ros::TimerEvent& event)
890  {
891  boost::mutex::scoped_lock lock(mutex_);
892  diagnostic_updater_->update();
893  }
894 
895 }
jsk_pcl_ros::OrganizedMultiPlaneSegmentation::estimation_method_
int estimation_method_
Definition: organized_multi_plane_segmentation.h:246
extract_top_polygon_likelihood.ex
ex
Definition: extract_top_polygon_likelihood.py:51
jsk_pcl_ros::OrganizedMultiPlaneSegmentation::org_coefficients_pub_
ros::Publisher org_coefficients_pub_
Definition: organized_multi_plane_segmentation.h:221
jsk_pcl_ros::OrganizedMultiPlaneSegmentation::buildConnectedPlanes
virtual void buildConnectedPlanes(const pcl::PointCloud< PointT >::Ptr &input, const std_msgs::Header &header, const std::vector< pcl::PointIndices > &inlier_indices, const std::vector< pcl::PointIndices > &boundary_indices, const std::vector< pcl::ModelCoefficients > &model_coefficients, const jsk_recognition_utils::IntegerGraphMap &connection_map, std::vector< pcl::PointIndices > &output_indices, std::vector< pcl::ModelCoefficients > &output_coefficients, std::vector< pcl::PointCloud< PointT > > &output_boundary_clouds)
Definition: organized_multi_plane_segmentation_nodelet.cpp:347
jsk_pcl_ros::OrganizedMultiPlaneSegmentation::plane_segmentation_time_acc_
jsk_topic_tools::TimeAccumulator plane_segmentation_time_acc_
Definition: organized_multi_plane_segmentation.h:230
NODELET_FATAL
#define NODELET_FATAL(...)
jsk_pcl_ros::OrganizedMultiPlaneSegmentation::connectPlanesMap
virtual void connectPlanesMap(const pcl::PointCloud< PointT >::Ptr &input, const std::vector< pcl::ModelCoefficients > &model_coefficients, const std::vector< pcl::PointIndices > &boundary_indices, jsk_recognition_utils::IntegerGraphMap &connection_map)
Definition: organized_multi_plane_segmentation_nodelet.cpp:230
jsk_pcl_ros::OrganizedMultiPlaneSegmentation::diagnostics_timer_
ros::Timer diagnostics_timer_
Definition: organized_multi_plane_segmentation.h:235
jsk_pcl_ros::OrganizedMultiPlaneSegmentation::refined_polygon_pub_
ros::Publisher refined_polygon_pub_
Definition: organized_multi_plane_segmentation.h:223
NODELET_ERROR
#define NODELET_ERROR(...)
jsk_pcl_ros::OrganizedMultiPlaneSegmentation::refined_pub_
ros::Publisher refined_pub_
Definition: organized_multi_plane_segmentation.h:223
depth_error_calibration.lock
lock
Definition: depth_error_calibration.py:32
jsk_recognition_utils::IntegerGraphMap
std::map< int, std::vector< int > > IntegerGraphMap
ros::Publisher
jsk_pcl_ros::OrganizedMultiPlaneSegmentation::org_polygon_pub_
ros::Publisher org_polygon_pub_
Definition: organized_multi_plane_segmentation.h:221
sample_simulate_tabletop_cloud.polygon
polygon
Definition: sample_simulate_tabletop_cloud.py:167
boost::shared_ptr< ConvexPolygon >
i
int i
diagnostic_updater::DiagnosticStatusWrapper::add
void add(const std::string &key, const bool &b)
jsk_pcl_ros::OrganizedMultiPlaneSegmentation::updateDiagnosticPlaneSegmentation
virtual void updateDiagnosticPlaneSegmentation(diagnostic_updater::DiagnosticStatusWrapper &stat)
Definition: organized_multi_plane_segmentation_nodelet.cpp:871
sample_simulate_tabletop_cloud.header
header
Definition: sample_simulate_tabletop_cloud.py:162
begin
begin
jsk_pcl_ros::OrganizedMultiPlaneSegmentation::pub_
ros::Publisher pub_
Definition: organized_multi_plane_segmentation.h:222
p
p
M_PI
#define M_PI
jsk_pcl_ros::OrganizedMultiPlaneSegmentation::min_size_
int min_size_
Definition: organized_multi_plane_segmentation.h:237
getName
ROSCONSOLE_CONSOLE_IMPL_DECL std::string getName(void *handle)
PCLIndicesMsg
pcl::PointIndices PCLIndicesMsg
jsk_pcl_ros::OrganizedMultiPlaneSegmentation::ransac_refinement_time_acc_
jsk_topic_tools::TimeAccumulator ransac_refinement_time_acc_
Definition: organized_multi_plane_segmentation.h:232
jsk_pcl_ros::OrganizedMultiPlaneSegmentation::normal_estimation_vital_checker_
jsk_topic_tools::VitalChecker::Ptr normal_estimation_vital_checker_
Definition: organized_multi_plane_segmentation.h:233
theta
int theta
jsk_pcl_ros::OrganizedMultiPlaneSegmentation::ransac_refine_outlier_distance_threshold_
double ransac_refine_outlier_distance_threshold_
Definition: organized_multi_plane_segmentation.h:268
diagnostic_updater::Updater
geo_util.h
jsk_pcl_ros::OrganizedMultiPlaneSegmentation::original_plane_num_counter_
jsk_recognition_utils::Counter original_plane_num_counter_
Definition: organized_multi_plane_segmentation.h:270
ros::Subscriber::shutdown
void shutdown()
plane_time_ensync_for_recognition.coefficients_pub
coefficients_pub
Definition: plane_time_ensync_for_recognition.py:38
jsk_pcl_ros::OrganizedMultiPlaneSegmentation::sub_
ros::Subscriber sub_
Definition: organized_multi_plane_segmentation.h:226
jsk_pcl_ros::OrganizedMultiPlaneSegmentation::connect_distance_threshold_
double connect_distance_threshold_
Definition: organized_multi_plane_segmentation.h:243
jsk_pcl_ros::OrganizedMultiPlaneSegmentation::unsubscribe
virtual void unsubscribe()
Definition: organized_multi_plane_segmentation_nodelet.cpp:202
jsk_pcl_ros::OrganizedMultiPlaneSegmentation::ransac_refine_coefficients_
bool ransac_refine_coefficients_
Definition: organized_multi_plane_segmentation.h:267
jsk_pcl_ros::OrganizedMultiPlaneSegmentation::estimateNormal
virtual void estimateNormal(pcl::PointCloud< PointT >::Ptr input, pcl::PointCloud< pcl::Normal >::Ptr output)
Definition: organized_multi_plane_segmentation_nodelet.cpp:745
jsk_pcl_ros::OrganizedMultiPlaneSegmentation::publishSegmentationInformation
virtual void publishSegmentationInformation(const std_msgs::Header &header, const pcl::PointCloud< PointT >::Ptr input, ros::Publisher &indices_pub, ros::Publisher &polygon_pub, ros::Publisher &coefficients_pub, const std::vector< pcl::PointIndices > &inlier_indices, const std::vector< pcl::PointCloud< PointT > > &boundaries, const std::vector< pcl::ModelCoefficients > &model_coefficients)
Definition: organized_multi_plane_segmentation_nodelet.cpp:463
organized_multi_plane_segmentation.h
jsk_pcl_ros::OrganizedMultiPlaneSegmentation::normal_pub_
ros::Publisher normal_pub_
Definition: organized_multi_plane_segmentation.h:224
jsk_pcl_ros::OrganizedMultiPlaneSegmentation::refined_coefficients_pub_
ros::Publisher refined_coefficients_pub_
Definition: organized_multi_plane_segmentation.h:223
pcl::fromROSMsg
void fromROSMsg(const sensor_msgs::PointCloud2 &cloud, pcl::PointCloud< T > &pcl_cloud)
jsk_pcl_ros::OrganizedMultiPlaneSegmentation::pointCloudToPolygon
virtual void pointCloudToPolygon(const pcl::PointCloud< PointT > &input, geometry_msgs::Polygon &polygon)
Definition: organized_multi_plane_segmentation_nodelet.cpp:334
PLUGINLIB_EXPORT_CLASS
PLUGINLIB_EXPORT_CLASS(jsk_pcl_ros::OrganizedMultiPlaneSegmentation, nodelet::Nodelet)
ros::Publisher::publish
void publish(const boost::shared_ptr< M > &message) const
cloud
cloud
jsk_pcl_ros::OrganizedMultiPlaneSegmentation::segmentOrganizedMultiPlanes
virtual void segmentOrganizedMultiPlanes(pcl::PointCloud< PointT >::Ptr input, pcl::PointCloud< pcl::Normal >::Ptr normal, PlanarRegionVector &regions, std::vector< pcl::ModelCoefficients > &model_coefficients, std::vector< pcl::PointIndices > &inlier_indices, pcl::PointCloud< pcl::Label >::Ptr &labels, std::vector< pcl::PointIndices > &label_indices, std::vector< pcl::PointIndices > &boundary_indices)
Definition: organized_multi_plane_segmentation_nodelet.cpp:437
jsk_pcl_ros::OrganizedMultiPlaneSegmentation
Definition: organized_multi_plane_segmentation.h:94
class_list_macros.h
jsk_pcl_ros::OrganizedMultiPlaneSegmentation::updateDiagnostics
virtual void updateDiagnostics(const ros::TimerEvent &event)
Definition: organized_multi_plane_segmentation_nodelet.cpp:920
jsk_pcl_ros::OrganizedMultiPlaneSegmentation::segment
virtual void segment(const sensor_msgs::PointCloud2::ConstPtr &msg)
Definition: organized_multi_plane_segmentation_nodelet.cpp:780
jsk_pcl_ros::OrganizedMultiPlaneSegmentation::pub_connection_marker_
ros::Publisher pub_connection_marker_
Definition: organized_multi_plane_segmentation.h:225
diagnostic_updater::DiagnosticStatusWrapper::summary
void summary(const diagnostic_msgs::DiagnosticStatus &src)
jsk_pcl_ros::OrganizedMultiPlaneSegmentation::coefficients_pub_
ros::Publisher coefficients_pub_
Definition: organized_multi_plane_segmentation.h:222
PCLModelCoefficientMsg
pcl::ModelCoefficients PCLModelCoefficientMsg
jsk_pcl_ros::OrganizedMultiPlaneSegmentation::pclIndicesArrayToClusterPointIndices
virtual void pclIndicesArrayToClusterPointIndices(const std::vector< pcl::PointIndices > &inlier_indices, const std_msgs::Header &header, jsk_recognition_msgs::ClusterPointIndices &output_indices)
Definition: organized_multi_plane_segmentation_nodelet.cpp:320
jsk_pcl_ros
Definition: add_color_from_image.h:51
jsk_pcl_ros::OrganizedMultiPlaneSegmentation::depth_dependent_smoothing_
bool depth_dependent_smoothing_
Definition: organized_multi_plane_segmentation.h:247
jsk_recognition_utils::Counter::add
virtual void add(double v)
jsk_pcl_ros::OrganizedMultiPlaneSegmentation::diagnostic_updater_
boost::shared_ptr< diagnostic_updater::Updater > diagnostic_updater_
Definition: organized_multi_plane_segmentation.h:229
jsk_pcl_ros::OrganizedMultiPlaneSegmentation::max_depth_change_factor_
double max_depth_change_factor_
Definition: organized_multi_plane_segmentation.h:248
PointT
pcl::PointXYZRGB PointT
jsk_pcl_ros::OrganizedMultiPlaneSegmentation::forceToDirectOrigin
virtual void forceToDirectOrigin(const std::vector< pcl::ModelCoefficients > &coefficients, std::vector< pcl::ModelCoefficients > &output_coefficients)
Definition: organized_multi_plane_segmentation_nodelet.cpp:173
jsk_pcl_ros::OrganizedMultiPlaneSegmentation::org_pub_
ros::Publisher org_pub_
Definition: organized_multi_plane_segmentation.h:221
labels
labels
jsk_pcl_ros::OrganizedMultiPlaneSegmentation::refineBasedOnRANSAC
virtual void refineBasedOnRANSAC(const pcl::PointCloud< PointT >::Ptr input, const std::vector< pcl::PointIndices > &input_indices, const std::vector< pcl::ModelCoefficients > &input_coefficients, std::vector< pcl::PointIndices > &output_indices, std::vector< pcl::ModelCoefficients > &output_coefficients, std::vector< jsk_recognition_utils::ConvexPolygon::Ptr > &output_boundaries)
Definition: organized_multi_plane_segmentation_nodelet.cpp:687
jsk_pcl_ros::OrganizedMultiPlaneSegmentation::estimate_normal_
bool estimate_normal_
Definition: organized_multi_plane_segmentation.h:251
jsk_pcl_ros::OrganizedMultiPlaneSegmentation::previous_checked_connection_status_for_normal_
jsk_topic_tools::ConnectionStatus previous_checked_connection_status_for_normal_
Previous checked status of connection.
Definition: organized_multi_plane_segmentation.h:257
jsk_pcl_ros::OrganizedMultiPlaneSegmentation::configCallback
virtual void configCallback(Config &config, uint32_t level)
Definition: organized_multi_plane_segmentation_nodelet.cpp:207
jsk_recognition_utils::Plane::toCoefficients
virtual std::vector< float > toCoefficients()
jsk_pcl_ros::OrganizedMultiPlaneSegmentation::segmentFromNormals
virtual void segmentFromNormals(pcl::PointCloud< PointT >::Ptr input, pcl::PointCloud< pcl::Normal >::Ptr normal, const std_msgs::Header &header)
Definition: organized_multi_plane_segmentation_nodelet.cpp:606
ros::TimerEvent
jsk_pcl_ros::OrganizedMultiPlaneSegmentation::plane_segmentation_vital_checker_
jsk_topic_tools::VitalChecker::Ptr plane_segmentation_vital_checker_
Definition: organized_multi_plane_segmentation.h:234
pcl_conversion_util.h
jsk_pcl_ros::OrganizedMultiPlaneSegmentation::mutex_
boost::mutex mutex_
Definition: organized_multi_plane_segmentation.h:228
jsk_pcl_ros::OrganizedMultiPlaneSegmentation::max_refined_area_threshold_
double max_refined_area_threshold_
Definition: organized_multi_plane_segmentation.h:245
jsk_pcl_ros::OrganizedMultiPlaneSegmentation::subscribe
virtual void subscribe()
Definition: organized_multi_plane_segmentation_nodelet.cpp:196
point
std::chrono::system_clock::time_point point
jsk_pcl_ros::OrganizedMultiPlaneSegmentation::min_refined_area_threshold_
double min_refined_area_threshold_
Definition: organized_multi_plane_segmentation.h:244
jsk_pcl_ros::OrganizedMultiPlaneSegmentation::connect_plane_angle_threshold_
double connect_plane_angle_threshold_
Definition: organized_multi_plane_segmentation.h:242
jsk_pcl_ros::OrganizedMultiPlaneSegmentation::max_curvature_
double max_curvature_
Definition: organized_multi_plane_segmentation.h:241
jsk_pcl_ros::OrganizedMultiPlaneSegmentation::polygon_pub_
ros::Publisher polygon_pub_
Definition: organized_multi_plane_segmentation.h:222
jsk_recognition_utils::addIndices
pcl::PointIndices::Ptr addIndices(const pcl::PointIndices &a, const pcl::PointIndices &b)
nodelet::Nodelet
sqrt
double sqrt()
jsk_recognition_utils::Plane::flip
virtual Plane flip()
dump_depth_error.f
f
Definition: dump_depth_error.py:39
coefficients
coefficients
jsk_recognition_utils::Counter::mean
virtual double mean()
jsk_pcl_ros::OrganizedMultiPlaneSegmentation::publishMarkerOfConnection
virtual void publishMarkerOfConnection(jsk_recognition_utils::IntegerGraphMap connection_map, const pcl::PointCloud< PointT >::Ptr cloud, const std::vector< pcl::PointIndices > &inliers, const std_msgs::Header &header)
Definition: organized_multi_plane_segmentation_nodelet.cpp:542
diagnostic_updater::DiagnosticStatusWrapper
pcl::toROSMsg
void toROSMsg(const pcl::PointCloud< T > &cloud, sensor_msgs::Image &msg)
jsk_recognition_utils::Plane
jsk_pcl_ros::OrganizedMultiPlaneSegmentation::distance_threshold_
double distance_threshold_
Definition: organized_multi_plane_segmentation.h:240
jsk_pcl_ros::OrganizedMultiPlaneSegmentation::normal_smoothing_size_
double normal_smoothing_size_
Definition: organized_multi_plane_segmentation.h:249
jsk_recognition_utils::buildAllGroupsSetFromGraphMap
void buildAllGroupsSetFromGraphMap(IntegerGraphMap graph_map, std::vector< std::set< int > > &output_sets)
polygon_pub
ros::Publisher polygon_pub
jsk_pcl_ros::OrganizedMultiPlaneSegmentation::updateDiagnosticNormalEstimation
virtual void updateDiagnosticNormalEstimation(diagnostic_updater::DiagnosticStatusWrapper &stat)
Definition: organized_multi_plane_segmentation_nodelet.cpp:809
jsk_pcl_ros::OrganizedMultiPlaneSegmentation::previous_checked_connection_status_for_plane_
jsk_topic_tools::ConnectionStatus previous_checked_connection_status_for_plane_
Previous checked status of connection for plane segmentation.
Definition: organized_multi_plane_segmentation.h:262
jsk_pcl_ros::OrganizedMultiPlaneSegmentation::angular_threshold_
double angular_threshold_
Definition: organized_multi_plane_segmentation.h:239
depth_error_calibration.input
input
Definition: depth_error_calibration.py:43
jsk_pcl_ros::OrganizedMultiPlaneSegmentation::normal_estimation_time_acc_
jsk_topic_tools::TimeAccumulator normal_estimation_time_acc_
Definition: organized_multi_plane_segmentation.h:231
jsk_pcl_ros::OrganizedMultiPlaneSegmentation::srv_
boost::shared_ptr< dynamic_reconfigure::Server< Config > > srv_
Definition: organized_multi_plane_segmentation.h:227
config
config
ros::Duration
pose_with_covariance_sample.msg
msg
Definition: pose_with_covariance_sample.py:22
n
GLfloat n[6][3]
jsk_pcl_ros::OrganizedMultiPlaneSegmentation::border_policy_ignore_
bool border_policy_ignore_
Definition: organized_multi_plane_segmentation.h:250
jsk_pcl_ros::OrganizedMultiPlaneSegmentation::onInit
virtual void onInit()
Definition: organized_multi_plane_segmentation_nodelet.cpp:97
jsk_pcl_ros::OrganizedMultiPlaneSegmentation::publish_normal_
bool publish_normal_
Definition: organized_multi_plane_segmentation.h:252
jsk_pcl_ros::OrganizedMultiPlaneSegmentation::PlanarRegionVector
std::vector< pcl::PlanarRegion< PointT >, Eigen::aligned_allocator< pcl::PlanarRegion< PointT > > > PlanarRegionVector
Definition: organized_multi_plane_segmentation.h:133
jsk_pcl_ros::OrganizedMultiPlaneSegmentation::connected_plane_num_counter_
jsk_recognition_utils::Counter connected_plane_num_counter_
Definition: organized_multi_plane_segmentation.h:271
NODELET_DEBUG
#define NODELET_DEBUG(...)
jsk_recognition_utils::Vertices
std::vector< Eigen::Vector3f, Eigen::aligned_allocator< Eigen::Vector3f > > Vertices


jsk_pcl_ros
Author(s): Yohei Kakiuchi
autogenerated on Fri May 16 2025 03:12:12