iros12_planar_removal.cpp
Go to the documentation of this file.
00001 #include "iros12_planar_removal.h"
00002 
00003 using namespace Eigen;
00004 
00005 // [Constructor]
00006 PlanarRemovalIROS2012::PlanarRemovalIROS2012() : it_(nh_) {
00007 
00008   //  cv::namedWindow(WINDOW);
00009 
00010   //string for port names
00011 
00012   // [init subscribers]
00013   this->pcl2_sub_ = this->nh_.subscribe<sensor_msgs::PointCloud2>("/planar_removal_iros2012/pcl2/input", 1, &PlanarRemovalIROS2012::pcl2_sub_callback, this);
00014 
00015   // [init publishers]
00016   this->image_pub_ = this->it_.advertise("/planar_removal_iros2012/image/dense", 1);
00017 //  jei_pub_name = "/jump_edge/image_depth_jef";
00018 //  this->jei_pub = this->it.advertise(jei_pub_name, 1);
00019 
00020   this->pcl2_pub_ = this->nh_.advertise<sensor_msgs::PointCloud2>("/planar_removal_iros2012/pcl2/output", 15);
00021   this->pcl2_planes_pub_ = this->nh_.advertise<sensor_msgs::PointCloud2>("/planar_removal_iros2012/pcl2/planes_output", 15);
00022   // Create a ROS publisher for the output point cloud
00023   this->coefficients_pub_ = this->nh_.advertise<pcl::ModelCoefficients> ("/planar_removal_iros2012/ModelCoefficients/output", 1);
00024 
00025   // [init services]
00026   dynamic_reconfigure::Server<iri_pcl_filters::IriPclFiltersParametersConfig>::CallbackType reconfig_callback_type = boost::bind(&PlanarRemovalIROS2012::reconfigureCallback, this, _1, _2);
00027 
00028   dyn_reconfig_srv.setCallback(reconfig_callback_type); 
00029 
00030   // [init clients]
00031   
00032   // [init action servers]
00033   
00034   // [init action clients]
00035 
00036   ROS_INFO("starting planar_removal_iros2012");
00037 
00038 }
00039 
00040 
00041 void PlanarRemovalIROS2012::reconfigureCallback(iri_pcl_filters::IriPclFiltersParametersConfig &config, uint32_t level)
00042 {
00043   ROS_INFO("Reconfigure request : distance th: %f lasting_cloud: %f #planes: %d ",
00044            config.distance_threshold, config.cloud_remaining_proportion_threshold, config.max_num_of_planes_removed);
00045 
00046   mutex.enter();
00047   distance_threshold_ = config.distance_threshold;
00048   cloud_remaining_proportion_threshold_ = config.cloud_remaining_proportion_threshold;
00049   max_num_of_planes_removed_ = config.max_num_of_planes_removed;
00050   mutex.exit();
00051   
00052 }
00053 
00054 PlanarRemovalIROS2012::~PlanarRemovalIROS2012(){
00055   //  cv::destroyWindow(WINDOW);
00056 }
00057 
00058 void PlanarRemovalIROS2012::removePlanesXYZ(pcl::PointCloud<pcl::PointXYZ> cloud,pcl::PointCloud<pcl::PointXYZRGB>& cloud_filtered,pcl::PointCloud<pcl::PointXYZRGB>& cloud_planes){ 
00059 
00060   pcl::PointCloud<pcl::PointXYZ> one_plane;
00061   pcl::copyPointCloud(cloud, cloud_filtered); //??
00062 
00063   pcl::ModelCoefficients::Ptr coefficients(new pcl::ModelCoefficients ());
00064   pcl::PointIndices::Ptr inliers(new pcl::PointIndices ());
00065   // Create the segmentation object
00066   pcl::SACSegmentation<pcl::PointXYZ> seg;
00067 
00068   double distance_threshold_aux;
00069   double cloud_remaining_proportion_threshold_aux;
00070 
00071   mutex.enter();
00072   distance_threshold_aux = distance_threshold_;
00073   cloud_remaining_proportion_threshold_aux = cloud_remaining_proportion_threshold_;
00074   mutex.exit();
00075 
00076   //init auxiliary point cloud
00077   cloud_planes.width = cloud.width;
00078   cloud_planes.height = cloud.height;
00079   cloud_planes.points.resize (one_plane.width * one_plane.height);
00080   cloud_planes.is_dense = cloud.is_dense;
00081   cloud_planes.header = cloud.header;
00082 
00083   // Optional
00084   seg.setOptimizeCoefficients (true);
00085     
00086   // Mandatory
00087   seg.setModelType (pcl::SACMODEL_PLANE);
00088   seg.setMethodType (pcl::SAC_RANSAC);
00089   seg.setDistanceThreshold (distance_threshold_aux);
00090     
00091   seg.setInputCloud (cloud.makeShared ());
00092   seg.segment (*inliers, *coefficients); 
00093   // Publish the model coefficients
00094   coefficients_pub_.publish (*coefficients);
00095 
00096   if (inliers->indices.size () == 0) {
00097     ROS_INFO("Could not estimate a planar model for the given dataset.");
00098     return;
00099   }
00100 
00101   // Create the filtering object
00102   pcl::ExtractIndices<pcl::PointXYZ> extract;
00103       
00104   // Extract the inliers
00105   extract.setInputCloud (cloud.makeShared());
00106   extract.setIndices (inliers);
00107   extract.setNegative (false);
00108   extract.filter (one_plane);
00109   //cloud_planes += one_plane;
00110   pcl::copyPointCloud(one_plane, cloud_planes); 
00111 
00112   ROS_INFO("points ok %d",inliers->indices.size());
00113   for(int j = 0; j < inliers->indices.size(); j++){
00114     uint8_t r = 255, g = 0, b = 0;    // Example: Red color
00115     uint32_t rgb = ((uint32_t)r << 16 | (uint32_t)g << 8 | (uint32_t)b);
00116     cloud_filtered[inliers->indices[j]].rgb = *reinterpret_cast<float*>(&rgb); 
00117   }
00118   //generate mask image
00119   cv::Mat mask(480,640,CV_8UC1);
00120   mask.setTo(255);
00121 
00122   int z=0;
00123   uint8_t r = 255, g = 0, b = 0;    // Example: Red color
00124   uint32_t rgb = ((uint32_t)r << 16 | (uint32_t)g << 8 | (uint32_t)b);
00125   
00126   for(int j=0;j<mask.rows;j++)
00127   {
00128     for(int i=0;i<mask.cols;i++)
00129     {
00130       if(cloud_filtered[z].rgb == *reinterpret_cast<float*>(&rgb) || isnan(cloud_filtered[z].z))
00131         mask.ptr(j)[i]=(uint)0;
00132       z++;
00133     }
00134   }
00135   cv::imwrite("/tmp/tamp.png",mask);
00136 }
00137 
00138 
00139 void PlanarRemovalIROS2012::removePlanesXYZRGB(pcl::PointCloud<pcl::PointXYZRGB> cloud,pcl::PointCloud<pcl::PointXYZRGB>& cloud_filtered,pcl::PointCloud<pcl::PointXYZRGB>& cloud_planes){ 
00140 
00141   pcl::PointCloud<pcl::PointXYZRGB> color_valid_points;
00142   pcl::PointCloud<pcl::PointXYZRGB> one_plane;
00143   pcl::PointCloud<pcl::PointXYZRGB> unstructured_cloud;
00144 
00145   pcl::copyPointCloud(cloud, cloud_filtered);
00146 
00147   pcl::ModelCoefficients::Ptr coefficients(new pcl::ModelCoefficients ());
00148   pcl::PointIndices::Ptr inliers(new pcl::PointIndices ());
00149   // Create the segmentation object
00150   pcl::SACSegmentation<pcl::PointXYZRGB> seg;
00151 
00152   double distance_threshold_aux;
00153   double cloud_remaining_proportion_threshold_aux;
00154 
00155   mutex.enter();
00156   distance_threshold_aux = distance_threshold_;
00157   cloud_remaining_proportion_threshold_aux = cloud_remaining_proportion_threshold_;
00158   mutex.exit();
00159 
00160   //init auxiliary point cloud
00161   cloud_planes.width = cloud.width;
00162   cloud_planes.height = cloud.height;
00163   cloud_planes.points.resize (one_plane.width * one_plane.height);
00164   cloud_planes.is_dense = cloud.is_dense;
00165   cloud_planes.header = cloud.header;
00166 
00167   if(0)
00168   {
00169     RGBValue color_accept;
00170     color_accept.Red=143.4074;
00171     color_accept.Green=134.5007;
00172     color_accept.Blue=134.8869;
00173     
00174     pcl::ComparisonBase<pcl::PointXYZRGB>::Ptr color_filter(new ConditionColor(color_accept, 28.3));
00175     pcl::ConditionAnd<pcl::PointXYZRGB>::Ptr andfilter(new pcl::ConditionAnd<pcl::PointXYZRGB>);
00176     andfilter->addComparison(color_filter);
00177     pcl::ConditionalRemoval<pcl::PointXYZRGB> condrem (andfilter);
00178     
00179     condrem.setInputCloud(cloud.makeShared());
00180     condrem.setKeepOrganized(true);
00181     pcl::PointIndicesPtr inliers3(new pcl::PointIndices);
00182     for (int i=0;i<cloud.width*cloud.height;i++)
00183       inliers3->indices.push_back(i);
00184     std::cout<<" s0120941093 "<< inliers3->indices.size();
00185     condrem.setIndices(inliers3);
00186     pcl::IndicesConstPtr inliers2;
00187     inliers2=condrem.getRemovedIndices();
00188     condrem.filter(color_valid_points);
00189 
00190     for(int i=0;i<inliers2->size();i++)
00191     {
00192       std::cout<<(*inliers2)[i]<<" ";
00193       inliers->indices.push_back((*inliers2)[i]);
00194     }
00195   }else{
00196   // Optional
00197     seg.setOptimizeCoefficients (true);
00198     
00199     // Mandatory
00200     seg.setModelType (pcl::SACMODEL_PLANE);
00201     seg.setMethodType (pcl::SAC_RANSAC);
00202     seg.setDistanceThreshold (distance_threshold_aux);
00203     
00204     seg.setInputCloud (cloud.makeShared ());
00205     seg.segment (*inliers, *coefficients); 
00206   // Publish the model coefficients
00207     coefficients_pub_.publish (*coefficients);
00208   }
00209 // Create the filtering object
00210   pcl::ExtractIndices<pcl::PointXYZRGB> extract;
00211 
00212     
00213   // seg.setOptimizeCoefficients (false);
00214   // seg.setInputCloud (cloud.makeShared());
00215   // seg.segment(*inliers, *coefficients);
00216   // std::cout<<"----"<<*coefficients<<std::endl;
00217   if (inliers->indices.size () == 0) {
00218     ROS_INFO("Could not estimate a planar model for the given dataset.");
00219     return;
00220   }
00221       
00222   // Extract the inliers
00223   extract.setInputCloud (cloud.makeShared());
00224   extract.setIndices (inliers);
00225   extract.setNegative (false);
00226   extract.filter (one_plane);
00227   
00228   cloud_planes += one_plane;
00229 
00230   ROS_INFO("points ok %d",inliers->indices.size());
00231   for(int j = 0; j < inliers->indices.size(); j++){
00232     uint8_t r = 255, g = 0, b = 0;    // Example: Red color
00233     uint32_t rgb = ((uint32_t)r << 16 | (uint32_t)g << 8 | (uint32_t)b);
00234     cloud_filtered[inliers->indices[j]].rgb = *reinterpret_cast<float*>(&rgb); 
00235   }
00236   //generate mask image
00237   cv::Mat mask(480,640,CV_8UC1);
00238   mask.setTo(255);
00239 
00240   int z=0;
00241   uint8_t r = 255, g = 0, b = 0;    // Example: Red color
00242   uint32_t rgb = ((uint32_t)r << 16 | (uint32_t)g << 8 | (uint32_t)b);
00243   
00244   for(int j=0;j<mask.rows;j++)
00245   {
00246     for(int i=0;i<mask.cols;i++)
00247     {
00248       if(cloud_filtered[z].rgb == *reinterpret_cast<float*>(&rgb) )
00249         mask.ptr(j)[i]=(uint)0;
00250       z++;
00251     }
00252   }
00253   cv::imwrite("/tmp/tamp.png",mask);
00254 }
00255 
00256 // [subscriber callbacks]
00257 void PlanarRemovalIROS2012::pcl2_sub_callback(const sensor_msgs::PointCloud2::ConstPtr& pcl2_msg_) { 
00258 
00259   // Create the filtering object: downsample the dataset using a leaf size of 1cm
00260 //  pcl::VoxelGrid<sensor_msgs::PointCloud2> sor;
00261 //  sor.setInputCloud (*pcl2_msg_);
00262 //  sor.setLeafSize (0.01f, 0.01f, 0.01f);
00263 //  sor.filter(*pcl2_msg_);
00264 
00265   cv::Mat rgb_image;
00266   pcl::PointCloud<pcl::PointXYZRGB> pcl_xyzrgb_aux;
00267   pcl::PointCloud<pcl::PointXYZ> pcl_xyz_aux;
00268 
00269   
00270   if(sensor_msgs::getPointCloud2FieldIndex(*pcl2_msg_,"rgb")!=-1)
00271   {
00272     pcl::fromROSMsg(*pcl2_msg_, pcl_xyzrgb_);
00273     removePlanesXYZRGB(pcl_xyzrgb_, pcl_xyzrgb_aux, pcl_planes_xyzrgb_);
00274   }
00275   else
00276   {
00277     pcl::fromROSMsg(*pcl2_msg_, pcl_xyz_);
00278     removePlanesXYZ(pcl_xyz_, pcl_xyzrgb_aux, pcl_planes_xyzrgb_);
00279   }
00280   
00281   //ROS_INFO("5 msg size %d %d data size %d size %d %d data size %d rgb_image %d %d",pcl2_msg_->height, pcl2_msg_->width, pcl2_msg_->data.size(),pcl_xyzrgb_aux.height, pcl_xyzrgb_aux.width, pcl_xyzrgb_aux.size(), rgb_image.rows, rgb_image.cols);
00282 
00283   rgb_image.create(pcl_xyzrgb_aux.height, pcl_xyzrgb_aux.width, CV_8UC3); 
00284 
00285   cv_image.header.stamp = ros::Time::now();
00286   cv_image.header.frame_id = "camera";
00287   cv_image.encoding = "bgr8";
00288 //  rgb_image = cv::imread("/home/pmonso/default.jpg");
00289   rgb_image = cv::Mat::zeros(rgb_image.size(), CV_8UC3);
00290   image_from_sparse_pcl2(pcl_xyzrgb_aux,rgb_image);
00291   cv_image.image = rgb_image;
00292   
00293   image_pub_.publish(cv_image.toImageMsg());
00294 
00295   pcl::toROSMsg(pcl_xyzrgb_, pcl2_filtered_msg_);
00296   // [publish Point Cloud 2 and Depth Image]
00297   pcl2_pub_.publish(pcl2_filtered_msg_);
00298 //  this->image_pub.publish(image_msg_);  //  this->jei_pub.publish(Image_msg_);
00299   pcl::toROSMsg(pcl_planes_xyzrgb_, pcl2_planes_msg_);
00300   pcl2_planes_pub_.publish(pcl2_planes_msg_);
00301 
00302 }
00303 
00304 void PlanarRemovalIROS2012::image_from_pcl2(cv::Mat& rgb_image){
00305 
00306 //  pcl::PointCloud<pcl::PointXYZRGB>::iterator pt_iter = this->pcl_xyzrgb_.begin();
00307 //
00308 //  rgb_image.create(this->pcl_xyzrgb_.height, this->pcl_xyzrgb_.width, CV_8UC3);
00309 //  for (int rr = 0; rr < (int)this->pcl_xyzrgb_.height; ++rr) {
00310 //    for (int cc = 0; cc < (int)this->pcl_xyzrgb_.width; ++cc, ++pt_iter) {
00311 //      pcl::PointXYZRGB &pt = *pt_iter;
00312 //      RGBValue color;
00313 //      color.float_value = pt.rgb;
00314 //      rgb_image.at<Vec3b>(rr,cc)[0] = color.Blue;
00315 //      rgb_image.at<Vec3b>(rr,cc)[1] = color.Green;
00316 //      rgb_image.at<Vec3b>(rr,cc)[2] = color.Red;
00317 //    }
00318 //  }
00319 }
00320 
00321 void PlanarRemovalIROS2012::image_from_sparse_pcl2(pcl::PointCloud<pcl::PointXYZRGB> cloud, cv::Mat& rgb_image){
00322 
00323   pcl::PointCloud<pcl::PointXYZRGB>::iterator pt_iter_xyzrgb = cloud.begin();
00324 //  rgb_image.create(this->pcl_xyz_.height, this->pcl_xyz_.width, CV_8UC3); 
00325   if(cloud.height != rgb_image.rows || cloud.width != rgb_image.cols){
00326     ROS_ERROR("Size mismatch between point cloud and rgb_image");
00327     ROS_INFO("xyzrgb size %d %d data size %d xyz %d %d data size %d rgb_image %d %d",pcl_xyzrgb_.height, pcl_xyzrgb_.width, pcl_xyzrgb_.size(),cloud.height, cloud.width, cloud.size(), rgb_image.rows, rgb_image.cols);
00328   } else {
00329     for (int rr = 0; rr < cloud.height; ++rr) {
00330       for (int cc = 0; cc < cloud.width; ++cc, ++pt_iter_xyzrgb) {
00331         pcl::PointXYZRGB &pt_xyzrgb = *pt_iter_xyzrgb;
00332         RGBValue color;
00333         color.float_value = pt_xyzrgb.rgb;
00334         if(isnan(pt_iter_xyzrgb->x) && isnan(pt_iter_xyzrgb->y) && isnan(pt_iter_xyzrgb->z)){
00335             rgb_image.at<cv::Vec3b>(rr,cc)[0] = 0;
00336             rgb_image.at<cv::Vec3b>(rr,cc)[1] = 0;
00337             rgb_image.at<cv::Vec3b>(rr,cc)[2] = 0; 
00338         }else{
00339             rgb_image.at<cv::Vec3b>(rr,cc)[0] = color.Blue;
00340             rgb_image.at<cv::Vec3b>(rr,cc)[1] = color.Green;
00341             rgb_image.at<cv::Vec3b>(rr,cc)[2] = color.Red;
00342         }
00343       }
00344     }
00345   }
00346 }
00347 
00348 int main(int argc, char** argv)
00349 {
00350   ros::init(argc, argv, "planar_removal_iros2012");
00351   PlanarRemovalIROS2012 planar_removal;
00352   ros::spin();
00353   return 0;
00354 }
00355 


iri_pcl_filters
Author(s): Sergi Foix
autogenerated on Fri Dec 6 2013 20:44:42