Go to the documentation of this file.00001 #include <iostream>
00002
00003
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
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
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
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
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
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
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 ();
00081 return true;
00082 }
00083
00084 void inputCallback(const sensor_msgs::PointCloud2::ConstPtr& msg)
00085 {
00086
00087
00088
00089
00090
00091
00092
00093 pcl::PointCloud<pcl::PointXYZRGB> cloud;
00094 pcl::fromROSMsg (*msg, cloud);
00095
00096
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;
00102 if (!std::isnan(cloud.points[idx].x))
00103 {
00104 cloud.points[idx].rgb = it->rgb;
00105
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
00114 sensor_msgs::PointCloud2 cloud_blob;
00115 pcl::toROSMsg (cloud, cloud_blob);
00116 pub_.publish (cloud_blob);
00117
00118
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
00139
00140
00141 return 0;
00142 }