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
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,
00075 OpenNI_12_bit_depth = 1,
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
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
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
00453
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
00500
00501
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