Go to the documentation of this file.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/point_cloud.h>
00037 #include <pcl/point_types.h>
00038 #include <pcl/io/openni_grabber.h>
00039 #include <pcl/io/pcd_io.h>
00040 #include <pcl/io/openni_camera/openni_driver.h>
00041 #include <pcl/filters/voxel_grid.h>
00042 #include <pcl/surface/concave_hull.h>
00043 #include <pcl/console/parse.h>
00044 #include <pcl/common/time.h>
00045 #include <pcl/visualization/cloud_viewer.h>
00046
00047 using namespace pcl;
00048 using namespace pcl::visualization;
00049 using namespace std;
00050
00051 #define FPS_CALC(_WHAT_) \
00052 do \
00053 { \
00054 static unsigned count = 0;\
00055 static double last = pcl::getTime ();\
00056 if (++count == 100) \
00057 { \
00058 double now = pcl::getTime (); \
00059 std::cout << "Average framerate("<< _WHAT_ << "): " << double(count)/double(now - last) << " Hz" << std::endl; \
00060 count = 0; \
00061 last = now; \
00062 } \
00063 }while(false)
00064
00065 template <typename PointType>
00066 class OpenNI3DConcaveHull
00067 {
00068 public:
00069 typedef pcl::PointCloud<PointType> Cloud;
00070 typedef typename Cloud::Ptr CloudPtr;
00071 typedef typename Cloud::ConstPtr CloudConstPtr;
00072
00073 OpenNI3DConcaveHull (const std::string& device_id = "")
00074 : viewer ("PCL OpenNI 3D Concave Hull Viewer")
00075 , device_id_(device_id)
00076 {
00077 grid.setFilterFieldName ("z");
00078 grid.setFilterLimits (0.0, 1.0);
00079 grid.setLeafSize (0.01f, 0.01f, 0.01f);
00080 }
00081
00082 void
00083 cloud_cb (const CloudConstPtr& cloud)
00084 {
00085 boost::mutex::scoped_lock lock (mtx_);
00086 FPS_CALC ("computation");
00087
00088 cloud_pass_.reset (new Cloud);
00089
00090 grid.setInputCloud (cloud);
00091 grid.filter (*cloud_pass_);
00092
00093
00094 pcl::ConcaveHull<PointType> hr;
00095 hr.setAlpha (0.1);
00096 hr.setInputCloud (cloud_pass_);
00097 cloud_hull_.reset (new Cloud);
00098 hr.reconstruct (*cloud_hull_, vertices_);
00099
00100 cloud_ = cloud;
00101 new_cloud_ = true;
00102 }
00103
00104 void
00105 viz_cb (pcl::visualization::PCLVisualizer& viz)
00106 {
00107 if (!cloud_ || !new_cloud_)
00108 {
00109 boost::this_thread::sleep (boost::posix_time::milliseconds (1));
00110 return;
00111 }
00112
00113 {
00114 boost::mutex::scoped_lock lock (mtx_);
00115 FPS_CALC ("visualization");
00116 CloudPtr temp_cloud;
00117 temp_cloud.swap (cloud_pass_);
00118
00119 if (!viz.updatePointCloud (temp_cloud, "OpenNICloud"))
00120 {
00121 viz.addPointCloud (temp_cloud, "OpenNICloud");
00122 viz.resetCameraViewpoint ("OpenNICloud");
00123 }
00124
00125 if (new_cloud_ && cloud_hull_)
00126 {
00127 viz.removePointCloud ("hull");
00128 viz.addPolygonMesh<PointType> (cloud_hull_, vertices_, "hull");
00129 }
00130 new_cloud_ = false;
00131 }
00132 }
00133
00134 void
00135 run ()
00136 {
00137 pcl::Grabber* interface = new pcl::OpenNIGrabber (device_id_);
00138
00139 boost::function<void (const CloudConstPtr&)> f = boost::bind (&OpenNI3DConcaveHull::cloud_cb, this, _1);
00140 boost::signals2::connection c = interface->registerCallback (f);
00141
00142 viewer.runOnVisualizationThread (boost::bind(&OpenNI3DConcaveHull::viz_cb, this, _1), "viz_cb");
00143
00144 interface->start ();
00145
00146 while (!viewer.wasStopped ())
00147 {
00148 boost::this_thread::sleep(boost::posix_time::milliseconds(1));
00149 }
00150
00151 interface->stop ();
00152 }
00153
00154 pcl::VoxelGrid<PointType> grid;
00155 pcl::visualization::CloudViewer viewer;
00156
00157 std::string device_id_;
00158 boost::mutex mtx_;
00159
00160 CloudConstPtr cloud_;
00161 CloudPtr cloud_pass_, cloud_hull_;
00162 std::vector<pcl::Vertices> vertices_;
00163 bool new_cloud_;
00164 };
00165
00166 void
00167 usage (char ** argv)
00168 {
00169 std::cout << "usage: " << argv[0] << " <device_id> <options>\n\n";
00170
00171 openni_wrapper::OpenNIDriver& driver = openni_wrapper::OpenNIDriver::getInstance ();
00172 if (driver.getNumberDevices () > 0)
00173 {
00174 for (unsigned deviceIdx = 0; deviceIdx < driver.getNumberDevices (); ++deviceIdx)
00175 {
00176 cout << "Device: " << deviceIdx + 1 << ", vendor: " << driver.getVendorName (deviceIdx) << ", product: " << driver.getProductName (deviceIdx)
00177 << ", connected: " << driver.getBus (deviceIdx) << " @ " << driver.getAddress (deviceIdx) << ", serial number: \'" << driver.getSerialNumber (deviceIdx) << "\'" << endl;
00178 cout << "device_id may be #1, #2, ... for the first second etc device in the list or" << endl
00179 << " bus@address for the device connected to a specific usb-bus / address combination (works only in Linux) or" << endl
00180 << " <serial-number> (only in Linux and for devices which provide serial numbers)" << endl;
00181 }
00182 }
00183 else
00184 cout << "No devices connected." << endl;
00185 }
00186
00187 int
00188 main (int argc, char ** argv)
00189 {
00190 std::string arg;
00191 if (argc > 1)
00192 arg = std::string (argv[1]);
00193
00194 if (arg == "--help" || arg == "-h")
00195 {
00196 usage (argv);
00197 return 1;
00198 }
00199
00200 pcl::OpenNIGrabber grabber ("");
00201 if (grabber.providesCallback<pcl::OpenNIGrabber::sig_cb_openni_point_cloud_rgba> ())
00202 {
00203 PCL_INFO ("PointXYZRGBA mode enabled.\n");
00204 OpenNI3DConcaveHull<pcl::PointXYZRGBA> v ("");
00205 v.run ();
00206 }
00207 else
00208 {
00209 PCL_INFO ("PointXYZ mode enabled.\n");
00210 OpenNI3DConcaveHull<pcl::PointXYZ> v ("");
00211 v.run ();
00212 }
00213 return (0);
00214 }