colorize_random_points_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  *********************************************************************/
36 #include <pcl/common/centroid.h>
37 
38 namespace jsk_pcl_ros
39 {
41  {
42  ConnectionBasedNodelet::onInit();
43  pub_ = advertise<sensor_msgs::PointCloud2>(*pnh_, "output", 1);
44 
45  srand(time(NULL));
46 
47  double tmp_radius, tmp_pass, tmp_pass2;
48  int tmp_sum_num;
49  tmp_radius = 0.03;
50  tmp_pass = 0.03;
51  tmp_pass2 = 0.06;
52  tmp_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 
58  if (!pnh_->getParam("po", tmp_pass))
59  {
60  NODELET_WARN("~po is not specified, so set to 0.03");
61  }
62 
63  if (!pnh_->getParam("po2", tmp_pass2))
64  {
65  NODELET_WARN("~po2 is not specified, so set to 0.06");
66  }
67 
68  if (!pnh_->getParam("sum_num", tmp_sum_num))
69  {
70  NODELET_WARN("~sum_num is not specified, so set to 100");
71  }
72 
73  radius_search_ = tmp_radius;
74  pass_offset_ = tmp_pass;
75  pass_offset2_ = tmp_pass2;
76  sum_num_ = tmp_sum_num;
78  }
79 
81  {
82  sub_input_ = pnh_->subscribe("input", 1, &ColorizeMapRandomForest::extract, this);
83  }
84 
86  {
88  }
89 
90  void ColorizeMapRandomForest::extract(const sensor_msgs::PointCloud2 pc)
91  {
92  pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloud (new pcl::PointCloud<pcl::PointXYZRGB> ());
93 
94  std::vector<int> indices;
95  pcl::fromROSMsg(pc, *cloud);
96 
97  cloud->is_dense = false;
98  pcl::removeNaNFromPointCloud(*cloud, *cloud, indices);
99 
100  pcl::search::KdTree<pcl::PointXYZRGB>::Ptr tree (new pcl::search::KdTree<pcl::PointXYZRGB>);
101  tree->setInputCloud (cloud);
102 
103  pcl::PassThrough<pcl::PointXYZRGB> pass;
104  pass.setInputCloud (cloud);
105  pass.setFilterFieldName (std::string("z"));
106  pass.setFilterLimits (0.0, 1.5);
107  pass.filter (*cloud);
108 
109  pcl::NormalEstimation<pcl::PointXYZRGB, pcl::PointXYZRGBNormal> ne;
110  pcl::search::KdTree<pcl::PointXYZRGB>::Ptr tree2 (new pcl::search::KdTree<pcl::PointXYZRGB> ());
111  pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr cloud_normals (new pcl::PointCloud<pcl::PointXYZRGBNormal>);
112  ne.setInputCloud (cloud);
113  NODELET_DEBUG("normal estimate");
114  ne.setSearchMethod (tree2);
115  ne.setRadiusSearch (0.02);
116  ne.compute (*cloud_normals);
117 
118  for (int cloud_index = 0; cloud_index < cloud_normals->points.size(); cloud_index++){
119  cloud_normals->points[cloud_index].x = cloud->points[cloud_index].x;
120  cloud_normals->points[cloud_index].y = cloud->points[cloud_index].y;
121  cloud_normals->points[cloud_index].z = cloud->points[cloud_index].z;
122  // cloud_normals->points[cloud_index].rgba = cloud->points[cloud_index].rgba;
123  }
124 
125  int result_counter=0, call_counter = 0;
126  pcl::PointXYZRGBNormal max_pt,min_pt;
127  pcl::getMinMax3D(*cloud_normals, min_pt, max_pt);
128  for (int i = 0 ; i < 200; i++){
129  NODELET_DEBUG("fpfh %d / 200", i);
130  double lucky = 0, lucky2 = 0;
131  std::string axis("x"),other_axis("y");
132  int rand_xy = rand()%2;
133  if (rand_xy == 0){
134  lucky = min_pt.x - pass_offset_ + (max_pt.x - min_pt.x - pass_offset_*2) * 1.0 * rand() / RAND_MAX;
135  lucky2 = min_pt.y + (max_pt.y - min_pt.y) * 1.0 * rand() / RAND_MAX;
136  }
137  else {
138  lucky = min_pt.y - pass_offset_ + (max_pt.y - min_pt.y - pass_offset_*2) * 1.0 * rand() / RAND_MAX;
139  lucky2 = min_pt.x + (max_pt.x - min_pt.x) * 1.0 * rand() / RAND_MAX;
140  axis = std::string("y");
141  other_axis = std::string("x");
142  }
143 
144  pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr cloud_normals_pass (new pcl::PointCloud<pcl::PointXYZRGBNormal>);
145 
146  pcl::PassThrough<pcl::PointXYZRGBNormal> pass;
147  pcl::IndicesPtr indices_x(new std::vector<int>());
148  pass.setInputCloud (cloud_normals);
149  pass.setFilterFieldName (axis);
150  float small = std::min(lucky, lucky + pass_offset_);
151  float large = std::max(lucky, lucky + pass_offset_);
152  pass.setFilterLimits (small, large);
153  pass.filter (*cloud_normals_pass);
154  pass.setInputCloud (cloud_normals_pass);
155  pass.setFilterFieldName (other_axis);
156  float small2 = std::min(lucky2, lucky2 + pass_offset2_);
157  float large2 = std::max(lucky2, lucky2 + pass_offset2_);
158  pass.setFilterLimits (small2, large2);
159  pass.filter (*cloud_normals_pass);
160 
161  std::vector<int> tmp_indices;
162  pcl::removeNaNFromPointCloud(*cloud_normals_pass, *cloud_normals_pass, tmp_indices);
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 tree4 (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 (tree4);
173  fpfh.setRadiusSearch (radius_search_);
174  fpfh.compute (*fpfhs);
175  int target_id, max_value;
176  if ((int)fpfhs->points.size() - sum_num_ - 1 < 1){
177  target_id = 0;
178  max_value = (int)fpfhs->points.size();
179  }else{
180  target_id = rand() % ((int)fpfhs->points.size() - sum_num_ - 1);
181  max_value = target_id + sum_num_;
182  }
183  std::vector<double> result;
184  bool success = true;
185 
186  for(int index = 0; index < 33; index++){
187  float sum_hist_points = 0;
188  for(int kndex = target_id; kndex < max_value;kndex++)
189  {
190  if(pcl_isnan(fpfhs->points[kndex].histogram[index])){
191  success = false;
192  }else{
193  sum_hist_points+=fpfhs->points[kndex].histogram[index];
194  }
195  }
196  result.push_back( sum_hist_points/sum_num_ );
197  }
198 
199  bool cloth = false;
200  if(success){
201  call_counter++;
202  ros::ServiceClient client = pnh_->serviceClient<ml_classifiers::ClassifyData>("classify_server");
203  ml_classifiers::ClassifyData srv;
204  ml_classifiers::ClassDataPoint class_data_point;
205  class_data_point.point = result;
206  srv.request.data.push_back(class_data_point);
207  if(client.call(srv))
208  if (atoi(srv.response.classifications[0].c_str()) == 0)
209  cloth = true;
210  NODELET_DEBUG("response result : %s", srv.response.classifications[0].c_str());
211  }else{
212  continue;
213  }
214 
215  Eigen::Vector4f c;
216  pcl::compute3DCentroid (*cloud_normals_pass, c);
217 
218  pcl::octree::OctreePointCloudSearch<pcl::PointXYZRGBNormal> search_octree (0.05);
219  search_octree.setInputCloud (cloud_normals);
220  search_octree.addPointsFromInputCloud ();
221 
222  pcl::PointXYZRGBNormal point_a;
223  point_a.x = c[0];point_a.y = c[1];point_a.z = c[2];
224  std::vector<int> k_indices;
225  std::vector<float> k_sqr_distances;
226  search_octree.radiusSearch(point_a, 0.05, k_indices, k_sqr_distances);
227 
228  for(int index = 0; index < k_indices.size(); index++){
229  int id = k_indices[index];
230  if(cloth){
231  cloud_normals->points[id].r = std::min(std::max(255.0 - sqrt(k_sqr_distances[index]) * 2000, 0.0) + cloud_normals->points[id].r, 255.0);
232  }else{
233  cloud_normals->points[id].b = std::min(std::max(255.0 - sqrt(k_sqr_distances[index]) * 2000, 0.0) + cloud_normals->points[id].b, 255.0);
234  }
235  }
236  }
237  sensor_msgs::PointCloud2 _pointcloud2;
238  pcl::toROSMsg(*cloud_normals, _pointcloud2);
239  _pointcloud2.header = pc.header;
240  _pointcloud2.is_dense = false;
241  pub_.publish(_pointcloud2);
242  }
243 }
244 
245 
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
double sqrt()
boost::shared_ptr< ros::NodeHandle > pnh_
srv
PLUGINLIB_EXPORT_CLASS(jsk_pcl_ros::ColorizeMapRandomForest, nodelet::Nodelet)
void toROSMsg(const pcl::PointCloud< T > &pcl_cloud, sensor_msgs::PointCloud2 &cloud)
#define NULL
c
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