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 }