region_growing_multiple_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) 2014, 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 
39 #include <pcl/segmentation/conditional_euclidean_clustering.h>
40 #include <pcl/sample_consensus/method_types.h>
41 #include <pcl/sample_consensus/model_types.h>
42 #include <pcl/segmentation/sac_segmentation.h>
43 
44 namespace jsk_pcl_ros
45 {
46 
48  {
49  DiagnosticNodelet::onInit();
50 
51  srv_ = boost::make_shared <dynamic_reconfigure::Server<Config> > (*pnh_);
52  dynamic_reconfigure::Server<Config>::CallbackType f =
53  boost::bind (
55  srv_->setCallback (f);
56 
57  pub_polygons_ = advertise<jsk_recognition_msgs::PolygonArray>(
58  *pnh_, "output/polygons", 1);
59  pub_inliers_ = advertise<jsk_recognition_msgs::ClusterPointIndices>(
60  *pnh_, "output/inliers", 1);
61  pub_coefficients_ = advertise<jsk_recognition_msgs::ModelCoefficientsArray>(
62  *pnh_, "output/coefficients", 1);
63  pub_clustering_result_ = advertise<jsk_recognition_msgs::ClusterPointIndices>(
64  *pnh_, "output/clustering_result", 1);
65  pub_latest_time_ = advertise<std_msgs::Float32>(
66  *pnh_, "output/latest_time", 1);
67  pub_average_time_ = advertise<std_msgs::Float32>(
68  *pnh_, "output/average_time", 1);
69  done_initialization_ = true;
70  onInitPostProcess();
71  }
72 
74  // message_filters::Synchronizer needs to be called reset
75  // before message_filters::Subscriber is freed.
76  // Calling reset fixes the following error on shutdown of the nodelet:
77  // terminate called after throwing an instance of
78  // 'boost::exception_detail::clone_impl<boost::exception_detail::error_info_injector<boost::lock_error> >'
79  // what(): boost: mutex lock failed in pthread_mutex_lock: Invalid argument
80  // Also see https://github.com/ros/ros_comm/issues/720 .
81  sync_.reset();
82  }
83 
85  {
86  sub_input_.subscribe(*pnh_, "input", 1);
87  sub_normal_.subscribe(*pnh_, "input_normal", 1);
88  sync_
89  = boost::make_shared<
91  sync_->connectInput(sub_input_, sub_normal_);
92  sync_->registerCallback(
94  _1, _2));
95  }
96 
98  {
101  }
102 
104  Config &config, uint32_t level)
105  {
106  boost::mutex::scoped_lock lock(mutex_);
107  angular_threshold_ = config.angular_threshold;
108  distance_threshold_ = config.distance_threshold;
109  max_curvature_ = config.max_curvature;
110  min_size_ = config.min_size;
111  max_size_ = config.max_size;
112  min_area_ = config.min_area;
113  max_area_ = config.max_area;
114  cluster_tolerance_ = config.cluster_tolerance;
116  = config.ransac_refine_outlier_distance_threshold;
118  = config.ransac_refine_max_iterations;
119  }
120 
122  const pcl::PointCloud<pcl::PointXYZRGB>::Ptr& cloud,
123  const pcl::PointIndices::Ptr& indices,
124  pcl::PointIndices& inliers,
125  pcl::ModelCoefficients& coefficient)
126  {
127  pcl::SACSegmentation<pcl::PointXYZRGB> seg;
128  seg.setOptimizeCoefficients (true);
129  seg.setMethodType (pcl::SAC_RANSAC);
130  seg.setDistanceThreshold (ransac_refine_outlier_distance_threshold_);
131  seg.setInputCloud(cloud);
132  seg.setIndices(indices);
133  seg.setMaxIterations (ransac_refine_max_iterations_);
134  seg.setModelType (pcl::SACMODEL_PLANE);
135  seg.segment(inliers, coefficient);
136  }
137 
139  const sensor_msgs::PointCloud2::ConstPtr& msg,
140  const sensor_msgs::PointCloud2::ConstPtr& normal_msg)
141  {
142  boost::mutex::scoped_lock lock(mutex_);
143  if (!done_initialization_) {
144  return;
145  }
146  vital_checker_->poke();
147  {
150  pcl::PointCloud<PointT>::Ptr cloud(new pcl::PointCloud<PointT>);
151  pcl::PointCloud<pcl::Normal>::Ptr normal(new pcl::PointCloud<pcl::Normal>);
152  pcl::fromROSMsg(*msg, *cloud);
153  pcl::fromROSMsg(*normal_msg, *normal);
154  // concatenate fields
155  pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr
156  all_cloud (new pcl::PointCloud<pcl::PointXYZRGBNormal>);
157  pcl::concatenateFields(*cloud, *normal, *all_cloud);
158  pcl::PointIndices::Ptr indices (new pcl::PointIndices);
159  for (size_t i = 0; i < all_cloud->points.size(); i++) {
160  if (!std::isnan(all_cloud->points[i].x) &&
161  !std::isnan(all_cloud->points[i].y) &&
162  !std::isnan(all_cloud->points[i].z) &&
163  !std::isnan(all_cloud->points[i].normal_x) &&
164  !std::isnan(all_cloud->points[i].normal_y) &&
165  !std::isnan(all_cloud->points[i].normal_z) &&
166  !std::isnan(all_cloud->points[i].curvature)) {
167  if (all_cloud->points[i].curvature < max_curvature_) {
168  indices->indices.push_back(i);
169  }
170  }
171  }
172  pcl::ConditionalEuclideanClustering<pcl::PointXYZRGBNormal> cec (true);
173 
174  // vector of pcl::PointIndices
175  pcl::IndicesClustersPtr clusters (new pcl::IndicesClusters);
176  cec.setInputCloud (all_cloud);
177  cec.setIndices(indices);
178  cec.setClusterTolerance(cluster_tolerance_);
179  cec.setMinClusterSize(min_size_);
180  //cec.setMaxClusterSize(max_size_);
181  {
182  boost::mutex::scoped_lock lock2(global_custom_condigion_function_mutex);
184  cec.setConditionFunction(
186  //ros::Time before = ros::Time::now();
187  cec.segment (*clusters);
188  // ros::Time end = ros::Time::now();
189  // ROS_INFO("segment took %f sec", (before - end).toSec());
190  }
191  // Publish raw cluster information
192  // pcl::IndicesCluster is typdefed as std::vector<pcl::PointIndices>
193  jsk_recognition_msgs::ClusterPointIndices ros_clustering_result;
194  ros_clustering_result.cluster_indices
195  = pcl_conversions::convertToROSPointIndices(*clusters, msg->header);
196  ros_clustering_result.header = msg->header;
197  pub_clustering_result_.publish(ros_clustering_result);
198 
199  // estimate planes
200  std::vector<pcl::PointIndices::Ptr> all_inliers;
201  std::vector<pcl::ModelCoefficients::Ptr> all_coefficients;
202  jsk_recognition_msgs::PolygonArray ros_polygon;
203  ros_polygon.header = msg->header;
204  for (size_t i = 0; i < clusters->size(); i++) {
205  pcl::PointIndices::Ptr plane_inliers(new pcl::PointIndices);
206  pcl::ModelCoefficients::Ptr plane_coefficients(new pcl::ModelCoefficients);
207 #if ( PCL_MAJOR_VERSION >= 1 && PCL_MINOR_VERSION >= 12 )
208  pcl::PointIndices::Ptr cluster = std::make_shared<pcl::PointIndices>((*clusters)[i]);
209 #else
210  pcl::PointIndices::Ptr cluster = boost::make_shared<pcl::PointIndices>((*clusters)[i]);
211 #endif
212  ransacEstimation(cloud, cluster,
213  *plane_inliers, *plane_coefficients);
214  if (plane_inliers->indices.size() > 0) {
216  = jsk_recognition_utils::convexFromCoefficientsAndInliers<pcl::PointXYZRGB>(
217  cloud, plane_inliers, plane_coefficients);
218  if (convex) {
219  if (min_area_ > convex->area() || convex->area() > max_area_) {
220  continue;
221  }
222  {
223  // check direction consistency of coefficients and convex
224  Eigen::Vector3f coefficient_normal(plane_coefficients->values[0],
225  plane_coefficients->values[1],
226  plane_coefficients->values[2]);
227  if (convex->getNormalFromVertices().dot(coefficient_normal) < 0) {
228  convex = boost::make_shared<jsk_recognition_utils::ConvexPolygon>(convex->flipConvex());
229  }
230  }
231  // Normal should direct to origin
232  {
233  Eigen::Vector3f p = convex->getPointOnPlane();
234  Eigen::Vector3f n = convex->getNormal();
235  if (p.dot(n) > 0) {
236  convex = boost::make_shared<jsk_recognition_utils::ConvexPolygon>(convex->flipConvex());
237  Eigen::Vector3f new_normal = convex->getNormal();
238  plane_coefficients->values[0] = new_normal[0];
239  plane_coefficients->values[1] = new_normal[1];
240  plane_coefficients->values[2] = new_normal[2];
241  plane_coefficients->values[3] = convex->getD();
242  }
243  }
244 
245  geometry_msgs::PolygonStamped polygon;
246  polygon.polygon = convex->toROSMsg();
247  polygon.header = msg->header;
248  ros_polygon.polygons.push_back(polygon);
249  all_inliers.push_back(plane_inliers);
250  all_coefficients.push_back(plane_coefficients);
251  }
252  }
253  }
254 
255  jsk_recognition_msgs::ClusterPointIndices ros_indices;
256  ros_indices.cluster_indices =
257  pcl_conversions::convertToROSPointIndices(all_inliers, msg->header);
258  ros_indices.header = msg->header;
259  pub_inliers_.publish(ros_indices);
260  jsk_recognition_msgs::ModelCoefficientsArray ros_coefficients;
261  ros_coefficients.header = msg->header;
262  ros_coefficients.coefficients =
264  all_coefficients, msg->header);
265  pub_coefficients_.publish(ros_coefficients);
266  pub_polygons_.publish(ros_polygon);
267  }
268  }
269 
273 }
274 
jsk_pcl_ros::RegionGrowingMultiplePlaneSegmentation::timer_
jsk_recognition_utils::WallDurationTimer timer_
Definition: region_growing_multiple_plane_segmentation.h:209
jsk_pcl_ros::RegionGrowingMultiplePlaneSegmentation::angular_threshold_
double angular_threshold_
Definition: region_growing_multiple_plane_segmentation.h:213
depth_error_calibration.lock
lock
Definition: depth_error_calibration.py:32
_2
boost::arg< 2 > _2
sample_simulate_tabletop_cloud.polygon
polygon
Definition: sample_simulate_tabletop_cloud.py:167
message_filters::Synchronizer
jsk_pcl_ros::RegionGrowingMultiplePlaneSegmentation::onInit
virtual void onInit()
Definition: region_growing_multiple_plane_segmentation_nodelet.cpp:79
boost::shared_ptr< ConvexPolygon >
i
int i
jsk_pcl_ros::RegionGrowingMultiplePlaneSegmentation::subscribe
virtual void subscribe()
Definition: region_growing_multiple_plane_segmentation_nodelet.cpp:116
p
p
geo_util.h
jsk_pcl_ros::RegionGrowingMultiplePlaneSegmentation::setCondifionFunctionParameter
static void setCondifionFunctionParameter(const double angular_threshold, const double distance_threshold)
Definition: region_growing_multiple_plane_segmentation.h:150
jsk_pcl_ros::RegionGrowingMultiplePlaneSegmentation
Definition: region_growing_multiple_plane_segmentation.h:88
jsk_pcl_ros::RegionGrowingMultiplePlaneSegmentation::pub_average_time_
ros::Publisher pub_average_time_
Definition: region_growing_multiple_plane_segmentation.h:207
pcl::fromROSMsg
void fromROSMsg(const sensor_msgs::PointCloud2 &cloud, pcl::PointCloud< T > &pcl_cloud)
jsk_pcl_ros::RegionGrowingMultiplePlaneSegmentation::cluster_tolerance_
double cluster_tolerance_
Definition: region_growing_multiple_plane_segmentation.h:220
jsk_pcl_ros::RegionGrowingMultiplePlaneSegmentation::sub_input_
message_filters::Subscriber< sensor_msgs::PointCloud2 > sub_input_
Definition: region_growing_multiple_plane_segmentation.h:197
ros::Publisher::publish
void publish(const boost::shared_ptr< M > &message) const
message_filters::Subscriber::unsubscribe
void unsubscribe()
cloud
cloud
jsk_pcl_ros::RegionGrowingMultiplePlaneSegmentation::global_angular_threshold
static double global_angular_threshold
Definition: region_growing_multiple_plane_segmentation.h:227
class_list_macros.h
jsk_pcl_ros::RegionGrowingMultiplePlaneSegmentation::mutex_
boost::mutex mutex_
Definition: region_growing_multiple_plane_segmentation.h:208
PLUGINLIB_EXPORT_CLASS
PLUGINLIB_EXPORT_CLASS(jsk_pcl_ros::RegionGrowingMultiplePlaneSegmentation, nodelet::Nodelet)
jsk_pcl_ros::RegionGrowingMultiplePlaneSegmentation::segment
virtual void segment(const sensor_msgs::PointCloud2::ConstPtr &msg, const sensor_msgs::PointCloud2::ConstPtr &normal_msg)
Definition: region_growing_multiple_plane_segmentation_nodelet.cpp:170
jsk_pcl_ros
Definition: add_color_from_image.h:51
jsk_pcl_ros::RegionGrowingMultiplePlaneSegmentation::pub_inliers_
ros::Publisher pub_inliers_
Definition: region_growing_multiple_plane_segmentation.h:203
jsk_pcl_ros::RegionGrowingMultiplePlaneSegmentation::max_area_
double max_area_
Definition: region_growing_multiple_plane_segmentation.h:219
jsk_pcl_ros::RegionGrowingMultiplePlaneSegmentation::min_size_
int min_size_
Definition: region_growing_multiple_plane_segmentation.h:216
jsk_pcl_ros::RegionGrowingMultiplePlaneSegmentation::configCallback
virtual void configCallback(Config &config, uint32_t level)
Definition: region_growing_multiple_plane_segmentation_nodelet.cpp:135
pcl::concatenateFields
void concatenateFields(PointCloud< PointXYZ > &cloud_xyz, PointCloud< RGB > &cloud_rgb, PointCloud< PointXYZRGB > &cloud)
Definition: kinfu_nodelet.cpp:58
attention_pose_set.r
r
Definition: attention_pose_set.py:9
jsk_pcl_ros::RegionGrowingMultiplePlaneSegmentation::ransac_refine_outlier_distance_threshold_
double ransac_refine_outlier_distance_threshold_
Definition: region_growing_multiple_plane_segmentation.h:221
_1
boost::arg< 1 > _1
jsk_pcl_ros::RegionGrowingMultiplePlaneSegmentation::regionGrowingFunction
static bool regionGrowingFunction(const pcl::PointXYZRGBNormal &a, const pcl::PointXYZRGBNormal &b, float distance)
Definition: region_growing_multiple_plane_segmentation.h:163
jsk_pcl_ros::RegionGrowingMultiplePlaneSegmentation::ransacEstimation
virtual void ransacEstimation(const pcl::PointCloud< pcl::PointXYZRGB >::Ptr &cloud, const pcl::PointIndices::Ptr &indices, pcl::PointIndices &inliers, pcl::ModelCoefficients &coefficient)
Definition: region_growing_multiple_plane_segmentation_nodelet.cpp:153
pcl_conversions::convertToROSModelCoefficients
std::vector< PCLModelCoefficientMsg > convertToROSModelCoefficients(const std::vector< pcl::ModelCoefficients::Ptr > &coefficients, const std_msgs::Header &header)
jsk_pcl_ros::RegionGrowingMultiplePlaneSegmentation::pub_polygons_
ros::Publisher pub_polygons_
Definition: region_growing_multiple_plane_segmentation.h:202
jsk_pcl_ros::RegionGrowingMultiplePlaneSegmentation::sub_normal_
message_filters::Subscriber< sensor_msgs::PointCloud2 > sub_normal_
Definition: region_growing_multiple_plane_segmentation.h:198
pcl_conversion_util.h
jsk_pcl_ros::RegionGrowingMultiplePlaneSegmentation::done_initialization_
bool done_initialization_
Definition: region_growing_multiple_plane_segmentation.h:223
jsk_pcl_ros::RegionGrowingMultiplePlaneSegmentation::pub_coefficients_
ros::Publisher pub_coefficients_
Definition: region_growing_multiple_plane_segmentation.h:204
message_filters::Subscriber::subscribe
void subscribe()
jsk_pcl_ros::RegionGrowingMultiplePlaneSegmentation::pub_latest_time_
ros::Publisher pub_latest_time_
Definition: region_growing_multiple_plane_segmentation.h:206
jsk_pcl_ros::RegionGrowingMultiplePlaneSegmentation::unsubscribe
virtual void unsubscribe()
Definition: region_growing_multiple_plane_segmentation_nodelet.cpp:129
jsk_recognition_utils::WallDurationTimer::reporter
virtual ScopedWallDurationReporter reporter()
jsk_pcl_ros::RegionGrowingMultiplePlaneSegmentation::max_size_
int max_size_
Definition: region_growing_multiple_plane_segmentation.h:217
nodelet::Nodelet
jsk_pcl_ros::RegionGrowingMultiplePlaneSegmentation::min_area_
double min_area_
Definition: region_growing_multiple_plane_segmentation.h:218
jsk_pcl_ros::RegionGrowingMultiplePlaneSegmentation::srv_
boost::shared_ptr< dynamic_reconfigure::Server< Config > > srv_
Definition: region_growing_multiple_plane_segmentation.h:201
dump_depth_error.f
f
Definition: dump_depth_error.py:39
jsk_pcl_ros::RegionGrowingMultiplePlaneSegmentation::~RegionGrowingMultiplePlaneSegmentation
virtual ~RegionGrowingMultiplePlaneSegmentation()
Definition: region_growing_multiple_plane_segmentation_nodelet.cpp:105
region_growing_multiple_plane_segmentation.h
jsk_pcl_ros::RegionGrowingMultiplePlaneSegmentation::max_curvature_
double max_curvature_
Definition: region_growing_multiple_plane_segmentation.h:215
mutex
boost::mutex mutex
global mutex.
Definition: depth_camera_error_visualization.cpp:86
jsk_pcl_ros::RegionGrowingMultiplePlaneSegmentation::distance_threshold_
double distance_threshold_
Definition: region_growing_multiple_plane_segmentation.h:214
jsk_recognition_utils::ScopedWallDurationReporter
jsk_pcl_ros::RegionGrowingMultiplePlaneSegmentation::global_distance_threshold
static double global_distance_threshold
Definition: region_growing_multiple_plane_segmentation.h:228
pcl_conversions::convertToROSPointIndices
std::vector< PCLIndicesMsg > convertToROSPointIndices(const std::vector< pcl::PointIndices > cluster_indices, const std_msgs::Header &header)
jsk_pcl_ros::RegionGrowingMultiplePlaneSegmentation::sync_
boost::shared_ptr< message_filters::Synchronizer< NormalSyncPolicy > > sync_
Definition: region_growing_multiple_plane_segmentation.h:200
jsk_pcl_ros::RegionGrowingMultiplePlaneSegmentation::global_custom_condigion_function_mutex
static boost::mutex global_custom_condigion_function_mutex
Definition: region_growing_multiple_plane_segmentation.h:229
config
config
pose_with_covariance_sample.msg
msg
Definition: pose_with_covariance_sample.py:22
n
GLfloat n[6][3]
jsk_pcl_ros::RegionGrowingMultiplePlaneSegmentation::pub_clustering_result_
ros::Publisher pub_clustering_result_
Definition: region_growing_multiple_plane_segmentation.h:205
jsk_pcl_ros::RegionGrowingMultiplePlaneSegmentation::ransac_refine_max_iterations_
int ransac_refine_max_iterations_
Definition: region_growing_multiple_plane_segmentation.h:222


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