openni_device.h
Go to the documentation of this file.
00001 /*
00002  * Software License Agreement (BSD License)
00003  *
00004  *  Point Cloud Library (PCL) - www.pointclouds.org
00005  *  Copyright (c) 2009-2011, Willow Garage, Inc.
00006  *
00007  *  All rights reserved.
00008  *
00009  *  Redistribution and use in source and binary forms, with or without
00010  *  modification, are permitted provided that the following conditions
00011  *  are met:
00012  *
00013  *   * Redistributions of source code must retain the above copyright
00014  *     notice, this list of conditions and the following disclaimer.
00015  *   * Redistributions in binary form must reproduce the above
00016  *     copyright notice, this list of conditions and the following
00017  *     disclaimer in the documentation and/or other materials provided
00018  *     with the distribution.
00019  *   * Neither the name of the copyright holder(s) nor the names of its
00020  *     contributors may be used to endorse or promote products derived
00021  *     from this software without specific prior written permission.
00022  *
00023  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00024  *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00025  *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
00026  *  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
00027  *  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
00028  *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
00029  *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00030  *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00031  *  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00032  *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
00033  *  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00034  *  POSSIBILITY OF SUCH DAMAGE.
00035  *
00036  */
00037 
00038 #include <pcl/pcl_config.h>
00039 #ifdef HAVE_OPENNI
00040 
00041 #ifndef __OPENNI_IDEVICE_H__
00042 #define __OPENNI_IDEVICE_H__
00043 #include <map>
00044 #include <vector>
00045 #include <utility>
00046 #include "openni_exception.h"
00047 #include "openni.h"
00048 
00049 #include <pcl/io/boost.h>
00050 #include <pcl/pcl_macros.h>
00051 
00052 
00054 
00055 #ifndef _WIN32
00056 #define __stdcall
00057 #endif
00058 
00059 namespace openni_wrapper
00060 {
00061   class Image;
00062   class DepthImage;
00063   class IRImage;
00064 
00069   class PCL_EXPORTS OpenNIDevice
00070   {
00071     public:
00072       typedef enum
00073       {
00074         OpenNI_shift_values = 0, // Shift values (disparity)
00075         OpenNI_12_bit_depth = 1, // Default mode: regular 12-bit depth
00076       } DepthMode;
00077 
00078       typedef boost::function<void(boost::shared_ptr<Image>, void* cookie) > ImageCallbackFunction;
00079       typedef boost::function<void(boost::shared_ptr<DepthImage>, void* cookie) > DepthImageCallbackFunction;
00080       typedef boost::function<void(boost::shared_ptr<IRImage>, void* cookie) > IRImageCallbackFunction;
00081       typedef unsigned CallbackHandle;
00082 
00083     public:
00084 
00086       virtual ~OpenNIDevice () throw ();
00087 
00095       bool 
00096       findCompatibleImageMode (const XnMapOutputMode& output_mode, XnMapOutputMode& mode ) const throw ();
00097 
00105       bool 
00106       findCompatibleDepthMode (const XnMapOutputMode& output_mode, XnMapOutputMode& mode ) const throw ();
00107 
00112       bool 
00113       isImageModeSupported (const XnMapOutputMode& output_mode) const throw ();
00114 
00119       bool 
00120       isDepthModeSupported (const XnMapOutputMode& output_mode) const throw ();
00121 
00125       const XnMapOutputMode& 
00126       getDefaultImageMode () const throw ();
00127 
00131       const XnMapOutputMode& 
00132       getDefaultDepthMode () const throw ();
00133 
00137       const XnMapOutputMode& 
00138       getDefaultIRMode () const throw ();
00139 
00143       void 
00144       setImageOutputMode (const XnMapOutputMode& output_mode);
00145 
00149       void 
00150       setDepthOutputMode (const XnMapOutputMode& output_mode);
00151 
00155       void 
00156       setIROutputMode (const XnMapOutputMode& output_mode);
00157 
00159       XnMapOutputMode 
00160       getImageOutputMode () const;
00161 
00163       XnMapOutputMode 
00164       getDepthOutputMode () const;
00165 
00167       XnMapOutputMode 
00168       getIROutputMode () const;
00169 
00173       void 
00174       setDepthRegistration (bool on_off);
00175 
00177       bool 
00178       isDepthRegistered () const throw ();
00179 
00181       bool 
00182       isDepthRegistrationSupported () const throw ();
00183 
00187       void 
00188       setSynchronization (bool on_off);
00189 
00191       bool 
00192       isSynchronized () const throw ();
00193 
00195       virtual bool 
00196       isSynchronizationSupported () const throw ();
00197 
00199       bool 
00200       isDepthCropped () const;
00201 
00208       void 
00209       setDepthCropping (unsigned x, unsigned y, unsigned width, unsigned height);
00210 
00212       bool 
00213       isDepthCroppingSupported () const throw ();
00214 
00218       inline float 
00219       getImageFocalLength (int output_x_resolution = 0) const throw ();
00220 
00224       inline float 
00225       getDepthFocalLength (int output_x_resolution = 0) const throw ();
00226 
00228       inline float 
00229       getBaseline () const throw ();
00230 
00232       virtual void 
00233       startImageStream ();
00234 
00236       virtual void 
00237       stopImageStream ();
00238 
00240       virtual void 
00241       startDepthStream ();
00242 
00244       virtual void 
00245       stopDepthStream ();
00246 
00248       virtual void 
00249       startIRStream ();
00250 
00252       virtual void 
00253       stopIRStream ();
00254 
00256       bool 
00257       hasImageStream () const throw ();
00258 
00260       bool 
00261       hasDepthStream () const throw ();
00262 
00264       bool 
00265       hasIRStream () const throw ();
00266 
00268       virtual bool 
00269       isImageStreamRunning () const throw ();
00270 
00272       virtual bool 
00273       isDepthStreamRunning () const throw ();
00274 
00276       virtual bool 
00277       isIRStreamRunning () const throw ();
00278 
00285       CallbackHandle 
00286       registerImageCallback (const ImageCallbackFunction& callback, void* cookie = NULL) throw ();
00287 
00295       template<typename T> CallbackHandle 
00296       registerImageCallback (void (T::*callback)(boost::shared_ptr<Image>, void* cookie), T& instance, void* cookie = NULL) throw ();
00297 
00302       bool 
00303       unregisterImageCallback (const CallbackHandle& callbackHandle) throw ();
00304 
00305 
00312       CallbackHandle 
00313       registerDepthCallback (const DepthImageCallbackFunction& callback, void* cookie = NULL) throw ();
00314 
00322       template<typename T> CallbackHandle 
00323       registerDepthCallback (void (T::*callback)(boost::shared_ptr<DepthImage>, void* cookie), T& instance, void* cookie = NULL) throw ();
00324 
00329       bool 
00330       unregisterDepthCallback (const CallbackHandle& callbackHandle) throw ();
00331 
00338       CallbackHandle 
00339       registerIRCallback (const IRImageCallbackFunction& callback, void* cookie = NULL) throw ();
00340 
00348       template<typename T> CallbackHandle 
00349       registerIRCallback (void (T::*callback)(boost::shared_ptr<IRImage>, void* cookie), T& instance, void* cookie = NULL) throw ();
00350 
00355       bool 
00356       unregisterIRCallback (const CallbackHandle& callbackHandle) throw ();
00357 
00361       const char* 
00362       getSerialNumber () const throw ();
00363 
00365       const char* 
00366       getConnectionString () const throw ();
00367 
00369       const char* 
00370       getVendorName () const throw ();
00371 
00373       const char* 
00374       getProductName () const throw ();
00375 
00377       unsigned short 
00378       getVendorID () const throw ();
00379 
00381       unsigned short 
00382       getProductID () const throw ();
00383 
00385       unsigned char  
00386       getBus () const throw ();
00387 
00389       unsigned char  
00390       getAddress () const throw ();
00391 
00395       inline void
00396       setRGBFocalLength (float focal_length)
00397       {
00398         rgb_focal_length_SXGA_ = focal_length;
00399       }
00400 
00404       inline void
00405       setDepthFocalLength (float focal_length)
00406       {
00407         depth_focal_length_SXGA_ = focal_length;
00408       }
00409 
00413       void
00414       setDepthOutputFormat (const DepthMode& depth_mode = OpenNI_12_bit_depth);
00415 
00417       XnUInt64 
00418       getDepthOutputFormat () const;
00419 
00420 
00422       pcl::uint16_t
00423       shiftToDepth (pcl::uint16_t shift_value) const
00424       {
00425         assert (shift_conversion_parameters_.init_);
00426 
00427         pcl::uint16_t ret = 0;
00428 
00429         // lookup depth value in shift lookup table
00430         if (shift_value<shift_to_depth_table_.size())
00431           ret = shift_to_depth_table_[shift_value];
00432 
00433         return ret;
00434       }
00435 
00436     private:
00437       // make OpenNIDevice non copyable
00438       OpenNIDevice (OpenNIDevice const &);
00439       OpenNIDevice& operator=(OpenNIDevice const &);
00440     protected:
00441       typedef boost::function<void(boost::shared_ptr<Image>) > ActualImageCallbackFunction;
00442       typedef boost::function<void(boost::shared_ptr<DepthImage>) > ActualDepthImageCallbackFunction;
00443       typedef boost::function<void(boost::shared_ptr<IRImage>) > ActualIRImageCallbackFunction;
00444 
00445       OpenNIDevice (xn::Context& context, const xn::NodeInfo& device_node, const xn::NodeInfo& image_node, const xn::NodeInfo& depth_node, const xn::NodeInfo& ir_node);
00446       OpenNIDevice (xn::Context& context, const xn::NodeInfo& device_node, const xn::NodeInfo& depth_node, const xn::NodeInfo& ir_node);
00447       OpenNIDevice (xn::Context& context);
00448       static void __stdcall NewDepthDataAvailable (xn::ProductionNode& node, void* cookie) throw ();
00449       static void __stdcall NewImageDataAvailable (xn::ProductionNode& node, void* cookie) throw ();
00450       static void __stdcall NewIRDataAvailable (xn::ProductionNode& node, void* cookie) throw ();
00451 
00452       // This is a workaround, since in the NewDepthDataAvailable function WaitAndUpdateData leads to a dead-lock behaviour
00453       // and retrieving image data without WaitAndUpdateData leads to incomplete images!!!
00454       void 
00455       ImageDataThreadFunction ();
00456 
00457       void 
00458       DepthDataThreadFunction ();
00459 
00460       void 
00461       IRDataThreadFunction ();
00462 
00463       virtual bool 
00464       isImageResizeSupported (unsigned input_width, unsigned input_height, unsigned output_width, unsigned output_height) const  throw () = 0;
00465 
00466       void 
00467       setRegistration (bool on_off);
00468 
00469       virtual boost::shared_ptr<Image> 
00470       getCurrentImage (boost::shared_ptr<xn::ImageMetaData> image_data) const throw () = 0;
00471 
00472       void 
00473       Init ();
00474 
00475       void InitShiftToDepthConversion();
00476       void ReadDeviceParametersFromSensorNode();
00477 
00478       struct ShiftConversion
00479       {
00480         ShiftConversion() : init_(false) {}
00481 
00482         XnUInt16 zero_plane_distance_;
00483         XnFloat zero_plane_pixel_size_;
00484         XnFloat emitter_dcmos_distace_;
00485         XnUInt32 max_shift_;
00486         XnUInt32 device_max_shift_;
00487         XnUInt32 const_shift_;
00488         XnUInt32 pixel_size_factor_;
00489         XnUInt32 param_coeff_;
00490         XnUInt32 shift_scale_;
00491         XnUInt32 min_depth_;
00492         XnUInt32 max_depth_;
00493         bool init_;
00494 
00495       } shift_conversion_parameters_;
00496 
00497       std::vector<pcl::uint16_t> shift_to_depth_table_;
00498 
00499       // holds the callback functions together with custom data
00500       // since same callback function can be registered multiple times with e.g. different custom data
00501       // we use a map structure with a handle as the key
00502       std::map<CallbackHandle, ActualImageCallbackFunction> image_callback_;
00503       std::map<CallbackHandle, ActualDepthImageCallbackFunction> depth_callback_;
00504       std::map<CallbackHandle, ActualIRImageCallbackFunction> ir_callback_;
00505 
00506       std::vector<XnMapOutputMode> available_image_modes_;
00507       std::vector<XnMapOutputMode> available_depth_modes_;
00508 
00510       xn::Context& context_;
00512       xn::NodeInfo device_node_info_;
00513 
00515       xn::DepthGenerator depth_generator_;
00517       xn::ImageGenerator image_generator_;
00519       xn::IRGenerator ir_generator_;
00520 
00521       XnCallbackHandle depth_callback_handle_;
00522       XnCallbackHandle image_callback_handle_;
00523       XnCallbackHandle ir_callback_handle_;
00524 
00526       float depth_focal_length_SXGA_;
00528       float baseline_;
00530       float rgb_focal_length_SXGA_;
00531 
00533       XnUInt64 shadow_value_;
00535       XnUInt64 no_sample_value_;
00536 
00537       OpenNIDevice::CallbackHandle image_callback_handle_counter_;
00538       OpenNIDevice::CallbackHandle depth_callback_handle_counter_;
00539       OpenNIDevice::CallbackHandle ir_callback_handle_counter_;
00540 
00541       bool quit_;
00542       mutable boost::mutex image_mutex_;
00543       mutable boost::mutex depth_mutex_;
00544       mutable boost::mutex ir_mutex_;
00545       boost::condition_variable image_condition_;
00546       boost::condition_variable depth_condition_;
00547       boost::condition_variable ir_condition_;
00548       boost::thread image_thread_;
00549       boost::thread depth_thread_;
00550       boost::thread ir_thread_;
00551   };
00552 
00554   float
00555   OpenNIDevice::getImageFocalLength (int output_x_resolution) const throw ()
00556   {
00557     if (output_x_resolution == 0)
00558       output_x_resolution = getImageOutputMode ().nXRes;
00559 
00560     float scale = static_cast<float> (output_x_resolution) / static_cast<float> (XN_SXGA_X_RES);
00561     return (rgb_focal_length_SXGA_ * scale);
00562   }
00563 
00565   float
00566   OpenNIDevice::getDepthFocalLength (int output_x_resolution) const throw ()
00567   {
00568     if (output_x_resolution == 0)
00569       output_x_resolution = getDepthOutputMode ().nXRes;
00570 
00571     float scale = static_cast<float> (output_x_resolution) / static_cast<float> (XN_SXGA_X_RES);
00572     if (isDepthRegistered ())
00573       return (rgb_focal_length_SXGA_ * scale);
00574     else
00575       return (depth_focal_length_SXGA_ * scale);
00576   }
00577 
00579   float
00580   OpenNIDevice::getBaseline () const throw ()
00581   {
00582     return (baseline_);
00583   }
00584 
00586   template<typename T> OpenNIDevice::CallbackHandle
00587   OpenNIDevice::registerImageCallback (void (T::*callback)(boost::shared_ptr<Image>, void* cookie), T& instance, void* custom_data) throw ()
00588   {
00589     image_callback_[image_callback_handle_counter_] = boost::bind (callback, boost::ref (instance), _1, custom_data);
00590     return (image_callback_handle_counter_++);
00591   }
00592 
00594   template<typename T> OpenNIDevice::CallbackHandle
00595   OpenNIDevice::registerDepthCallback (void (T::*callback)(boost::shared_ptr<DepthImage>, void* cookie), T& instance, void* custom_data) throw ()
00596   {
00597     depth_callback_[depth_callback_handle_counter_] = boost::bind ( callback,  boost::ref (instance), _1, custom_data);
00598     return (depth_callback_handle_counter_++);
00599   }
00600 
00602   template<typename T> OpenNIDevice::CallbackHandle
00603   OpenNIDevice::registerIRCallback (void (T::*callback)(boost::shared_ptr<IRImage>, void* cookie), T& instance, void* custom_data) throw ()
00604   {
00605     ir_callback_[ir_callback_handle_counter_] = boost::bind ( callback,  boost::ref (instance), _1, custom_data);
00606     return (ir_callback_handle_counter_++);
00607   }
00608 
00609 }
00610 #endif // __OPENNI_IDEVICE_H__
00611 #endif // HAVE_OPENNI


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