openni_organized_compression.cpp
Go to the documentation of this file.
00001 /*
00002  * Software License Agreement (BSD License)
00003  *
00004  *  Copyright (c) 2011, Willow Garage, Inc.
00005  *  All rights reserved.
00006  *
00007  *  Redistribution and use in source and binary forms, with or without
00008  *  modification, are permitted provided that the following conditions
00009  *  are met:
00010  *
00011  *   * Redistributions of source code must retain the above copyright
00012  *     notice, this list of conditions and the following disclaimer.
00013  *   * Redistributions in binary form must reproduce the above
00014  *     copyright notice, this list of conditions and the following
00015  *     disclaimer in the documentation and/or other materials provided
00016  *     with the distribution.
00017  *   * Neither the name of Willow Garage, Inc. nor the names of its
00018  *     contributors may be used to endorse or promote products derived
00019  *     from this software without specific prior written permission.
00020  *
00021  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00022  *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00023  *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
00024  *  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
00025  *  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
00026  *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
00027  *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00028  *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00029  *  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00030  *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
00031  *  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00032  *  POSSIBILITY OF SUCH DAMAGE.
00033  *
00034  * Author: Julius Kammerl (julius@kammerl.de)
00035  */
00036 
00037 
00038 #include <pcl/point_cloud.h>
00039 #include <pcl/point_types.h>
00040 #include <pcl/io/openni_grabber.h>
00041 #include <pcl/visualization/cloud_viewer.h>
00042 #include <pcl/console/parse.h>
00043 #include <pcl/common/time.h>
00044 
00045 #include <pcl/compression/organized_pointcloud_compression.h>
00046 
00047 #include <iostream>
00048 #include <vector>
00049 #include <stdio.h>
00050 #include <sstream>
00051 #include <stdlib.h>
00052 #include <iostream>
00053 #include <string>
00054 
00055 #include <boost/asio.hpp>
00056 
00057 using boost::asio::ip::tcp;
00058 
00059 using namespace pcl;
00060 using namespace pcl::io;
00061 
00062 using namespace std;
00063 
00064 char usage[] = "\n"
00065   "  PCL organized point cloud stream compression\n"
00066   "\n"
00067   "  usage: ./pcl_openni_organized_compression [mode] [parameters]\n"
00068   "\n"
00069   "  I/O: \n"
00070   "      -f file  : file name \n"
00071   "\n"
00072   "  file compression mode:\n"
00073   "      -x: encode point cloud stream to file\n"
00074   "      -d: decode from file and display point cloud stream\n"
00075   "\n"
00076   "  network streaming mode:\n"
00077   "      -s       : start server on localhost\n"
00078   "      -c host  : connect to server and display decoded cloud stream\n"
00079   "\n"
00080   "  optional compression parameters:\n"
00081   "      -a       : enable color coding\n"
00082   "      -t       : output statistics\n"
00083   "      -e       : show input cloud during encoding\n"
00084   "      -r       : raw encoding of disparity maps\n"
00085   "      -g       : gray scale conversion\n"
00086 
00087   "\n"
00088   "  example:\n"
00089   "      ./pcl_openni_organized_compression -x -t -f pc_compressed.pcc \n"
00090   "\n";
00091 
00092 #define FPS_CALC(_WHAT_) \
00093 do \
00094 { \
00095     static unsigned count = 0;\
00096     static double last = pcl::getTime ();\
00097     double now = pcl::getTime (); \
00098     ++count; \
00099     if (now - last >= 1.0) \
00100     { \
00101       std::cout << "Average framerate("<< _WHAT_ << "): " << double(count)/double(now - last) << " Hz" <<  std::endl; \
00102       count = 0; \
00103       last = now; \
00104     } \
00105 }while(false)
00106 
00107 void
00108 print_usage (std::string msg)
00109 {
00110   std::cerr << msg << std::endl;
00111   std::cout << usage << std::endl;
00112 }
00113 
00114 class SimpleOpenNIViewer
00115 {
00116   public:
00117     SimpleOpenNIViewer (ostream& outputFile_arg,
00118                         OrganizedPointCloudCompression<PointXYZRGBA>* octreeEncoder_arg,
00119                         bool doColorEncoding_arg,
00120                         bool bShowStatistics_arg,
00121                         bool bRawImageEncoding_arg,
00122                         bool bGrayScaleConversion_arg,
00123                         int pngLevel_arg = -1) :
00124     viewer ("Input Point Cloud - PCL Compression Viewer"),
00125     outputFile_ (outputFile_arg),
00126     organizedEncoder_ (octreeEncoder_arg),
00127     doColorEncoding_ (doColorEncoding_arg),
00128     bShowStatistics_ (bShowStatistics_arg),
00129     bRawImageEncoding_ (bRawImageEncoding_arg),
00130     bGrayScaleConversion_(bGrayScaleConversion_arg),
00131     pngLevel_ (pngLevel_arg)
00132     {
00133     }
00134 
00135     void cloud_cb_ (const pcl::PointCloud<pcl::PointXYZRGBA>::ConstPtr &cloud)
00136     {
00137       if (!viewer.wasStopped ())
00138       {
00139         organizedEncoder_->encodePointCloud (cloud, outputFile_, doColorEncoding_,bGrayScaleConversion_,bShowStatistics_, pngLevel_);
00140 
00141         viewer.showCloud (cloud);
00142       }
00143     }
00144 
00145 
00146 
00147     void run ()
00148     {
00149 
00150       if (!bRawImageEncoding_)
00151       {
00152         // create a new grabber for OpenNI devices
00153         pcl::Grabber* interface = new pcl::OpenNIGrabber();
00154 
00155         // make callback function from member function
00156         boost::function<void (const pcl::PointCloud<pcl::PointXYZRGBA>::ConstPtr&)> f =
00157           boost::bind (&SimpleOpenNIViewer::cloud_cb_, this, _1);
00158 
00159         // connect callback function for desired signal. In this case its a point cloud with color values
00160         boost::signals2::connection c = interface->registerCallback (f);
00161 
00162         // start receiving point clouds
00163         interface->start ();
00164 
00165 
00166         while (!outputFile_.fail())
00167         {
00168           boost::this_thread::sleep(boost::posix_time::seconds(1));
00169         }
00170 
00171         interface->stop ();
00172       }
00173 
00174     }
00175 
00176     pcl::visualization::CloudViewer viewer;
00177     ostream& outputFile_;
00178     OrganizedPointCloudCompression<PointXYZRGBA>* organizedEncoder_;
00179     bool doColorEncoding_;
00180     bool bShowStatistics_;
00181     bool bRawImageEncoding_;
00182     bool bGrayScaleConversion_;
00183     int pngLevel_;
00184 };
00185 
00186 struct EventHelper
00187 {
00188   EventHelper (ostream& outputFile_arg,
00189                OrganizedPointCloudCompression<PointXYZRGBA>* octreeEncoder_arg,
00190                bool doColorEncoding_arg,
00191                bool bShowStatistics_arg,
00192                bool bRawImageEncoding_arg,
00193                bool bGrayScaleConversion_arg,
00194                int pngLevel_arg = -1) :
00195   outputFile_ (outputFile_arg),
00196   organizedEncoder_ (octreeEncoder_arg),
00197   doColorEncoding_ (doColorEncoding_arg),
00198   bShowStatistics_ (bShowStatistics_arg),
00199   bRawImageEncoding_ (bRawImageEncoding_arg),
00200   bGrayScaleConversion_(bGrayScaleConversion_arg) ,
00201   pngLevel_ (pngLevel_arg)
00202   {
00203   }
00204 
00205   void
00206   cloud_cb_ (const pcl::PointCloud<pcl::PointXYZRGBA>::ConstPtr &cloud)
00207   {
00208     if (!outputFile_.fail ())
00209     {
00210       organizedEncoder_->encodePointCloud (cloud, outputFile_, doColorEncoding_, bGrayScaleConversion_, bShowStatistics_, pngLevel_);
00211     }
00212   }
00213 
00214   void
00215   image_callback (const boost::shared_ptr<openni_wrapper::Image> &image,
00216                   const boost::shared_ptr<openni_wrapper::DepthImage> &depth_image, float)
00217   {
00218 
00219     vector<uint16_t> disparity_data;
00220     vector<uint8_t> rgb_data;
00221 
00222     uint32_t width=depth_image->getWidth ();
00223     uint32_t height=depth_image->getHeight ();
00224 
00225     disparity_data.resize(width*height);
00226     depth_image->fillDepthImageRaw (width, height, &disparity_data[0], static_cast<unsigned int> (width * sizeof (uint16_t)));
00227 
00228     if (image->getEncoding() != openni_wrapper::Image::RGB)
00229     {
00230       rgb_data.resize(width*height*3);
00231       image->fillRGB(width, height, &rgb_data[0], static_cast<unsigned int> (width * sizeof (uint8_t) * 3));
00232     }
00233 
00234     organizedEncoder_->encodeRawDisparityMapWithColorImage (disparity_data, rgb_data, width, height, outputFile_, doColorEncoding_, bGrayScaleConversion_, bShowStatistics_, pngLevel_);
00235 
00236   }
00237 
00238   void
00239   run ()
00240   {
00241     if (!bRawImageEncoding_)
00242     {
00243       // create a new grabber for OpenNI devices
00244       pcl::Grabber* interface = new pcl::OpenNIGrabber ();
00245 
00246       // make callback function from member function
00247       boost::function<void
00248       (const pcl::PointCloud<pcl::PointXYZRGBA>::ConstPtr&)> f = boost::bind (&EventHelper::cloud_cb_, this, _1);
00249 
00250       // connect callback function for desired signal. In this case its a point cloud with color values
00251       boost::signals2::connection c = interface->registerCallback (f);
00252 
00253       // start receiving point clouds
00254       interface->start ();
00255 
00256       while (!outputFile_.fail ())
00257       {
00258         boost::this_thread::sleep(boost::posix_time::seconds(1));
00259       }
00260 
00261       interface->stop ();
00262     } else
00263     {
00264       pcl::OpenNIGrabber::Mode image_mode = pcl::OpenNIGrabber::OpenNI_Default_Mode;
00265       int depthformat = openni_wrapper::OpenNIDevice::OpenNI_shift_values;
00266 
00267       pcl::OpenNIGrabber grabber ("", pcl::OpenNIGrabber::OpenNI_Default_Mode, image_mode);
00268 
00269       // Set the depth output format
00270       grabber.getDevice ()->setDepthOutputFormat (static_cast<openni_wrapper::OpenNIDevice::DepthMode> (depthformat));
00271 
00272       boost::function<void (const boost::shared_ptr<openni_wrapper::Image>&, const boost::shared_ptr<openni_wrapper::DepthImage>&, float) > image_cb = boost::bind (&EventHelper::image_callback, this, _1, _2, _3);
00273       boost::signals2::connection image_connection = grabber.registerCallback (image_cb);
00274 
00275       grabber.start ();
00276       while (!outputFile_.fail())
00277       {
00278         boost::this_thread::sleep(boost::posix_time::seconds(1));
00279       }
00280       grabber.stop ();
00281 
00282     }
00283   }
00284 
00285   ostream& outputFile_;
00286   OrganizedPointCloudCompression<PointXYZRGBA>* organizedEncoder_;
00287   bool doColorEncoding_;
00288   bool bShowStatistics_;
00289   bool bRawImageEncoding_;
00290   bool bGrayScaleConversion_;
00291   int pngLevel_;
00292 };
00293 
00294 int
00295 main (int argc, char **argv)
00296 {
00297   OrganizedPointCloudCompression<PointXYZRGBA>* organizedCoder;
00298 
00299   bool showStatistics;
00300   bool doColorEncoding;
00301   bool bShowInputCloud;
00302   bool bRawImageEncoding;
00303   bool bGrayScaleConversion;
00304 
00305   std::string fileName = "pc_compressed.pcc";
00306   std::string hostName = "localhost";
00307 
00308   bool bServerFileMode;
00309   bool bEnDecode;
00310   bool validArguments;
00311 
00312   validArguments = false;
00313   bServerFileMode = false;
00314   bEnDecode = false;
00315 
00316   showStatistics = false;
00317   doColorEncoding = false;
00318   bShowInputCloud = false;
00319   bRawImageEncoding = false;
00320   bGrayScaleConversion = false;
00321 
00322   if (pcl::console::find_argument (argc, argv, "-e")>0) 
00323     bShowInputCloud = true;
00324 
00325   if (pcl::console::find_argument (argc, argv, "-r")>0)
00326     bRawImageEncoding = true;
00327 
00328   if (pcl::console::find_argument (argc, argv, "-g")>0)
00329     bGrayScaleConversion = true;
00330 
00331   if (pcl::console::find_argument (argc, argv, "-s")>0) 
00332   {
00333     bEnDecode = true;
00334     bServerFileMode = true;
00335     validArguments = true;
00336   }
00337 
00338   if (pcl::console::parse_argument (argc, argv, "-c", hostName)>0) 
00339   {
00340     bEnDecode = false;
00341     bServerFileMode = true;
00342     validArguments = true;
00343   }
00344 
00345   if (pcl::console::find_argument (argc, argv, "-a")>0)
00346   {
00347     doColorEncoding = true;
00348   }
00349 
00350   if (pcl::console::find_argument (argc, argv, "-x")>0) 
00351   {
00352     bEnDecode = true;
00353     bServerFileMode = false;
00354     validArguments = true;
00355   }
00356 
00357   if (pcl::console::find_argument (argc, argv, "-d")>0) 
00358   {
00359     bEnDecode = false;
00360     bServerFileMode = false;
00361     validArguments = true;
00362   }
00363 
00364   if (pcl::console::find_argument (argc, argv, "-t")>0) 
00365     showStatistics = true;
00366 
00367   pcl::console::parse_argument (argc, argv, "-f", fileName);
00368 
00369 
00370   if (pcl::console::find_argument (argc, argv, "-?")>0) 
00371   {
00372     print_usage ("");
00373     return 1;
00374   }
00375 
00376   if (!validArguments)
00377   {
00378     print_usage ("Please specify compression mode..\n");
00379     return -1;
00380   }
00381 
00382   organizedCoder = new OrganizedPointCloudCompression<PointXYZRGBA> ();
00383 
00384 
00385   if (!bServerFileMode) 
00386   {
00387     if (bEnDecode) 
00388     {
00389       // ENCODING
00390       ofstream compressedPCFile;
00391       compressedPCFile.open (fileName.c_str(), ios::out | ios::trunc | ios::binary);
00392 
00393       if (!bShowInputCloud) 
00394       {
00395         EventHelper v (compressedPCFile, organizedCoder, doColorEncoding, showStatistics, bRawImageEncoding, bGrayScaleConversion);
00396         v.run ();
00397       } 
00398       else
00399       {
00400         SimpleOpenNIViewer v (compressedPCFile, organizedCoder, doColorEncoding, showStatistics, bRawImageEncoding, bGrayScaleConversion);
00401         v.run ();
00402       }
00403 
00404     } else
00405     {
00406       // DECODING
00407       ifstream compressedPCFile;
00408       compressedPCFile.open (fileName.c_str(), ios::in | ios::binary);
00409       compressedPCFile.seekg (0);
00410       compressedPCFile.unsetf (ios_base::skipws);
00411 
00412       pcl::visualization::CloudViewer viewer ("PCL Compression Viewer");
00413 
00414       while (!compressedPCFile.eof())
00415       {
00416         PointCloud<PointXYZRGBA>::Ptr cloudOut (new PointCloud<PointXYZRGBA> ());
00417         organizedCoder->decodePointCloud ( compressedPCFile, cloudOut );
00418         viewer.showCloud (cloudOut);
00419       }
00420     }
00421   } else
00422   {
00423     if (bEnDecode)
00424     {
00425       // ENCODING
00426       try
00427       {
00428         boost::asio::io_service io_service;
00429         tcp::endpoint endpoint (tcp::v4 (), 6666);
00430         tcp::acceptor acceptor (io_service, endpoint);
00431 
00432         tcp::iostream socketStream;
00433 
00434         std::cout << "Waiting for connection.." << std::endl;
00435 
00436         acceptor.accept (*socketStream.rdbuf ());
00437 
00438         std::cout << "Connected!" << std::endl;
00439 
00440         if (!bShowInputCloud) 
00441         {
00442           EventHelper v (socketStream, organizedCoder, doColorEncoding, showStatistics, bRawImageEncoding, bGrayScaleConversion);
00443           v.run ();
00444         } 
00445         else
00446         {
00447           SimpleOpenNIViewer v (socketStream, organizedCoder, doColorEncoding, showStatistics, bRawImageEncoding, bGrayScaleConversion);
00448           v.run ();
00449         }
00450 
00451         std::cout << "Disconnected!" << std::endl;
00452 
00453         boost::this_thread::sleep(boost::posix_time::seconds(3));
00454 
00455       }
00456       catch (std::exception& e)
00457       {
00458         std::cerr << e.what () << std::endl;
00459       }
00460     }
00461     else
00462     {
00463       // DECODING
00464       std::cout << "Connecting to: " << hostName << ".." << std::endl;
00465 
00466       try
00467       {
00468         tcp::iostream socketStream (hostName.c_str (), "6666");
00469 
00470         std::cout << "Connected!" << std::endl;
00471 
00472         pcl::visualization::CloudViewer viewer ("Decoded Point Cloud - PCL Compression Viewer");
00473 
00474         while (!socketStream.fail()) 
00475         {
00476           FPS_CALC ("drawing");
00477           PointCloud<PointXYZRGBA>::Ptr cloudOut (new PointCloud<PointXYZRGBA> ());
00478           organizedCoder->decodePointCloud (socketStream, cloudOut);
00479           viewer.showCloud (cloudOut);
00480         }
00481 
00482       }
00483       catch (std::exception& e)
00484       {
00485         std::cout << "Exception: " << e.what () << std::endl;
00486       }
00487     }
00488   }
00489 
00490   delete (organizedCoder);
00491   return (0);
00492 }
00493 


pcl
Author(s): Open Perception
autogenerated on Wed Aug 26 2015 15:26:45