feature_extractor_node.cpp
Go to the documentation of this file.
00001 #include "ros/ros.h"
00002 #include "sensor_msgs/PointCloud2.h"
00003 #include "sensor_msgs/point_cloud_conversion.h"
00004 
00005 #include <boost/make_shared.hpp>
00006 #include "pcl/io/pcd_io.h"
00007 #include <pcl/features/fpfh_omp.h>
00008 #include <pcl/kdtree/kdtree_flann.h>
00009 #include <pcl/features/normal_3d_omp.h>
00010 #include "pcl/filters/voxel_grid.h"
00011 
00012 //#include "feature_extractor_fpfh/AddTwoInts.h"
00013 #include "feature_extractor_fpfh/FPFHCalc.h"
00014 
00015 using namespace pcl;
00016 using namespace std;
00017 typedef KdTree<PointXYZ>::Ptr KdTreePtr;
00018 
00019 
00020 bool fpfh_cb(feature_extractor_fpfh::FPFHCalc::Request &req,
00021              feature_extractor_fpfh::FPFHCalc::Response &res)
00022 {
00023     float leaf_size = .01;
00024     pcl::VoxelGrid<sensor_msgs::PointCloud2> sor;
00025     sensor_msgs::PointCloud2::Ptr input_cloud(new sensor_msgs::PointCloud2());
00026     sensor_msgs::convertPointCloudToPointCloud2(req.input, *input_cloud);
00027     //sensor_msgs::PointCloud2::Ptr input_cloud(&req.input);
00028 
00029     sensor_msgs::PointCloud2::Ptr cloud_filtered(new sensor_msgs::PointCloud2());
00030     sor.setInputCloud(input_cloud);
00031     sor.setLeafSize (leaf_size, leaf_size, leaf_size);
00032     sor.filter(*cloud_filtered);
00033     ROS_INFO("after filtering: %d points", cloud_filtered->width * cloud_filtered->height);
00034 
00035     PointCloud<PointXYZ> cloud;
00036     fromROSMsg(*cloud_filtered, cloud);
00037     std::vector<int> indices;
00038     indices.resize (cloud.points.size());
00039     for (size_t i = 0; i < indices.size (); ++i) { indices[i] = i; }
00040 
00041     // make tree
00042     KdTreePtr tree;
00043     tree.reset(new KdTreeFLANN<PointXYZ> (false));
00044     tree->setInputCloud(cloud.makeShared());
00045 
00046     PointCloud<Normal>::Ptr normals(new PointCloud<Normal>());
00047     boost::shared_ptr< vector<int> > indicesptr(new vector<int> (indices));
00048     NormalEstimation<PointXYZ, Normal> normal_estimator;
00049 
00050     // set normal estimation parameters
00051     normal_estimator.setIndices(indicesptr);
00052     normal_estimator.setSearchMethod(tree);
00053     normal_estimator.setKSearch(10); // Use 10 nearest neighbors to estimate the normals
00054 
00055     // estimate
00056     ROS_INFO("Calculating normals...\n");
00057     normal_estimator.setInputCloud(cloud.makeShared());
00058     normal_estimator.compute(*normals);
00059 
00060     // calculate FPFH
00061     //FPFHEstimation<PointXYZ, Normal, FPFHSignature33> fpfh;
00062     FPFHEstimationOMP<PointXYZ, Normal, FPFHSignature33> fpfh(4);    // instantiate 4 threads
00063 
00064     // object
00065     PointCloud<FPFHSignature33>::Ptr fphists (new PointCloud<FPFHSignature33>());
00066 
00067     // set parameters
00068     int d1, d2, d3;
00069     d1 = d2 = d3 = 11;
00070     fpfh.setNrSubdivisions(d1, d2, d3);
00071     fpfh.setIndices(indicesptr);
00072     fpfh.setSearchMethod(tree);
00073     fpfh.setKSearch(50);
00074 
00075     // estimate
00076     ROS_INFO("Calculating fpfh...\n");
00077     fpfh.setInputNormals(normals);
00078     fpfh.setInputCloud(cloud.makeShared());
00079     fpfh.compute(*fphists);
00080 
00081     res.hist.dim[0] = d1;
00082     res.hist.dim[1] = d2;
00083     res.hist.dim[2] = d3;
00084     unsigned int total_size = d1+d2+d3;
00085     res.hist.histograms.resize(total_size * cloud.points.size());
00086     res.hist.points3d.resize(3*cloud.points.size());
00087 
00088     ROS_INFO("copying into message...\n");
00089     for (unsigned int i = 0; i < cloud.points.size(); i++)
00090     {
00091         for (unsigned int j = 0; j < total_size; j++)
00092         {
00093             res.hist.histograms[i*total_size + j] = fphists->points[i].histogram[j];
00094             //if (i == 0)
00095             //{
00096             //    printf(">> %.2f \n", fphists->points[i].histogram[j]);
00097             //}
00098 
00099             //if (i == 4)
00100             //{
00101             //    printf("X %.2f \n", fphists->points[i].histogram[j]);
00102             //}
00103         }
00104 
00105         res.hist.points3d[3*i]   = cloud.points[i].x;
00106         res.hist.points3d[3*i+1] = cloud.points[i].y;
00107         res.hist.points3d[3*i+2] = cloud.points[i].z;
00108         //if (i == 0)
00109         //    printf(">> 0  %.4f %.4f %.4f \n", cloud.points[i].x, cloud.points[i].y, cloud.points[i].z);
00110         //if (i == 4)
00111         //    printf(">> 4  %.4f %.4f %.4f \n", cloud.points[i].x, cloud.points[i].y, cloud.points[i].z);
00112     }
00113 
00114     res.hist.npoints = cloud.points.size();
00115     ROS_INFO("done.\n");
00116     //printf("%d\n", );
00117     // sensor_msgs::PointCloud2 req
00118     // new feature_extractor::FPFHist()
00119     return true;
00120 }
00121 
00122 
00123 
00124 int main(int argc, char **argv)
00125 {
00126   ros::init(argc, argv, "fpfh_feature_extractor");
00127   ros::NodeHandle n;
00128   //ros::ServiceServer service = n.advertiseService("fpfh", fpfh);
00129   //ros::ServiceServer service = n.advertiseService("add", add);
00130   ros::ServiceServer fpfh_service = n.advertiseService("fpfh", fpfh_cb);
00131 
00132   //ros::ServiceServer service = n.advertiseService("fpfh", boost::bind(&fpfh, _1, _2));
00133   ROS_INFO("ready.\n");
00134   ros::spin();
00135   return 0;
00136 }
00137 
00138 
00139 
00140 
00141 
00142 
00143 
00144 //bool add(feature_extractor::AddTwoInts::Request  &req,
00145 //         feature_extractor::AddTwoInts::Response &res )
00146 //{
00147 //  res.sum = req.a + req.b;
00148 //  ROS_INFO("request: x=%ld, y=%ld", (long int)req.a, (long int)req.b);
00149 //  ROS_INFO("sending back response: [%ld]", (long int)res.sum);
00150 //  return true;
00151 //}


feature_extractor_fpfh
Author(s): Hai Nguyen
autogenerated on Wed Nov 27 2013 11:46:13