00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 
00025 
00026 
00027 
00028 
00029 
00030 
00031 
00032 
00033 
00034 
00035 
00036 #include <pcl/io/openni_grabber.h>
00037 #include <pcl/visualization/cloud_viewer.h>
00038 #include <pcl/visualization/pcl_visualizer.h>
00039 #include <pcl/io/io.h>
00040 #include <pcl/common/time.h>
00041 #include <pcl/features/integral_image_normal.h>
00042 #include <pcl/features/normal_3d.h>
00043 #include <pcl/ModelCoefficients.h>
00044 #include <pcl/segmentation/planar_region.h>
00045 #include <pcl/segmentation/organized_multi_plane_segmentation.h>
00046 #include <pcl/segmentation/organized_connected_component_segmentation.h>
00047 #include <pcl/filters/extract_indices.h>
00048 
00049 typedef pcl::PointXYZRGBA PointT;
00050 
00051 class OpenNIOrganizedMultiPlaneSegmentation
00052 {
00053   private:
00054     boost::shared_ptr<pcl::visualization::PCLVisualizer> viewer;
00055     pcl::PointCloud<PointT>::ConstPtr prev_cloud;
00056     boost::mutex cloud_mutex;
00057 
00058   public:
00059     OpenNIOrganizedMultiPlaneSegmentation ()
00060     {
00061 
00062     }
00063     ~OpenNIOrganizedMultiPlaneSegmentation ()
00064     {
00065     }
00066 
00067     boost::shared_ptr<pcl::visualization::PCLVisualizer>
00068     cloudViewer (pcl::PointCloud<PointT>::ConstPtr cloud)
00069     {
00070       boost::shared_ptr < pcl::visualization::PCLVisualizer> viewer (new pcl::visualization::PCLVisualizer ("Viewer"));
00071       viewer->setBackgroundColor (0, 0, 0);
00072       pcl::visualization::PointCloudColorHandlerCustom<PointT> single_color (cloud, 0, 255, 0);
00073       viewer->addPointCloud<PointT> (cloud, single_color, "cloud");
00074       viewer->setPointCloudRenderingProperties (pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 1, "cloud");
00075       viewer->setPointCloudRenderingProperties (pcl::visualization::PCL_VISUALIZER_OPACITY, 0.15, "cloud");
00076       viewer->addCoordinateSystem (1.0);
00077       viewer->initCameraParameters ();
00078       return (viewer);
00079     }
00080 
00081     void
00082     cloud_cb_ (const pcl::PointCloud<PointT>::ConstPtr& cloud)
00083     {
00084       if (!viewer->wasStopped ())
00085       {
00086         cloud_mutex.lock ();
00087         prev_cloud = cloud;
00088         cloud_mutex.unlock ();
00089       }
00090     }
00091 
00092     void
00093     removePreviousDataFromScreen (size_t prev_models_size)
00094     {
00095       char name[1024];
00096       for (size_t i = 0; i < prev_models_size; i++)
00097       {
00098         sprintf (name, "normal_%zu", i);
00099         viewer->removeShape (name);
00100 
00101         sprintf (name, "plane_%02zu", i);
00102         viewer->removePointCloud (name);
00103       }
00104     }
00105 
00106     void
00107     run ()
00108     {
00109       pcl::Grabber* interface = new pcl::OpenNIGrabber ();
00110 
00111       boost::function<void(const pcl::PointCloud<PointT>::ConstPtr&)> f = boost::bind (&OpenNIOrganizedMultiPlaneSegmentation::cloud_cb_, this, _1);
00112 
00113       
00114       pcl::PointCloud<PointT>::Ptr init_cloud_ptr (new pcl::PointCloud<PointT>);
00115       viewer = cloudViewer (init_cloud_ptr);
00116       boost::signals2::connection c = interface->registerCallback (f);
00117 
00118       interface->start ();
00119 
00120       unsigned char red [6] = {255,   0,   0, 255, 255,   0};
00121       unsigned char grn [6] = {  0, 255,   0, 255,   0, 255};
00122       unsigned char blu [6] = {  0,   0, 255,   0, 255, 255};
00123 
00124       pcl::IntegralImageNormalEstimation<PointT, pcl::Normal> ne;
00125       ne.setNormalEstimationMethod (ne.COVARIANCE_MATRIX);
00126       ne.setMaxDepthChangeFactor (0.03f);
00127       ne.setNormalSmoothingSize (20.0f);
00128 
00129       pcl::OrganizedMultiPlaneSegmentation<PointT, pcl::Normal, pcl::Label> mps;
00130       mps.setMinInliers (10000);
00131       mps.setAngularThreshold (0.017453 * 2.0); 
00132       mps.setDistanceThreshold (0.02); 
00133 
00134       std::vector<pcl::PlanarRegion<PointT>, Eigen::aligned_allocator<pcl::PlanarRegion<PointT> > > regions;
00135       pcl::PointCloud<PointT>::Ptr contour (new pcl::PointCloud<PointT>);
00136       size_t prev_models_size = 0;
00137       char name[1024];
00138 
00139       while (!viewer->wasStopped ())
00140       {
00141         viewer->spinOnce (100);
00142 
00143         if (prev_cloud && cloud_mutex.try_lock ())
00144         {
00145           regions.clear ();
00146           pcl::PointCloud<pcl::Normal>::Ptr normal_cloud (new pcl::PointCloud<pcl::Normal>);
00147           double normal_start = pcl::getTime ();
00148           ne.setInputCloud (prev_cloud);
00149           ne.compute (*normal_cloud);
00150           double normal_end = pcl::getTime ();
00151           std::cout << "Normal Estimation took " << double (normal_end - normal_start) << std::endl;
00152 
00153           double plane_extract_start = pcl::getTime ();
00154           mps.setInputNormals (normal_cloud);
00155           mps.setInputCloud (prev_cloud);
00156           mps.segmentAndRefine (regions);
00157           double plane_extract_end = pcl::getTime ();
00158           std::cout << "Plane extraction took " << double (plane_extract_end - plane_extract_start) << std::endl;
00159           std::cout << "Frame took " << double (plane_extract_end - normal_start) << std::endl;
00160 
00161           pcl::PointCloud<PointT>::Ptr cluster (new pcl::PointCloud<PointT>);
00162 
00163           if (!viewer->updatePointCloud<PointT> (prev_cloud, "cloud"))
00164             viewer->addPointCloud<PointT> (prev_cloud, "cloud");
00165 
00166           removePreviousDataFromScreen (prev_models_size);
00167           
00168           for (size_t i = 0; i < regions.size (); i++)
00169           {
00170             Eigen::Vector3f centroid = regions[i].getCentroid ();
00171             Eigen::Vector4f model = regions[i].getCoefficients ();
00172             pcl::PointXYZ pt1 = pcl::PointXYZ (centroid[0], centroid[1], centroid[2]);
00173             pcl::PointXYZ pt2 = pcl::PointXYZ (centroid[0] + (0.5f * model[0]),
00174                                                centroid[1] + (0.5f * model[1]),
00175                                                centroid[2] + (0.5f * model[2]));
00176             sprintf (name, "normal_%zu", i);
00177             viewer->addArrow (pt2, pt1, 1.0, 0, 0, false, name);
00178 
00179             contour->points = regions[i].getContour ();
00180             sprintf (name, "plane_%02zu", i);
00181             pcl::visualization::PointCloudColorHandlerCustom <PointT> color (contour, red[i], grn[i], blu[i]);
00182             viewer->addPointCloud (contour, color, name);
00183             viewer->setPointCloudRenderingProperties (pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 4, name);
00184           }
00185           prev_models_size = regions.size ();
00186           cloud_mutex.unlock ();
00187         }
00188       }
00189 
00190       interface->stop ();
00191     }
00192 };
00193 
00194 int
00195 main ()
00196 {
00197   OpenNIOrganizedMultiPlaneSegmentation multi_plane_app;
00198   multi_plane_app.run ();
00199   return 0;
00200 }