colorize_segmented_RF_nodelet.cpp
Go to the documentation of this file.
1 /*********************************************************************
2  * Software License Agreement (BSD License)
3  *
4  * Copyright (c) 2013, yuto_inagaki and JSK Lab
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  *
11  * * Redistributions of source code must retain the above copyright
12  * notice, this list of conditions and the following disclaimer.
13  * * Redistributions in binary form must reproduce the above
14  * copyright notice, this list of conditions and the following
15  * disclaimer in the documentation and/o2r other materials provided
16  * with the distribution.
17  * * Neither the name of the JSK Lab nor the names of its
18  * contributors may be used to endorse or promote products derived
19  * from this software without specific prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
25  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
27  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
29  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
31  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32  * POSSIBILITY OF SUCH DAMAGE.
33  *********************************************************************/
37 
38 namespace jsk_pcl_ros
39 {
41  {
42  // not implemented yet
43  PCLNodelet::onInit();
44  sub_input_ = pnh_->subscribe("input", 1, &ColorizeRandomForest::extract, this);
45 
46  pub_ = pnh_->advertise<sensor_msgs::PointCloud2>("output/zero", 1);
47  pub2_ = pnh_->advertise<sensor_msgs::PointCloud2>("output/nonzero", 1);
48 
49  srand(time(NULL));
50 
51  double tmp_radius = 0.03, tmp_pass = 0.03, tmp_pass2 = 0.06;
52  sum_num_ = 100;
53  if (!pnh_->getParam("rs", tmp_radius))
54  {
55  NODELET_WARN("~rs is not specified, so set to 0.03");
56  }
57  if (!pnh_->getParam("po", tmp_pass))
58  {
59  NODELET_WARN("~po is not specified, so set to 0.03");
60  }
61  if (!pnh_->getParam("po2", tmp_pass2))
62  {
63  NODELET_WARN("~po2 is not specified, so set to 0.06");
64  }
65  if (!pnh_->getParam("sum_num", sum_num_))
66  {
67  NODELET_WARN("~sum_num is not specified, so set to 100");
68  }
69 
70  radius_search_ = tmp_radius;
71  pass_offset_ = tmp_pass;
72  pass_offset2_ = tmp_pass2;
73  }
74 
75  void ColorizeRandomForest::extract(const sensor_msgs::PointCloud2 pc)
76  {
77  pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloud (new pcl::PointCloud<pcl::PointXYZRGB> ());
78 
79  std::vector<int> indices;
80  pcl::fromROSMsg(pc, *cloud);
81  cloud->is_dense = false;
82  pcl::removeNaNFromPointCloud(*cloud, *cloud, indices);
83 
84  pcl::search::KdTree<pcl::PointXYZRGB>::Ptr tree (new pcl::search::KdTree<pcl::PointXYZRGB>);
85  tree->setInputCloud (cloud);
86  pcl::PassThrough<pcl::PointXYZRGB> pass;
87  pass.setInputCloud (cloud);
88  pass.setFilterFieldName (std::string("z"));
89  pass.setFilterLimits (0.0, 1.5);
90  pass.filter (*cloud);
91 
92  std::vector<pcl::PointIndices> cluster_indices;
93  pcl::EuclideanClusterExtraction<pcl::PointXYZRGB> ec;
94  ec.setClusterTolerance (0.025);
95  ec.setMinClusterSize (200);
96  ec.setMaxClusterSize (100000);
97  ec.setSearchMethod (tree);
98  ec.setInputCloud (cloud);
99  ec.extract (cluster_indices);
100 
101  pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloth_cloud_cluster (new pcl::PointCloud<pcl::PointXYZRGB>);
102  pcl::PointCloud<pcl::PointXYZRGB>::Ptr noncloth_cloud_cluster (new pcl::PointCloud<pcl::PointXYZRGB>);
103  int cluster_num = 0;
104  for (std::vector<pcl::PointIndices>::const_iterator it = cluster_indices.begin (); it != cluster_indices.end (); ++it)
105  {
106  NODELET_DEBUG("Calculate time %d / %ld", cluster_num , cluster_indices.size());
107  pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloud_cluster (new pcl::PointCloud<pcl::PointXYZRGB>);
108  for (std::vector<int>::const_iterator pit = it->indices.begin (); pit != it->indices.end (); pit++)
109  cloud_cluster->points.push_back (cloud->points[*pit]);
110  cloud_cluster->is_dense = true;
111  cluster_num ++ ;
112 
113  pcl::NormalEstimation<pcl::PointXYZRGB, pcl::PointXYZRGBNormal> ne;
114  pcl::search::KdTree<pcl::PointXYZRGB>::Ptr tree (new pcl::search::KdTree<pcl::PointXYZRGB> ());
115  pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr cloud_normals (new pcl::PointCloud<pcl::PointXYZRGBNormal>);
116  ne.setInputCloud (cloud_cluster);
117  ne.setSearchMethod (tree);
118  ne.setRadiusSearch (0.02);
119  ne.compute (*cloud_normals);
120 
121  for (int cloud_index = 0; cloud_index < cloud_normals->points.size(); cloud_index++){
122  cloud_normals->points[cloud_index].x = cloud_cluster->points[cloud_index].x;
123  cloud_normals->points[cloud_index].y = cloud_cluster->points[cloud_index].y;
124  cloud_normals->points[cloud_index].z = cloud_cluster->points[cloud_index].z;
125  }
126 
127  int result_counter=0, call_counter = 0;
128  pcl::PointXYZRGBNormal max_pt,min_pt;
129  pcl::getMinMax3D(*cloud_normals, min_pt, max_pt);
130 
131  for (int i = 0 ; i < 30; i++){
132  double lucky = 0, lucky2 = 0;
133  std::string axis("x"), other_axis("y");
134  int rand_xy = rand()%2;
135  if (rand_xy == 0){
136  lucky = min_pt.x - pass_offset_ + (max_pt.x - min_pt.x - pass_offset_*2) * 1.0 * rand() / RAND_MAX;
137  lucky2 = min_pt.y + (max_pt.y - min_pt.y) * 1.0 * rand() / RAND_MAX;
138  }else {
139  lucky = min_pt.y - pass_offset_ + (max_pt.y - min_pt.y - pass_offset_*2) * 1.0 * rand() / RAND_MAX;
140  lucky2 = min_pt.x + (max_pt.x - min_pt.x) * 1.0 * rand() / RAND_MAX;
141  axis = std::string("y");
142  other_axis = std::string("x");
143  }
144  pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr cloud_normals_pass (new pcl::PointCloud<pcl::PointXYZRGBNormal>);
145  pcl::PassThrough<pcl::PointXYZRGBNormal> pass;
146  pcl::IndicesPtr indices_x(new std::vector<int>());
147  pass.setInputCloud (cloud_normals);
148  pass.setFilterFieldName (axis);
149  float small = std::min(lucky, lucky + pass_offset_);
150  float large = std::max(lucky, lucky + pass_offset_);
151  pass.setFilterLimits (small, large);
152  pass.filter (*cloud_normals_pass);
153  pass.setInputCloud (cloud_normals_pass);
154  pass.setFilterFieldName (other_axis);
155  float small2 = std::min(lucky2, lucky2 + pass_offset2_);
156  float large2 = std::max(lucky2, lucky2 + pass_offset2_);
157  pass.setFilterLimits (small2, large2);
158  pass.filter (*cloud_normals_pass);
159 
160  std::vector<int> tmp_indices;
161  pcl::removeNaNFromPointCloud(*cloud_normals_pass, *cloud_normals_pass, tmp_indices);
162 
163  if(cloud_normals_pass->points.size() == 0)
164  continue;
165 
166  pcl::FPFHEstimationOMP<pcl::PointXYZRGBNormal, pcl::PointXYZRGBNormal, pcl::FPFHSignature33> fpfh;
167  pcl::search::KdTree<pcl::PointXYZRGBNormal>::Ptr tree (new pcl::search::KdTree<pcl::PointXYZRGBNormal>);
168  pcl::PointCloud<pcl::FPFHSignature33>::Ptr fpfhs (new pcl::PointCloud<pcl::FPFHSignature33> ());
169  fpfh.setNumberOfThreads(8);
170  fpfh.setInputCloud (cloud_normals_pass);
171  fpfh.setInputNormals (cloud_normals_pass);
172  fpfh.setSearchMethod (tree);
173  fpfh.setRadiusSearch (radius_search_);
174  fpfh.compute (*fpfhs);
175 
176  if((int)fpfhs->points.size() == 0)
177  continue;
178 
179  std::vector<double> result;
180  int target_id, max_value;
181  if ((int)fpfhs->points.size() - sum_num_ - 1 < 1){
182  target_id = 0;
183  max_value = (int)fpfhs->points.size();
184  }else{
185  target_id = rand() % ((int)fpfhs->points.size() - sum_num_ - 1);
186  max_value = target_id + sum_num_;
187  }
188 
189  bool has_nan = false;
190  for(int index = 0; index < 33; index++){
191  float sum_hist_points = 0;
192  for(int kndex = target_id; kndex < max_value;kndex++)
193  {
194  sum_hist_points+=fpfhs->points[kndex].histogram[index];
195  }
196  result.push_back( sum_hist_points/sum_num_ );
197  }
198 
199  for(int x = 0; x < result.size(); x ++){
200  if(pcl_isnan(result[x]))
201  has_nan = true;
202  }
203  if(has_nan)
204  break;
205 
206  call_counter++;
207  ros::ServiceClient client = pnh_->serviceClient<ml_classifiers::ClassifyData>("classify_server");
208  ml_classifiers::ClassifyData srv;
209  ml_classifiers::ClassDataPoint class_data_point;
210  class_data_point.point = result;
211  srv.request.data.push_back(class_data_point);
212  if(client.call(srv))
213  if (atoi(srv.response.classifications[0].c_str()) == 0)
214  result_counter += 1;
215  NODELET_DEBUG("response result : %s", srv.response.classifications[0].c_str());
216  }
217 
218  if(result_counter >= call_counter / 2){
219  NODELET_DEBUG("Result == 0 because counter is %d / %d", result_counter, call_counter);
220  }
221  else{
222  NODELET_DEBUG("Result != 0 because counter is %d / %d", result_counter, call_counter);
223  }
224 
225  for (int i = 0; i < cloud_cluster->points.size(); i++){
226  if(result_counter >= call_counter / 2){
227  cloth_cloud_cluster->points.push_back (cloud_cluster->points[i]);
228  }
229  else{
230  noncloth_cloud_cluster->points.push_back (cloud_cluster->points[i]);
231  }
232  }
233  }
234  sensor_msgs::PointCloud2 cloth_pointcloud2;
235  pcl::toROSMsg(*cloth_cloud_cluster, cloth_pointcloud2);
236  cloth_pointcloud2.header = pc.header;
237  cloth_pointcloud2.is_dense = false;
238  pub_.publish(cloth_pointcloud2);
239 
240  sensor_msgs::PointCloud2 noncloth_pointcloud2;
241  pcl::toROSMsg(*noncloth_cloud_cluster, noncloth_pointcloud2);
242  noncloth_pointcloud2.header = pc.header;
243  noncloth_pointcloud2.is_dense = false;
244  pub2_.publish(noncloth_pointcloud2);
245  }
246 }
247 
double min(const OneDataStat &d)
wrapper function for min method for boost::function
Definition: one_data_stat.h:94
#define NODELET_WARN(...)
void publish(const boost::shared_ptr< M > &message) const
double max(const OneDataStat &d)
wrapper function for max method for boost::function
bool call(MReq &req, MRes &res)
void fromROSMsg(const sensor_msgs::PointCloud2 &cloud, pcl::PointCloud< T > &pcl_cloud)
unsigned int index
result
boost::shared_ptr< ros::NodeHandle > pnh_
PLUGINLIB_EXPORT_CLASS(jsk_pcl_ros::ColorizeRandomForest, nodelet::Nodelet)
srv
void toROSMsg(const pcl::PointCloud< T > &pcl_cloud, sensor_msgs::PointCloud2 &cloud)
#define NULL
void extract(const sensor_msgs::PointCloud2 cloud)
cloud
#define NODELET_DEBUG(...)


jsk_pcl_ros
Author(s): Yohei Kakiuchi
autogenerated on Mon May 3 2021 03:03:46