fpfh_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 #include "feature_extractor_fpfh/FPFHHist.h"
00015 #include "feature_extractor_fpfh/fpfh_node.h"
00016 
00017 #include "message_filters/subscriber.h"
00018 #include "message_filters/time_synchronizer.h"
00019 
00020 using namespace pcl;
00021 using namespace std;
00022 using namespace message_filters;
00023 typedef KdTree<PointXYZ>::Ptr KdTreePtr;
00024 
00025 using namespace message_filters;
00026 
00027 
00028 FPFHNode::FPFHNode(ros::NodeHandle &n): n_(n)
00029 {
00030     hist_publisher = n_.advertise<feature_extractor_fpfh::FPFHHist>("fpfh_hist", 10); 
00031     fpfh_service = n_.advertiseService("fpfh", &FPFHNode::fpfh_srv_cb, this);
00032     subsample_service = n_.advertiseService("subsample", &FPFHNode::subsample_srv_cb, this);
00033 }
00034 
00035 
00036 bool FPFHNode::fpfh_srv_cb(feature_extractor_fpfh::FPFHCalc::Request &req,
00037              feature_extractor_fpfh::FPFHCalc::Response &res)
00038 {
00039     //ROS_INFO("cloud has %d points", req.input->width * req.input->height);
00040     //feature_extractor_fpfh::FPFHHist::ConstPtr hist(&res.hist);
00041     //sensor_msgs::PointCloud2 cloud2;
00042     sensor_msgs::PointCloud2 *cloud2 = new sensor_msgs::PointCloud2();
00043     sensor_msgs::convertPointCloudToPointCloud2(req.input, *cloud2);
00044     ROS_INFO("cloud has %d points", cloud2->width * cloud2->height);
00045 
00046     const sensor_msgs::PointCloud2::ConstPtr input_cloud((const sensor_msgs::PointCloud2 *) cloud2);
00047     ROS_INFO("done1\n");
00048     process_point_cloud(input_cloud, res.hist);
00049     ROS_INFO("done2\n");
00050     //delete cloud2;
00051     return true;
00052 }
00053 
00054 
00055 bool FPFHNode::subsample_srv_cb(feature_extractor_fpfh::SubsampleCalc::Request &req, 
00056                                 feature_extractor_fpfh::SubsampleCalc::Response &res)
00057 {
00058     //float resolution = .005;
00059     float resolution = .005;
00060 
00061     sensor_msgs::PointCloud2 *cloud2 = new sensor_msgs::PointCloud2();
00062     sensor_msgs::convertPointCloudToPointCloud2(req.input, *cloud2);
00063     ROS_INFO("before cloud has %d points", cloud2->width * cloud2->height);
00064     const sensor_msgs::PointCloud2::ConstPtr input_cloud((const sensor_msgs::PointCloud2 *) cloud2);
00065 
00066     sensor_msgs::PointCloud2 pc2_filtered;
00067     pcl::VoxelGrid<sensor_msgs::PointCloud2> sor;
00068     sor.setInputCloud(input_cloud);
00069     sor.setLeafSize (resolution, resolution, resolution);
00070     sor.filter(pc2_filtered);
00071     sensor_msgs::convertPointCloud2ToPointCloud(pc2_filtered, res.output);
00072     ROS_INFO("after cloud has %d points", pc2_filtered.width * pc2_filtered.height);
00073 
00074     return true;
00075 }
00076 
00077 
00078 void FPFHNode::process_point_cloud(const sensor_msgs::PointCloud2::ConstPtr& input_cloud,
00079                                    feature_extractor_fpfh::FPFHHist &hist)
00080 {
00081     ROS_INFO("done3\n");
00082     float fpfh_leaf_size = .01;
00083     ROS_INFO("cloud has %d points", input_cloud->width * input_cloud->height);
00084 
00085     sensor_msgs::PointCloud2::Ptr cloud_filtered(new sensor_msgs::PointCloud2());
00086     pcl::VoxelGrid<sensor_msgs::PointCloud2> sor;
00087     sor.setInputCloud(input_cloud);
00088     sor.setLeafSize (fpfh_leaf_size, fpfh_leaf_size, fpfh_leaf_size);
00089     sor.filter(*cloud_filtered);
00090 
00091 
00092     float leaf_size = .005;
00093     sensor_msgs::PointCloud2::Ptr cloud_filtered2(new sensor_msgs::PointCloud2());
00094     pcl::VoxelGrid<sensor_msgs::PointCloud2> sor2;
00095     sor2.setInputCloud(input_cloud);
00096     sor2.setLeafSize (leaf_size, leaf_size, leaf_size);
00097     sor2.filter(*cloud_filtered2);
00098     PointCloud<PointXYZ> pcl_input_cloud_small;
00099     fromROSMsg(*cloud_filtered2, pcl_input_cloud_small);
00100 
00101     ROS_INFO("after coarse filtering: %d points", cloud_filtered->width * cloud_filtered->height);
00102     ROS_INFO("after fine filtering: %d points", cloud_filtered2->width * cloud_filtered2->height);
00103 
00104     if ((cloud_filtered->width * cloud_filtered->height) == 0)
00105     {
00106         return;
00107     }
00108     PointCloud<PointXYZ> cloud, pcl_input_cloud;
00109     fromROSMsg(*cloud_filtered, cloud);
00110     fromROSMsg(*input_cloud, pcl_input_cloud);
00111     std::vector<int> indices;
00112     indices.resize (cloud.points.size());
00113     for (size_t i = 0; i < indices.size (); ++i) { indices[i] = i; }
00114     ROS_INFO("here1");
00115 
00116     KdTreePtr tree;
00117     tree.reset(new KdTreeFLANN<PointXYZ> (false));
00118     tree->setInputCloud(cloud.makeShared());
00119 
00120     ROS_INFO("here2");
00121     PointCloud<Normal>::Ptr normals(new PointCloud<Normal>());
00122     boost::shared_ptr< vector<int> > indicesptr(new vector<int> (indices));
00123     NormalEstimation<PointXYZ, Normal> normal_estimator;
00124     ROS_INFO("here4");
00125 
00126     normal_estimator.setIndices(indicesptr);
00127     normal_estimator.setSearchMethod(tree);
00128     normal_estimator.setKSearch(10); // Use 10 nearest neighbors to estimate the normals
00129 
00130     // estimate
00131     ROS_DEBUG("fpfh_Calculating normals...\n");
00132     normal_estimator.setInputCloud(cloud.makeShared());
00133     normal_estimator.compute(*normals);
00134 
00135 
00136     FPFHEstimationOMP<PointXYZ, Normal, FPFHSignature33> fpfh(4);    // instantiate 4 threads
00137     // object
00138     PointCloud<FPFHSignature33>::Ptr fphists (new PointCloud<FPFHSignature33>());
00139     ROS_INFO("here5");
00140 
00141     // set parameters
00142     int d1, d2, d3;
00143     d1 = d2 = d3 = 11;
00144     fpfh.setNrSubdivisions(d1, d2, d3);
00145     fpfh.setSearchMethod(tree);
00146     fpfh.setIndices(indicesptr);
00147     fpfh.setKSearch(40);
00148 
00149     ROS_DEBUG("Calculating fpfh...\n");
00150     fpfh.setInputNormals(normals);
00151     fpfh.setInputCloud(cloud.makeShared());
00152     fpfh.compute(*fphists);
00153 
00154     ROS_INFO("here6");
00155     hist.header = input_cloud->header;
00156     hist.dim[0] = d1;
00157     hist.dim[1] = d2;
00158     hist.dim[2] = d3;
00159     unsigned int total_size = d1+d2+d3;
00160     hist.histograms.resize(total_size * cloud.points.size());
00161     hist.hpoints3d.resize(3*cloud.points.size());
00162     ROS_DEBUG("copying into message...\n");
00163     for (unsigned int i = 0; i < cloud.points.size(); i++)
00164     {
00165         for (unsigned int j = 0; j < total_size; j++)
00166         {
00167             hist.histograms[i*total_size + j] = fphists->points[i].histogram[j];
00168         }
00169 
00170         hist.hpoints3d[3*i]   = cloud.points[i].x;
00171         hist.hpoints3d[3*i+1] = cloud.points[i].y;
00172         hist.hpoints3d[3*i+2] = cloud.points[i].z;
00173     }
00174     hist.hist_npoints = cloud.points.size();
00175 
00176     ROS_INFO("here7");
00177     hist.origpoints.resize(3*pcl_input_cloud_small.points.size());
00178     for (unsigned int i = 0; i < pcl_input_cloud_small.points.size(); i++)
00179     {
00180         hist.origpoints[3*i]   = pcl_input_cloud_small.points[i].x;
00181         hist.origpoints[3*i+1] = pcl_input_cloud_small.points[i].y;
00182         hist.origpoints[3*i+2] = pcl_input_cloud_small.points[i].z;
00183     }
00184     hist.original_npoints = pcl_input_cloud_small.size();
00185     ROS_INFO("here8");
00186 }
00187 
00188 
00189 void FPFHNode::message_cb(const sensor_msgs::Image::ConstPtr& image, 
00190                         const sensor_msgs::PointCloud2::ConstPtr& input_cloud)
00191 {
00192 
00193     feature_extractor_fpfh::FPFHHist hist;
00194     process_point_cloud(input_cloud, hist);
00195 
00196     hist.image.header = image->header;
00197     hist.image.height = image->height;
00198     hist.image.width = image->width;
00199     hist.image.encoding = image->encoding;
00200     hist.image.is_bigendian = image->is_bigendian;
00201     hist.image.step = image->step;
00202     hist.image.data.resize(image->data.size());
00203     for (unsigned int i = 0; i < image->data.size(); i++)
00204     {
00205         hist.image.data[i] = image->data[i];
00206     }
00207 
00208     hist_publisher.publish(boost::make_shared<const feature_extractor_fpfh::FPFHHist>(hist));
00209     ROS_INFO("publish histogram done.\n");
00210 }
00211 
00212 int main(int argc, char** argv)
00213 {
00214   ros::init(argc, argv, "fpfh_calc");
00215   ros::NodeHandle nh;
00216   FPFHNode mc(nh);
00217 
00218   message_filters::Subscriber<sensor_msgs::Image> image_sub(nh, "image", 1);
00219   message_filters::Subscriber<sensor_msgs::PointCloud2> pc_sub(nh, "points2", 1);
00220   TimeSynchronizer<sensor_msgs::Image, sensor_msgs::PointCloud2> sync(image_sub, pc_sub, 10);
00221   sync.registerCallback(boost::bind(&FPFHNode::message_cb, &mc, _1, _2));
00222 
00223   ROS_INFO("started!");
00224   ros::spin();
00225   return 0;
00226 }
00227 
00228 
00229 
00230 
00231 
00232 
00233 
00234 
00235 
00236 
00237 
00238 
00239 
00240 
00241 
00242 
00243 
00244 
00245 
00246 
00247 
00248 
00249 
00250 // void FPFHNode::process_point_cloud(
00251 //         const boost::shared_ptr<const sensor_msgs::PointCloud2_<std::allocator<void> > >&, 
00252 //         const feature_extractor_fpfh::FPFHHist&)
00253 
00254 
00255 
00256     //if (hist_publisher.getNumSubscribers() <= 0)
00257     //{
00258     //    ROS_DEBUG("no subscribers. stopped processing.");
00259     //    return;
00260     //}
00261 
00262     //float fpfh_leaf_size = .02;
00263     //ROS_INFO("cloud has %d points", input_cloud->width * input_cloud->height);
00264 
00265     //sensor_msgs::PointCloud2::Ptr cloud_filtered(new sensor_msgs::PointCloud2());
00266     //pcl::VoxelGrid<sensor_msgs::PointCloud2> sor;
00267     //sor.setInputCloud(input_cloud);
00268     //sor.setLeafSize (fpfh_leaf_size, fpfh_leaf_size, fpfh_leaf_size);
00269     //sor.filter(*cloud_filtered);
00270 
00271 
00272     //float leaf_size = .005;
00273     //sensor_msgs::PointCloud2::Ptr cloud_filtered2(new sensor_msgs::PointCloud2());
00274     //pcl::VoxelGrid<sensor_msgs::PointCloud2> sor2;
00275     //sor2.setInputCloud(input_cloud);
00276     //sor2.setLeafSize (leaf_size, leaf_size, leaf_size);
00277     //sor2.filter(*cloud_filtered2);
00278     //PointCloud<PointXYZ> pcl_input_cloud_small;
00279     //fromROSMsg(*cloud_filtered2, pcl_input_cloud_small);
00280 
00281     //ROS_INFO("after filtering: %d points", cloud_filtered->width * cloud_filtered->height);
00282     //if ((cloud_filtered->width * cloud_filtered->height) == 0)
00283     //{
00284     //    return;
00285     //}
00286     //PointCloud<PointXYZ> cloud, pcl_input_cloud;
00287     //fromROSMsg(*cloud_filtered, cloud);
00288     //fromROSMsg(*input_cloud, pcl_input_cloud);
00289     //std::vector<int> indices;
00290     //indices.resize (cloud.points.size());
00291     //for (size_t i = 0; i < indices.size (); ++i) { indices[i] = i; }
00292 
00293     //KdTreePtr tree;
00294     //tree.reset(new KdTreeFLANN<PointXYZ> (false));
00295     //tree->setInputCloud(cloud.makeShared());
00296 
00297     //PointCloud<Normal>::Ptr normals(new PointCloud<Normal>());
00298     //boost::shared_ptr< vector<int> > indicesptr(new vector<int> (indices));
00299     //NormalEstimation<PointXYZ, Normal> normal_estimator;
00300 
00301     //normal_estimator.setIndices(indicesptr);
00302     //normal_estimator.setSearchMethod(tree);
00303     //normal_estimator.setKSearch(10); // Use 10 nearest neighbors to estimate the normals
00304 
00306     //ROS_DEBUG("fpfh_Calculating normals...\n");
00307     //normal_estimator.setInputCloud(cloud.makeShared());
00308     //normal_estimator.compute(*normals);
00309 
00310 
00311     //FPFHEstimationOMP<PointXYZ, Normal, FPFHSignature33> fpfh(4);    // instantiate 4 threads
00313     //PointCloud<FPFHSignature33>::Ptr fphists (new PointCloud<FPFHSignature33>());
00314 
00316     //int d1, d2, d3;
00317     //d1 = d2 = d3 = 11;
00318     //fpfh.setNrSubdivisions(d1, d2, d3);
00319     //fpfh.setSearchMethod(tree);
00320     //fpfh.setIndices(indicesptr);
00321     //fpfh.setKSearch(40);
00322 
00323     //ROS_DEBUG("Calculating fpfh...\n");
00324     //fpfh.setInputNormals(normals);
00325     //fpfh.setInputCloud(cloud.makeShared());
00326     //fpfh.compute(*fphists);
00327     //
00328     //
00329 
00330 
00331     //hist.header = input_cloud->header;
00332     //hist.dim[0] = d1;
00333     //hist.dim[1] = d2;
00334     //hist.dim[2] = d3;
00335     //unsigned int total_size = d1+d2+d3;
00336     //hist.histograms.resize(total_size * cloud.points.size());
00337     //hist.hpoints3d.resize(3*cloud.points.size());
00338     //ROS_DEBUG("copying into message...\n");
00339     //for (unsigned int i = 0; i < cloud.points.size(); i++)
00340     //{
00341     //    for (unsigned int j = 0; j < total_size; j++)
00342     //    {
00343     //        hist.histograms[i*total_size + j] = fphists->points[i].histogram[j];
00344     //    }
00345 
00346     //    hist.hpoints3d[3*i]   = cloud.points[i].x;
00347     //    hist.hpoints3d[3*i+1] = cloud.points[i].y;
00348     //    hist.hpoints3d[3*i+2] = cloud.points[i].z;
00349     //}
00350     //hist.hist_npoints = cloud.points.size();
00351 
00352     //hist.origpoints.resize(3*pcl_input_cloud_small.points.size());
00353     //for (unsigned int i = 0; i < pcl_input_cloud_small.points.size(); i++)
00354     //{
00355     //    hist.origpoints[3*i]   = pcl_input_cloud_small.points[i].x;
00356     //    hist.origpoints[3*i+1] = pcl_input_cloud_small.points[i].y;
00357     //    hist.origpoints[3*i+2] = pcl_input_cloud_small.points[i].z;
00358     //    //ROS_INFO("%.2f %.2f %.2f", pcl_input_cloud.points[i].x,
00359     //    //        pcl_input_cloud.points[i].y,
00360     //    //        pcl_input_cloud.points[i].z);
00361     //}
00362     //hist.original_npoints = pcl_input_cloud_small.size();


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