segmentation_all_in_one_nodelet.cpp
Go to the documentation of this file.
00001 
00063 #include <sstream>
00064 
00065 // ROS includes
00066 #include <ros/ros.h>
00067 #include <pluginlib/class_list_macros.h>
00068 #include <boost/make_shared.hpp>
00069 
00070 #include <pcl/io/io.h>
00071 #include <pcl/io/pcd_io.h>
00072   #ifdef PCL_VERSION_COMPARE //fuerte
00073     #include <pcl/for_each_type.h>
00074   #else //electric
00075     #include <pcl/ros/for_each_type.h>
00076   #endif
00077 
00078 #include <pcl_ros/point_cloud.h>
00079 #include <pcl_conversions/pcl_conversions.h>
00080 
00081 // Package includes
00082 #include <cob_3d_mapping_msgs/ShapeArray.h>
00083 #include <cob_3d_mapping_common/cylinder.h>
00084 #include <cob_3d_mapping_common/ros_msg_conversions.h>
00085 #include <cob_3d_mapping_common/stop_watch.h>
00086 #include "cob_3d_segmentation/segmentation_all_in_one_nodelet.h"
00087 
00088 
00089 void
00090 cob_3d_segmentation::SegmentationAllInOneNodelet::onInit()
00091 {
00092   nh_ = getNodeHandle();
00093 
00094   config_server_.reset(new dynamic_reconfigure::Server<segmentation_nodeletConfig>(getPrivateNodeHandle()));
00095   config_server_->setCallback(boost::bind(&SegmentationAllInOneNodelet::configCallback, this, _1, _2));
00096 
00097   one_.setOutputLabels(labels_);
00098   one_.setPixelSearchRadius(8,2,2);
00099   one_.setSkipDistantPointThreshold(8);
00100 
00101   seg_.setNormalCloudIn(normals_);
00102   seg_.setLabelCloudInOut(labels_);
00103   seg_.setClusterGraphOut(graph_);
00104 
00105   cc_.setClusterHandler(graph_->clusters());
00106   cc_.setNormalCloudInOut(normals_);
00107   cc_.setLabelCloudIn(labels_);
00108 
00109   if(!is_running_ && !enable_action_mode_)
00110   {
00111     ROS_INFO("Starting segmentation...");
00112     sub_points_ = nh_.subscribe("cloud_in", 1, &SegmentationAllInOneNodelet::receivedCloudCallback, this);
00113     is_running_ = true;
00114   }
00115   pub_segmented_ = nh_.advertise<PointCloud>("/segmentation/segmented_cloud", 1);
00116   pub_classified_ = nh_.advertise<PointCloud>("/segmentation/classified_cloud", 1);
00117   pub_shape_array_ = nh_.advertise<cob_3d_mapping_msgs::ShapeArray>("/segmentation/shape_array",1);
00118   pub_chull_ = nh_.advertise<PointCloud>("/segmentation/concave_hull", 1);
00119   pub_chull_dense_ = nh_.advertise<PointCloud>("/segmentation/concave_hull_dense", 1);
00120   std::cout << "Loaded segmentation nodelet" << std::endl;
00121 
00122   as_ = new actionlib::SimpleActionServer<cob_3d_mapping_msgs::TriggerAction>(nh_, "segmentation/trigger", boost::bind(&SegmentationAllInOneNodelet::actionCallback, this, _1), false);
00123   as_->start();
00124 }
00125 
00126 void
00127 cob_3d_segmentation::SegmentationAllInOneNodelet::configCallback(
00128     cob_3d_segmentation::segmentation_nodeletConfig& config,
00129     uint32_t level)
00130 {
00131   NODELET_INFO("[segmentation]: received new parameters");
00132   centroid_passthrough_ = config.centroid_passthrough;
00133   enable_action_mode_ = config.enable_action_mode;
00134 }
00135 
00136 
00137 void
00138 cob_3d_segmentation::SegmentationAllInOneNodelet::actionCallback(
00139   const cob_3d_mapping_msgs::TriggerGoalConstPtr& goal)
00140 {
00141   cob_3d_mapping_msgs::TriggerResult result;
00142   if(goal->start && !is_running_)
00143   {
00144     ROS_INFO("Starting segmentation...");
00145     sub_points_ = nh_.subscribe("cloud_in", 1, &SegmentationAllInOneNodelet::receivedCloudCallback, this);
00146     is_running_ = true;
00147   }
00148   else if(!goal->start && is_running_)
00149   {
00150     ROS_INFO("Stopping segmentation...");
00151     sub_points_.shutdown();
00152     is_running_ = false;
00153   }
00154 
00155   as_->setSucceeded(result);
00156 }
00157 
00158 
00159 void
00160 cob_3d_segmentation::SegmentationAllInOneNodelet::receivedCloudCallback(PointCloud::ConstPtr cloud)
00161 {
00162   PrecisionStopWatch t;
00163   t.precisionStart();
00164   NODELET_INFO("Start with segmentation .... ");
00165   one_.setInputCloud(cloud);
00166   one_.compute(*normals_);
00167 
00168   *classified_ = *segmented_ = *cloud;
00169 
00170   seg_.setInputCloud(cloud);
00171   seg_.performInitialSegmentation();
00172   seg_.refineSegmentation();
00173   graph_->clusters()->mapClusterColor(segmented_);
00174 
00175   //seg_.getPotentialObjects(objects, 500);
00176   //std::cout << "Found " << objects.size() << " potentail objects" << std::endl;
00177   NODELET_INFO("Done with segmentation .... ");
00178 
00179 
00180   cc_.setPointCloudIn(cloud);
00181   cc_.classify();
00182   graph_->clusters()->mapTypeColor(classified_);
00183   graph_->clusters()->mapClusterBorders(classified_);
00184   std::cout << "segmentation took " << t.precisionStop() << " s." << std::endl;
00185   //NODELET_INFO("publish first cloud .... ");
00186   pub_segmented_.publish(segmented_);
00187   //NODELET_INFO("publish second cloud .... ");
00188   pub_classified_.publish(classified_);
00189   //NODELET_INFO("publish shape array .... ");
00190   /*
00191   pcl::PointCloud<pcl::PointXYZRGB>::Ptr bp (new pcl::PointCloud<pcl::PointXYZRGB>);
00192    *bp = *cloud;
00193   graph_->clusters()->mapClusterBorders(bp);
00194   std::stringstream ss;
00195   ss << "/share/goa-sf/pcd_data/bags/pcd_borders/borders_"<<cloud->header.stamp<<".pcd";
00196   pcl::io::savePCDFileASCII(ss.str(), *bp);
00197    */
00198   publishShapeArray(graph_->clusters(), cloud);
00199 
00200   NODELET_INFO("Done with publishing .... ");
00201 
00202 }
00203 
00204 void
00205 cob_3d_segmentation::SegmentationAllInOneNodelet::publishShapeArray(
00206   ST::CH::Ptr cluster_handler, PointCloud::ConstPtr cloud)
00207 {
00208   cob_3d_mapping_msgs::ShapeArray sa;
00209   pcl_conversions::fromPCL(cloud->header, sa.header);
00210   //sa.header = cloud->header;
00211   //sa.header.frame_id = cloud->header.frame_id.c_str();
00212   //std::cout<<"[SN]-->CLOUD FRAME"<<cloud->header.frame_id.c_str()<<"\n";
00213   pcl::PointCloud<pcl::PointXYZRGB>::Ptr hull_cloud(new pcl::PointCloud<pcl::PointXYZRGB>);
00214   pcl::PointCloud<pcl::PointXYZRGB>::Ptr hull(new pcl::PointCloud<pcl::PointXYZRGB>);
00215   pcl::PointCloud<pcl::PointXYZRGB>::Ptr hull_cloud_dense(new pcl::PointCloud<pcl::PointXYZRGB>);
00216 
00217   unsigned int id = 0;
00218   for (ST::CH::ClusterPtr c = cluster_handler->begin(); c != cluster_handler->end(); ++c)
00219   {
00220     // compute hull:
00221     if (c->getCentroid()[2] > centroid_passthrough_) continue;
00222     if (c->type != I_PLANE && c->type != I_CYL) continue;
00223     if (c->size() <= ceil(1.1f * static_cast<float>(c->border_points.size())))
00224     {
00225       //std::cout <<"[ " << c->size() <<" | "<< c->border_points.size() << " ]" << std::endl;
00226       continue;
00227     }
00228 
00229     for (size_t i = 0; i < c->border_points.size(); ++i)
00230       hull_cloud_dense->push_back((*segmented_)[c->border_points[i].y * segmented_->width + c->border_points[i].x]);
00231 
00232     PolygonContours<PolygonPoint> poly;
00233     //std::cout << "Get outline for " << c->size() << " Points with "<< c->border_points.size() << " border points" << std::endl;
00234     pe_.outline(cloud->width, cloud->height, c->border_points, poly);
00235     if (!poly.polys_.size()) continue; // continue, if no contours were found
00236     //std::cout << "border -> outline: " << c->border_points.size() << " -> " << poly.polys_[0].size() << std::endl;
00237 
00238     int max_idx=0, max_size=0;
00239     //std::cout << "Polys: ";
00240     for (int i = 0; i < (int)poly.polys_.size(); ++i)
00241     {
00242       //std::cout << poly.polys_[i].size() << " ";
00243       if ((int)poly.polys_[i].size() > max_size) { max_idx = i; max_size = poly.polys_[i].size(); }
00244     }
00245     //std::cout << std::endl;
00246 
00247     sa.shapes.push_back(cob_3d_mapping_msgs::Shape());
00248     cob_3d_mapping_msgs::Shape* s = &sa.shapes.back();
00249     //s->id = id++;
00250     //s->points.resize(poly.polys_.size());
00251     s->header.frame_id = cloud->header.frame_id.c_str();
00252     Eigen::Vector3f color_tmp = c->computeDominantColorVector().cast<float>();
00253     float temp_inv = 1.0f/255.0f;
00254     std::vector<float> color(4,1);
00255     color[0] = color_tmp(0) * temp_inv;
00256     color[1] = color_tmp(1) * temp_inv;
00257     color[2] = color_tmp(2) * temp_inv;
00258     /*s->color.r = color(0) * temp_inv;
00259     s->color.g = color(1) * temp_inv;
00260     s->color.b = color(2) * temp_inv;
00261     s->color.a = 1.0f;*/
00262     //Eigen::Vector3f origin = c->getCentroid();
00263     //    Eigen::Matrix3f M = Eigen::Matrix3f::Identity() - c->pca_point_comp3 * c->pca_point_comp3.transpose(); // projection
00264     /*for (int i = 0; i < (int)poly.polys_.size(); ++i)
00265     {
00266       pcl::PointXYZRGB p;
00267       if (i == max_idx)
00268       {
00269         s->holes.push_back(false);
00270         std::vector<PolygonPoint>::iterator it = poly.polys_[i].begin();
00271         for ( ; it != poly.polys_[i].end(); ++it)
00272         {
00273           p.getVector3fMap() = cloud->points[PolygonPoint::getInd(it->x, it->y)].getVector3fMap();
00274           hull_cloud->points.push_back(p);
00275           hull->points.push_back(p);
00276         }
00277       }
00278       else
00279       {
00280         s->holes.push_back(true);
00281         std::vector<PolygonPoint>::reverse_iterator it = poly.polys_[i].rbegin();
00282         for ( ; it != poly.polys_[i].rend(); ++it)
00283         {
00284           p.getVector3fMap() = cloud->points[PolygonPoint::getInd(it->x, it->y)].getVector3fMap();
00285           hull_cloud->points.push_back(p);
00286           hull->points.push_back(p);
00287         }
00288       }
00289       hull->height = 1;
00290       hull->width = hull->points.size();
00291       pcl::toROSMsg(*hull, s->points[i]);
00292       hull->clear();
00293     }*/
00294     /*Eigen::Affine3f pose_inv;
00295     pcl::getTransformationFromTwoUnitVectorsAndOrigin(
00296         normal.unitOrthogonal(), normal, centroid, pose_inv);
00297     tf::poseEigenToMsg(pose.inverse().cast<double>(), s->pose_inv.inverse());*/
00298     /*s->centroid.x = centroid[0];
00299     s->centroid.y = centroid[1];
00300     s->centroid.z = centroid[2];*/
00301 
00302     std::vector<pcl::PointCloud<pcl::PointXYZ> > contours_3d;
00303     std::vector<bool> holes;
00304     //pcl::transformPointCloud(*cloud, cloud_tr, pose.inverse());
00305     for (int i = 0; i < (int)poly.polys_.size(); ++i)
00306     {
00307       pcl::PointCloud<pcl::PointXYZ> contour;
00308       if (i == max_idx)
00309       {
00310         holes.push_back(false);
00311         std::vector<PolygonPoint>::iterator it = poly.polys_[i].begin();
00312         for ( ; it != poly.polys_[i].end(); ++it) {
00313           pcl::PointXYZ pt;
00314           pt.getVector3fMap() = cloud->points[ it->x + it->y * cloud->width ].getVector3fMap();
00315           contour.push_back( pt );
00316           //contour.push_back( cloud->points[ it->x + it->y * cloud->width ] );
00317         }
00318       }
00319       else
00320       {
00321         holes.push_back(true);
00322         std::vector<PolygonPoint>::reverse_iterator it = poly.polys_[i].rbegin();
00323         for ( ; it != poly.polys_[i].rend(); ++it) {
00324           pcl::PointXYZ pt;
00325           pt.getVector3fMap() = cloud->points[ it->x + it->y * cloud->width ].getVector3fMap();
00326           contour.push_back( pt );
00327           //contour.push_back( cloud->points[ it->x + it->y * cloud->width ] );
00328         }
00329       }
00330       contour.height = 1;
00331       contour.width = contour.size();
00332       contours_3d.push_back(contour);
00333       //pcl::toROSMsg(*hull, s->points[i]);
00334       //hull->clear();
00335     }
00336 
00337     // Set type specific parameters:
00338     switch(c->type)
00339     {
00340     case I_PLANE:
00341     {
00342       cob_3d_mapping::Polygon::Ptr  poly(new cob_3d_mapping::Polygon(id,
00343                                                                      c->pca_point_comp3,
00344                                                                      c->getCentroid()/*fabs(c->getCentroid().dot(c->pca_point_comp3))*/,
00345                                                                      contours_3d,
00346                                                                      holes,
00347                                                                      color));
00348       cob_3d_mapping::toROSMsg(*poly, *s);
00349       //std::cout << "Plane: " << c->size() << ", " << c->border_points.size() << std::endl;
00350       /*s->type = cob_3d_mapping_msgs::Shape::POLYGON;
00351 
00352       s->params.resize(4);
00353       Eigen::Vector3f orientation =  c->pca_point_comp3;
00354       s->params[0] = orientation(0); // n_x
00355       s->params[1] = orientation(1); // n_y
00356       s->params[2] = orientation(2); // n_z
00357       s->params[3] = fabs(centroid.dot(orientation)); // d*/
00358       break;
00359     }
00360     case I_CYL:
00361     {
00362       /*Cylinder(unsigned int id,
00363                    Eigen::Vector3f origin,
00364                    Eigen::Vector3f sym_axis,
00365                    double radius,
00366                    std::vector<pcl::PointCloud<pcl::PointXYZ> >& contours_3d,
00367                    std::vector<bool> holes,
00368                    std::vector<float> color*/
00369       //std::cout<<"CLYINDER is published\n";
00370       //s->type = cob_3d_mapping_msgs::Shape::CYLINDER;
00371       //s->params.resize(6);
00372       Eigen::Vector3f origin = c->getCentroid();
00373       double radius = cob_3d_mapping::radiusAndOriginFromCloud(cloud, c->indices_, origin, c->pca_inter_comp1);
00374       cob_3d_mapping::Cylinder::Ptr cyl = cob_3d_mapping::Cylinder::Ptr(new cob_3d_mapping::Cylinder(id,
00375                                                                                                       origin,
00376                                                                                                       c->pca_inter_comp1,
00377                                                                                                       radius,
00378                                                                                                       contours_3d,
00379                                                                                                       holes,
00380                                                                                                       color));
00381       //Eigen::Vector3f centroid3f  = c->getCentroid();
00382       //cyl->centroid << centroid3f[0] , centroid3f[1] , centroid3f[2] , 0;
00383 
00384       //cyl->sym_axis_ =  c->pca_inter_comp1;
00385       //cyl->updateAttributes(c->pca_inter_comp1, centroid3f);
00386       //std::cout<<"sym axis\n"<<cyl->sym_axis<<"\n";
00387       //std::cout<<"centroid\n"<<cyl->centroid<<"\n";
00388       //cyl->ParamsFromCloud(cloud,c->indices_);
00389       //cyl->r_ = radiusFromCloud(cloud,c->indices_);
00390 
00391       cob_3d_mapping::toROSMsg(*cyl, *s);
00392       //pcl::io::savePCDFile("/tmp/cyl_cont.pcd", contours_3d[0]);
00393       //write parameters to msg - after transformation to target frame
00394       /*s->params[0] = cyl->normal[0];
00395       s->params[1] = cyl->normal[1];
00396       s->params[2] = cyl->normal[2];
00397 
00398       s->params[3] = cyl->sym_axis[0];
00399       s->params[4] = cyl->sym_axis[1];
00400       s->params[5] = cyl->sym_axis[2];
00401 
00402 
00403       s->params[6] = cyl->origin_[0];
00404       s->params[7] = cyl->origin_[1];
00405       s->params[8] = cyl->origin_[2];
00406 
00407       s->params[9]= cyl->r_;*/
00408 
00409       break;
00410     }
00411     default:
00412     {
00413       break;
00414     }
00415     }
00416     id++;
00417     /*for (int i = 0; i < sa.shapes.back().points.size(); ++i)
00418       {
00419       std::cout << "Size: " << sa.shapes.back().points[i].data.size()  cob_3d_mapping_msgs::PlaneExtractionFeedback feedback_;
00420       cob_3d_mapping_msgs::PlaneExtractionResult result_;
00421       << " \t Step: " << sa.shapes.back().points[i].point_step << std::endl;
00422       }*/
00423   }
00424   hull_cloud->header = cloud->header;
00425   hull_cloud->height = 1;
00426   hull_cloud->width = hull_cloud->size();
00427   hull_cloud_dense->header = cloud->header;
00428   hull_cloud_dense->height = 1;
00429   hull_cloud_dense->width = hull_cloud_dense->size();
00430   pub_chull_.publish(hull_cloud);
00431   pub_chull_dense_.publish(hull_cloud_dense);
00432   pub_shape_array_.publish(sa);
00433   //std::cout<<"[SN]-->sa array frame set to"<<sa.header.frame_id.c_str()<<"\n";
00434 }
00435 
00436 
00437 PLUGINLIB_DECLARE_CLASS(cob_3d_segmentation, SegmentationAllInOneNodelet, cob_3d_segmentation::SegmentationAllInOneNodelet, nodelet::Nodelet);


cob_3d_segmentation
Author(s): Georg Arbeiter
autogenerated on Wed Aug 26 2015 11:03:03