object_filter.cpp
Go to the documentation of this file.
00001 #include <iostream>
00002 //#include <iterator>
00003 //#include <vector>
00004 #include <boost/make_shared.hpp>
00005 
00006 #include <ros/ros.h>
00007 #include <sensor_msgs/PointCloud2.h>
00008 #include <pcl/point_types.h>
00009 #include <pcl/io/pcd_io.h>  
00010 
00011 #include "kinect_cleanup/FilterObject.h"
00012 
00013 // TODO get point index+position+color directly?
00014 struct filter
00015 {
00016   int row[2], col[2];
00017   double rgb;
00018   double plane[4];
00019 };
00020 
00021 class ObjectFilter
00022 {
00023   protected:
00024 
00025     ros::NodeHandle nh_;
00026     ros::Subscriber sub_;
00027     ros::Publisher pub_;
00028     //pcl_ros::Publisher<pcl::PointXYZRGB> pub_;
00029     ros::ServiceServer service_;
00030 
00031     std::vector<filter> to_filter;
00032     double std_noise_;
00033 
00034   public:
00035 
00036     ObjectFilter (ros::NodeHandle &nh, double std_noise) : nh_ (nh), std_noise_ (std_noise)
00037     {
00038       sub_ = nh_.subscribe("input", 1, &ObjectFilter::inputCallback, this);
00039       ROS_INFO ("[ObjectFilter] Subscribed to: %s", sub_.getTopic ().c_str ());
00040       pub_ = nh_.advertise<sensor_msgs::PointCloud2>("output", 0 );
00041       //pub_ = pcl_ros::Publisher<pcl::PointXYZRGB> (nh_, "output", 1);
00042       ROS_INFO ("[ObjectFilter] Publishing on: %s", pub_.getTopic ().c_str ());
00043       service_ = nh_.advertiseService("/filter_object", &ObjectFilter::add2filter, this);
00044       ROS_INFO ("[ObjectFilter] Advertising service on: %s", service_.getService ().c_str ());
00045 
00046       // -cam "0.005132195795,5.132195795/-0.01565100066,0.03999799863,0.9129999876/-0.00633858571,-0.04486026046,0.1577823364/0.01037906958,-0.9936787337,0.1117803609"
00047       // -cam "0.00618764,6.18764/0.0325911,-0.0688337,2.01496/0.114809,0.430051,-0.539011/0.0230098,-0.98133,-0.190949/1358,384/8,73"
00048       //int indices[2];
00049       //filter f;
00050       //f.plane[0] = 0;
00051       //f.plane[1] = 0;
00052       //f.plane[2] = 1;
00053       //f.plane[3] = 1;
00054       // tight: 125080 - 184010
00055       // loose: 119310 - 199400
00056       //indices[0] = 119310;
00057       //indices[1] = 199400;
00058       //for (int i=0; i<2; i++)
00059       //{
00060       //  f.row[i] = indices[i] / 640;
00061       //  f.col[i] = indices[i] - f.row[i] * 640;
00062       //}
00063       //f.rgb = 0.0;
00064       //to_filter.push_back (f);
00065     }
00066 
00067     bool add2filter (kinect_cleanup::FilterObject::Request  &req,
00068                      kinect_cleanup::FilterObject::Response &res)
00069     {
00070       filter f;
00071       f.rgb = req.rgb;
00072       f.row[0] = req.min_row;
00073       f.row[1] = req.max_row;
00074       f.col[0] = req.min_col;
00075       f.col[1] = req.max_col;
00076       // TODO simple saving would be OK too?
00077       for (int i=0; i<4; i++)
00078         f.plane[i] = req.plane_normal[i];
00079       to_filter.push_back (f);
00080       res.error = "filtering " + to_filter.size (); // TODO add out of bounds checks and reflect in result
00081       return true;
00082     }
00083 
00084     void inputCallback(const sensor_msgs::PointCloud2::ConstPtr& msg)
00085     {
00086       //sensor_msgs::PointCloud2 cloud_blob;
00087       //pcl::io::loadPCDFile ("1295257088.795222210.pcd", cloud_blob);
00088       //pcl::PointCloud<pcl::PointXYZRGB> cloud;
00089       //pcl::fromROSMsg (cloud_blob, cloud);
00090       // ... (boost::make_shared<pcl::PointCloud<pcl::PointXYZ> > (cloud));
00091 
00092       // Convert from message to point cloud
00093       pcl::PointCloud<pcl::PointXYZRGB> cloud;
00094       pcl::fromROSMsg (*msg, cloud);
00095 
00096       // Update the appropriate points
00097       for (std::vector<filter>::const_iterator it = to_filter.begin (); it != to_filter.end (); it++)
00098         for (int r = it->row[0]; r <= it->row[1]; r++)
00099           for (int c = it->col[0]; c <= it->col[1]; c++)
00100           {
00101             int idx = 640*r+c; // TODO iterator?
00102             if (!std::isnan(cloud.points[idx].x))
00103             {
00104               cloud.points[idx].rgb = it->rgb;
00105               // TODO map to eigen?
00106               double extend_backwards = -it->plane[3]/(cloud.points[idx].x * it->plane[0] + cloud.points[idx].y * it->plane[1] + cloud.points[idx].z * it->plane[2]);
00107               cloud.points[idx].x *= extend_backwards;
00108               cloud.points[idx].y *= extend_backwards;
00109               cloud.points[idx].z *= extend_backwards;
00110             }
00111           }
00112 
00113       // Convert to message and publish
00114       sensor_msgs::PointCloud2 cloud_blob;
00115       pcl::toROSMsg (cloud, cloud_blob);
00116       pub_.publish (cloud_blob);
00117 
00118       //pcl::io::savePCDFile ("./1295257088.795222210-fill.pcd", cloud);
00119     }
00120 
00121 };
00122 
00123 int main(int argc, char **argv)
00124 {
00125   double std_noise = 0.0;
00126   if (argc > 2)
00127   {
00128     std::stringstream ss (argv[1]);
00129     ss >> std_noise;
00130     std::cerr << "Using a noise level with a STD of " << std_noise << std::endl;
00131   }
00132 
00133   ros::init(argc, argv, "object_filter");
00134   ros::NodeHandle nh ("~");
00135   ObjectFilter f (nh, std_noise);
00136   ros::spin();
00137   
00138   //sensor_msgs::PointCloud2 msg;
00139   //f.inputCallback (boost::make_shared<sensor_msgs::PointCloud2> (msg));
00140   
00141   return 0;
00142 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Properties Friends


kinect_cleanup
Author(s): Zoltan-Csaba Marton, Dejan Pangercic
autogenerated on Sun Oct 6 2013 11:57:20