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