pointcloud_filtering.cpp
Go to the documentation of this file.
00001 #include <ros/ros.h>
00002 
00003 #include <std_msgs/String.h>
00004 
00005 #include <pcl/point_types.h>
00006 #include <pcl_ros/point_cloud.h>
00007 #include <pcl/filters/voxel_grid.h>
00008 #include <pcl/filters/passthrough.h>
00009 #include <pcl/filters/extract_indices.h>
00010 #include <pcl/filters/statistical_outlier_removal.h>
00011 
00012 typedef pcl::PointXYZRGB      Point;
00013 typedef pcl::PointCloud<Point>PointCloud;
00014 
00015 class PointCloudFiltering {
00016 
00017   // ROS properties
00018   ros::NodeHandle nh_;
00019   ros::NodeHandle nh_private_;
00020   ros::Subscriber point_cloud_sub_;
00021 
00022   // Publisher to send out the filtered point cloud
00023   ros::Publisher point_cloud_filtered_;
00024 
00025   // Filter parameters
00026   double x_filter_min_;
00027   double x_filter_max_;
00028   double y_filter_min_;
00029   double y_filter_max_;
00030   double z_filter_min_;
00031   double z_filter_max_;
00032   double voxel_size_;
00033   int mean_k_;
00034   double std_dev_thresh_;
00035 
00036   bool apply_xyz_limits_;
00037   bool apply_voxel_grid_;
00038   bool apply_outlier_removal_;
00039 
00040 public:
00041 
00045   PointCloudFiltering() : nh_private_("~")
00046   {
00047     // Read the parameters from the parameter server (set defaults)
00048     nh_private_.param("apply_xyz_limits", apply_xyz_limits_, true);
00049     nh_private_.param("apply_voxel_grid", apply_voxel_grid_, true);
00050     nh_private_.param("apply_outlier_removal", apply_outlier_removal_, false);
00051     nh_private_.param("x_filter_min", x_filter_min_, -3.0);
00052     nh_private_.param("x_filter_max", x_filter_max_, 3.0);
00053     nh_private_.param("y_filter_min", y_filter_min_, -3.0);
00054     nh_private_.param("y_filter_max", y_filter_max_, 3.0);
00055     nh_private_.param("z_filter_min", z_filter_min_, 0.2);
00056     nh_private_.param("z_filter_max", z_filter_max_, 3.0);
00057     nh_private_.param("voxel_size", voxel_size_, 0.01);
00058     nh_private_.param("mean_k", mean_k_, 50);
00059     nh_private_.param("std_dev_thresh", std_dev_thresh_, 1.0);
00060 
00061     // Subscription to the point cloud result from stereo_image_proc
00062     point_cloud_sub_ = nh_.subscribe<PointCloud>(
00063       "input",
00064       1,
00065       &PointCloudFiltering::
00066       pointCloudCb,
00067       this);
00068 
00069     // Declare the point cloud filtered topic
00070     point_cloud_filtered_ = nh_private_.advertise<PointCloud>("output", 1);
00071   }
00072 
00076   void pointCloudCb(const PointCloud::ConstPtr& point_cloud)
00077   {
00078     PointCloud cloud = *point_cloud;
00079 
00080     // Filter
00081     PointCloud::Ptr cloud_downsampled = filter(cloud.makeShared());
00082 
00083     // Publish the filtered point cloud
00084     point_cloud_filtered_.publish(cloud_downsampled);
00085   }
00086 
00091   PointCloud::Ptr filter(PointCloud::Ptr cloud)
00092   {
00093     // NAN and limit filtering
00094     PointCloud::Ptr cloud_filtered_ptr(new PointCloud);
00095     pcl::PassThrough<Point> pass;
00096 
00097     if (apply_xyz_limits_)
00098     {
00099       // X-filtering
00100       pass.setFilterFieldName("x");
00101       pass.setFilterLimits(x_filter_min_, x_filter_max_);
00102       pass.setInputCloud(cloud);
00103       pass.filter(*cloud_filtered_ptr);
00104 
00105       // Y-filtering
00106       pass.setFilterFieldName("y");
00107       pass.setFilterLimits(y_filter_min_, y_filter_max_);
00108       pass.setInputCloud(cloud_filtered_ptr);
00109       pass.filter(*cloud_filtered_ptr);
00110 
00111       // Z-filtering
00112       pass.setFilterFieldName("z");
00113       pass.setFilterLimits(z_filter_min_, z_filter_max_);
00114       pass.setInputCloud(cloud_filtered_ptr);
00115       pass.filter(*cloud_filtered_ptr);
00116     }
00117     else
00118     {
00119       cloud_filtered_ptr = cloud;
00120     }
00121 
00122     // Downsampling using voxel grid
00123     
00124     PointCloud::Ptr cloud_downsampled_ptr(new PointCloud);
00125 
00126     if (apply_voxel_grid_)
00127     {
00128       pcl::VoxelGrid<Point> grid;
00129       grid.setLeafSize(voxel_size_, voxel_size_, voxel_size_);
00130       grid.setDownsampleAllData(true);
00131       grid.setInputCloud(cloud_filtered_ptr);
00132       grid.filter(*cloud_downsampled_ptr);
00133     }
00134     else
00135     {
00136       cloud_downsampled_ptr = cloud_filtered_ptr;
00137     }
00138     
00139     // Statistical outlier removal
00140     PointCloud::Ptr cloud_outlier_ptr(new PointCloud);
00141 
00142     if (apply_outlier_removal_)
00143     {
00144       pcl::StatisticalOutlierRemoval<Point> sor;
00145       sor.setInputCloud(cloud_downsampled_ptr);
00146       sor.setMeanK(mean_k_);
00147       sor.setStddevMulThresh(std_dev_thresh_);
00148       sor.filter(*cloud_outlier_ptr);
00149     }
00150     else
00151     {
00152       cloud_outlier_ptr = cloud_downsampled_ptr;
00153     }    
00154 
00155     return cloud_outlier_ptr;
00156   }
00157 };
00158 
00162 int main(int argc, char **argv)
00163 {
00164   ros::init(argc, argv, "point_cloud_filtering");
00165   PointCloudFiltering node;
00166   ros::spin();
00167   return 0;
00168 }
00169 


pointcloud_tools
Author(s): Pep Lluis Negre
autogenerated on Fri Aug 28 2015 13:15:25