openni_shift_to_depth_conversion.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 <iostream>
00046 #include <vector>
00047 #include <stdio.h>
00048 #include <sstream>
00049 #include <stdlib.h>
00050 #include <iostream>
00051 #include <string>
00052 
00053 #include <boost/asio.hpp>
00054 
00055 using boost::asio::ip::tcp;
00056 
00057 using namespace pcl;
00058 using namespace pcl::io;
00059 
00060 using namespace std;
00061 
00062 
00063 class SimpleOpenNIViewer
00064 {
00065   public:
00066     SimpleOpenNIViewer () :
00067       viewer_ ("Input Point Cloud - Shift-to-depth conversion viewer"),
00068       grabber_(0)
00069     {
00070     }
00071 
00072     ~SimpleOpenNIViewer ()
00073     {
00074       if (grabber_)
00075         delete grabber_;
00076     }
00077 
00078     void
00079     image_callback (const boost::shared_ptr<openni_wrapper::Image> &image,
00080                     const boost::shared_ptr<openni_wrapper::DepthImage> &depth_image, float)
00081     {
00082 
00083       vector<uint16_t> raw_shift_data;
00084       vector<uint16_t> raw_depth_data;
00085 
00086       vector<uint8_t> rgb_data;
00087 
00088       uint32_t width=depth_image->getWidth ();
00089       uint32_t height=depth_image->getHeight ();
00090 
00091       // copy raw shift data from depth_image
00092       raw_shift_data.resize(width*height);
00093       depth_image->fillDepthImageRaw (width, height, &raw_shift_data[0], static_cast<unsigned int> (width * sizeof (uint16_t)));
00094 
00095       // convert raw shift data to raw depth data
00096       raw_depth_data.resize(width*height);
00097       grabber_->convertShiftToDepth(&raw_shift_data[0], &raw_depth_data[0], raw_shift_data.size());
00098 
00099       // check for color data
00100       if (image->getEncoding() != openni_wrapper::Image::RGB)
00101       {
00102         // copy raw rgb data from image
00103         rgb_data.resize(width*height*3);
00104         image->fillRGB(width, height, &rgb_data[0], static_cast<unsigned int> (width * sizeof (uint8_t) * 3));
00105       }
00106 
00107       // empty pointcloud
00108       pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloud = pcl::PointCloud<pcl::PointXYZRGB>::Ptr(new pcl::PointCloud<pcl::PointXYZRGB>());
00109 
00110       // convert raw depth and rgb data to pointcloud
00111       convert (raw_depth_data,
00112                rgb_data,
00113                width,
00114                height,
00115                depth_image->getFocalLength(),
00116                *cloud);
00117 
00118       // display pointcloud
00119       viewer_.showCloud (cloud);
00120     }
00121 
00122     void
00123     run ()
00124     {
00125       // initialize OpenNIDevice to shift-value mode
00126       pcl::OpenNIGrabber::Mode image_mode = pcl::OpenNIGrabber::OpenNI_Default_Mode;
00127       int depthformat = openni_wrapper::OpenNIDevice::OpenNI_shift_values;
00128 
00129       grabber_ = new pcl::OpenNIGrabber("", pcl::OpenNIGrabber::OpenNI_Default_Mode, image_mode);
00130 
00131       // Set the depth output format
00132       grabber_->getDevice ()->setDepthOutputFormat (static_cast<openni_wrapper::OpenNIDevice::DepthMode> (depthformat));
00133 
00134       // define image callback
00135       boost::function<void
00136       (const boost::shared_ptr<openni_wrapper::Image>&, const boost::shared_ptr<openni_wrapper::DepthImage>&, float)> image_cb =
00137           boost::bind (&SimpleOpenNIViewer::image_callback, this, _1, _2, _3);
00138       boost::signals2::connection image_connection = grabber_->registerCallback (image_cb);
00139 
00140       // start grabber thread
00141       grabber_->start ();
00142       while (true)
00143       {
00144         boost::this_thread::sleep (boost::posix_time::seconds (1));
00145       }
00146       grabber_->stop ();
00147 
00148   }
00149 
00150 protected:
00151 
00152   /* helper method to convert depth&rgb data to pointcloud*/
00153   void
00154   convert (std::vector<uint16_t>& depthData_arg,
00155            std::vector<uint8_t>& rgbData_arg,
00156            size_t width_arg,
00157            size_t height_arg,
00158            float focalLength_arg,
00159            pcl::PointCloud<PointXYZRGB>& cloud_arg) const
00160   {
00161     size_t i;
00162     size_t cloud_size = width_arg * height_arg;
00163 
00164     int x, y, centerX, centerY;
00165 
00166     // Reset point cloud
00167     cloud_arg.points.clear ();
00168     cloud_arg.points.reserve (cloud_size);
00169 
00170     // Define point cloud parameters
00171     cloud_arg.width = static_cast<uint32_t> (width_arg);
00172     cloud_arg.height = static_cast<uint32_t> (height_arg);
00173     cloud_arg.is_dense = false;
00174 
00175     // Calculate center of disparity image
00176     centerX = static_cast<int> (width_arg / 2);
00177     centerY = static_cast<int> (height_arg / 2);
00178 
00179     const float fl_const = 1.0f / focalLength_arg;
00180     static const float bad_point = std::numeric_limits<float>::quiet_NaN ();
00181 
00182     i = 0;
00183     for (y = -centerY; y < +centerY; ++y)
00184       for (x = -centerX; x < +centerX; ++x)
00185       {
00186         PointXYZRGB newPoint;
00187 
00188         const uint16_t& pixel_depth = depthData_arg[i];
00189 
00190         if (pixel_depth)
00191         {
00192           float depth = pixel_depth/1000.0f; // raw mm -> m
00193 
00194           // Define point location
00195           newPoint.z = depth;
00196           newPoint.x = static_cast<float> (x) * depth * fl_const;
00197           newPoint.y = static_cast<float> (y) * depth * fl_const;
00198 
00199           const uint8_t& pixel_r = rgbData_arg[i * 3 + 0];
00200           const uint8_t& pixel_g = rgbData_arg[i * 3 + 1];
00201           const uint8_t& pixel_b = rgbData_arg[i * 3 + 2];
00202 
00203           // Define point color
00204           uint32_t rgb = (static_cast<uint32_t> (pixel_r) << 16 | static_cast<uint32_t> (pixel_g) << 8
00205               | static_cast<uint32_t> (pixel_b));
00206           newPoint.rgb = *reinterpret_cast<float*> (&rgb);
00207         }
00208         else
00209         {
00210           // Define bad point
00211           newPoint.x = newPoint.y = newPoint.z = bad_point;
00212           newPoint.rgb = 0.0f;
00213         }
00214 
00215         // Add point to cloud
00216         cloud_arg.points.push_back (newPoint);
00217         // Increment point iterator
00218         ++i;
00219       }
00220   }
00221 
00222   pcl::visualization::CloudViewer viewer_;
00223   pcl::OpenNIGrabber* grabber_;
00224 
00225 };
00226 
00227 int
00228 main (int, char **)
00229 {
00230   SimpleOpenNIViewer v;
00231   v.run ();
00232 
00233   return (0);
00234 }
00235 


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