|
Point Cloud Library (PCL)
1.5.1
|
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 Willow Garage, Inc. 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 <XnCppWrapper.h> 00048 #include <boost/noncopyable.hpp> 00049 #include <boost/function.hpp> 00050 #include <boost/thread.hpp> 00051 #include <boost/thread/condition.hpp> 00052 00053 #include <pcl/pcl_macros.h> 00054 00056 00057 #ifndef _WIN32 00058 #define __stdcall 00059 #endif 00060 00061 namespace openni_wrapper 00062 { 00063 class Image; 00064 class DepthImage; 00065 class IRImage; 00066 00071 class PCL_EXPORTS OpenNIDevice : public boost::noncopyable 00072 { 00073 public: 00074 typedef boost::function<void(boost::shared_ptr<Image>, void* cookie) > ImageCallbackFunction; 00075 typedef boost::function<void(boost::shared_ptr<DepthImage>, void* cookie) > DepthImageCallbackFunction; 00076 typedef boost::function<void(boost::shared_ptr<IRImage>, void* cookie) > IRImageCallbackFunction; 00077 typedef unsigned CallbackHandle; 00078 00079 public: 00080 00082 virtual ~OpenNIDevice () throw (); 00083 00091 bool 00092 findCompatibleImageMode (const XnMapOutputMode& output_mode, XnMapOutputMode& mode ) const throw (); 00093 00101 bool 00102 findCompatibleDepthMode (const XnMapOutputMode& output_mode, XnMapOutputMode& mode ) const throw (); 00103 00108 bool 00109 isImageModeSupported (const XnMapOutputMode& output_mode) const throw (); 00110 00115 bool 00116 isDepthModeSupported (const XnMapOutputMode& output_mode) const throw (); 00117 00122 const XnMapOutputMode& 00123 getDefaultImageMode () const throw (); 00124 00128 const XnMapOutputMode& 00129 getDefaultDepthMode () const throw (); 00130 00134 const XnMapOutputMode& 00135 getDefaultIRMode () const throw (); 00136 00140 void 00141 setImageOutputMode (const XnMapOutputMode& output_mode); 00142 00146 void 00147 setDepthOutputMode (const XnMapOutputMode& output_mode); 00148 00152 void 00153 setIROutputMode (const XnMapOutputMode& output_mode); 00154 00156 XnMapOutputMode 00157 getImageOutputMode () const; 00158 00160 XnMapOutputMode 00161 getDepthOutputMode () const; 00162 00164 XnMapOutputMode 00165 getIROutputMode () const; 00166 00170 void 00171 setDepthRegistration (bool on_off); 00172 00174 bool 00175 isDepthRegistered () const throw (); 00176 00178 bool 00179 isDepthRegistrationSupported () const throw (); 00180 00184 void 00185 setSynchronization (bool on_off); 00186 00188 bool 00189 isSynchronized () const throw (); 00190 00192 bool 00193 isSynchronizationSupported () const throw (); 00194 00196 bool 00197 isDepthCropped () const; 00198 00205 void 00206 setDepthCropping (unsigned x, unsigned y, unsigned width, unsigned height); 00207 00209 bool 00210 isDepthCroppingSupported () const throw (); 00211 00215 inline float 00216 getImageFocalLength (int output_x_resolution = 0) const throw (); 00217 00221 inline float 00222 getDepthFocalLength (int output_x_resolution = 0) const throw (); 00223 00225 inline float 00226 getBaseline () const throw (); 00227 00229 virtual void 00230 startImageStream (); 00231 00233 virtual void 00234 stopImageStream (); 00235 00237 virtual void 00238 startDepthStream (); 00239 00241 virtual void 00242 stopDepthStream (); 00243 00245 virtual void 00246 startIRStream (); 00247 00249 virtual void 00250 stopIRStream (); 00251 00253 bool 00254 hasImageStream () const throw (); 00255 00257 bool 00258 hasDepthStream () const throw (); 00259 00261 bool 00262 hasIRStream () const throw (); 00263 00265 virtual bool 00266 isImageStreamRunning () const throw (); 00267 00269 virtual bool 00270 isDepthStreamRunning () const throw (); 00271 00273 virtual bool 00274 isIRStreamRunning () const throw (); 00275 00282 CallbackHandle 00283 registerImageCallback (const ImageCallbackFunction& callback, void* cookie = NULL) throw (); 00284 00292 template<typename T> CallbackHandle 00293 registerImageCallback (void (T::*callback)(boost::shared_ptr<Image>, void* cookie), T& instance, void* cookie = NULL) throw (); 00294 00299 bool 00300 unregisterImageCallback (const CallbackHandle& callbackHandle) throw (); 00301 00302 00309 CallbackHandle 00310 registerDepthCallback (const DepthImageCallbackFunction& callback, void* cookie = NULL) throw (); 00311 00319 template<typename T> CallbackHandle 00320 registerDepthCallback (void (T::*callback)(boost::shared_ptr<DepthImage>, void* cookie), T& instance, void* cookie = NULL) throw (); 00321 00326 bool 00327 unregisterDepthCallback (const CallbackHandle& callbackHandle) throw (); 00328 00335 CallbackHandle 00336 registerIRCallback (const IRImageCallbackFunction& callback, void* cookie = NULL) throw (); 00337 00345 template<typename T> CallbackHandle 00346 registerIRCallback (void (T::*callback)(boost::shared_ptr<IRImage>, void* cookie), T& instance, void* cookie = NULL) throw (); 00347 00352 bool 00353 unregisterIRCallback (const CallbackHandle& callbackHandle) throw (); 00354 00358 const char* 00359 getSerialNumber () const throw (); 00360 00362 const char* 00363 getConnectionString () const throw (); 00364 00366 const char* 00367 getVendorName () const throw (); 00368 00370 const char* 00371 getProductName () const throw (); 00372 00374 unsigned short 00375 getVendorID () const throw (); 00376 00378 unsigned short 00379 getProductID () const throw (); 00380 00382 unsigned char 00383 getBus () const throw (); 00384 00386 unsigned char 00387 getAddress () const throw (); 00388 00392 inline void 00393 setRGBFocalLength (float focal_length) 00394 { 00395 rgb_focal_length_SXGA_ = focal_length; 00396 } 00397 00401 inline void 00402 setDepthFocalLength (float focal_length) 00403 { 00404 depth_focal_length_SXGA_ = focal_length; 00405 } 00406 00407 protected: 00408 typedef boost::function<void(boost::shared_ptr<Image>) > ActualImageCallbackFunction; 00409 typedef boost::function<void(boost::shared_ptr<DepthImage>) > ActualDepthImageCallbackFunction; 00410 typedef boost::function<void(boost::shared_ptr<IRImage>) > ActualIRImageCallbackFunction; 00411 00412 OpenNIDevice (xn::Context& context, const xn::NodeInfo& device_node, const xn::NodeInfo& image_node, const xn::NodeInfo& depth_node, const xn::NodeInfo& ir_node); 00413 OpenNIDevice (xn::Context& context, const xn::NodeInfo& device_node, const xn::NodeInfo& depth_node, const xn::NodeInfo& ir_node); 00414 OpenNIDevice (xn::Context& context); 00415 static void __stdcall NewDepthDataAvailable (xn::ProductionNode& node, void* cookie) throw (); 00416 static void __stdcall NewImageDataAvailable (xn::ProductionNode& node, void* cookie) throw (); 00417 static void __stdcall NewIRDataAvailable (xn::ProductionNode& node, void* cookie) throw (); 00418 00419 // This is a workaround, since in the NewDepthDataAvailable function WaitAndUpdateData leads to a dead-lock behaviour 00420 // and retrieving image data without WaitAndUpdateData leads to incomplete images!!! 00421 void 00422 ImageDataThreadFunction (); 00423 00424 void 00425 DepthDataThreadFunction (); 00426 00427 void 00428 IRDataThreadFunction (); 00429 00430 virtual bool 00431 isImageResizeSupported (unsigned input_width, unsigned input_height, unsigned output_width, unsigned output_height) const throw () = 0; 00432 00433 void 00434 setRegistration (bool on_off); 00435 00436 virtual boost::shared_ptr<Image> 00437 getCurrentImage (boost::shared_ptr<xn::ImageMetaData> image_data) const throw () = 0; 00438 00439 void 00440 Init (); 00441 // holds the callback functions together with custom data 00442 // since same callback function can be registered multiple times with e.g. different custom data 00443 // we use a map structure with a handle as the key 00444 std::map<CallbackHandle, ActualImageCallbackFunction> image_callback_; 00445 std::map<CallbackHandle, ActualDepthImageCallbackFunction> depth_callback_; 00446 std::map<CallbackHandle, ActualIRImageCallbackFunction> ir_callback_; 00447 00448 std::vector<XnMapOutputMode> available_image_modes_; 00449 std::vector<XnMapOutputMode> available_depth_modes_; 00450 00452 xn::Context& context_; 00454 xn::NodeInfo device_node_info_; 00455 00457 xn::DepthGenerator depth_generator_; 00459 xn::ImageGenerator image_generator_; 00461 xn::IRGenerator ir_generator_; 00462 00463 XnCallbackHandle depth_callback_handle_; 00464 XnCallbackHandle image_callback_handle_; 00465 XnCallbackHandle ir_callback_handle_; 00466 00468 float depth_focal_length_SXGA_; 00470 float baseline_; 00472 float rgb_focal_length_SXGA_; 00473 00475 XnUInt64 shadow_value_; 00477 XnUInt64 no_sample_value_; 00478 00479 OpenNIDevice::CallbackHandle image_callback_handle_counter_; 00480 OpenNIDevice::CallbackHandle depth_callback_handle_counter_; 00481 OpenNIDevice::CallbackHandle ir_callback_handle_counter_; 00482 00483 bool quit_; 00484 mutable boost::mutex image_mutex_; 00485 mutable boost::mutex depth_mutex_; 00486 mutable boost::mutex ir_mutex_; 00487 boost::condition_variable image_condition_; 00488 boost::condition_variable depth_condition_; 00489 boost::condition_variable ir_condition_; 00490 boost::thread image_thread_; 00491 boost::thread depth_thread_; 00492 boost::thread ir_thread_; 00493 } ; 00494 00496 float 00497 OpenNIDevice::getImageFocalLength (int output_x_resolution) const throw () 00498 { 00499 if (output_x_resolution == 0) 00500 output_x_resolution = getImageOutputMode ().nXRes; 00501 00502 float scale = output_x_resolution / (float) XN_SXGA_X_RES; 00503 return (rgb_focal_length_SXGA_ * scale); 00504 } 00505 00507 float 00508 OpenNIDevice::getDepthFocalLength (int output_x_resolution) const throw () 00509 { 00510 if (output_x_resolution == 0) 00511 output_x_resolution = getDepthOutputMode ().nXRes; 00512 00513 float scale = output_x_resolution / (float) XN_SXGA_X_RES; 00514 if (isDepthRegistered ()) 00515 return (rgb_focal_length_SXGA_ * scale); 00516 else 00517 return (depth_focal_length_SXGA_ * scale); 00518 } 00519 00521 float 00522 OpenNIDevice::getBaseline () const throw () 00523 { 00524 return (baseline_); 00525 } 00526 00528 template<typename T> OpenNIDevice::CallbackHandle 00529 OpenNIDevice::registerImageCallback (void (T::*callback)(boost::shared_ptr<Image>, void* cookie), T& instance, void* custom_data) throw () 00530 { 00531 image_callback_[image_callback_handle_counter_] = boost::bind (callback, boost::ref (instance), _1, custom_data); 00532 return (image_callback_handle_counter_++); 00533 } 00534 00536 template<typename T> OpenNIDevice::CallbackHandle 00537 OpenNIDevice::registerDepthCallback (void (T::*callback)(boost::shared_ptr<DepthImage>, void* cookie), T& instance, void* custom_data) throw () 00538 { 00539 depth_callback_[depth_callback_handle_counter_] = boost::bind ( callback, boost::ref (instance), _1, custom_data); 00540 return (depth_callback_handle_counter_++); 00541 } 00542 00544 template<typename T> OpenNIDevice::CallbackHandle 00545 OpenNIDevice::registerIRCallback (void (T::*callback)(boost::shared_ptr<IRImage>, void* cookie), T& instance, void* custom_data) throw () 00546 { 00547 ir_callback_[ir_callback_handle_counter_] = boost::bind ( callback, boost::ref (instance), _1, custom_data); 00548 return (ir_callback_handle_counter_++); 00549 } 00550 00551 } 00552 #endif // __OPENNI_IDEVICE_H__ 00553 #endif // HAVE_OPENNI
1.8.0