00001 /*!@file Devices/KinectGrabber.H Definition and access functions for Kinect grabber */ 00002 00003 // //////////////////////////////////////////////////////////////////// // 00004 // The iLab Neuromorphic Vision C++ Toolkit - Copyright (C) 2001 by the // 00005 // University of Southern California (USC) and the iLab at USC. // 00006 // See http://iLab.usc.edu for information about this project. // 00007 // //////////////////////////////////////////////////////////////////// // 00008 // Major portions of the iLab Neuromorphic Vision Toolkit are protected // 00009 // under the U.S. patent ``Computation of Intrinsic Perceptual Saliency // 00010 // in Visual Environments, and Applications'' by Christof Koch and // 00011 // Laurent Itti, California Institute of Technology, 2001 (patent // 00012 // pending; application number 09/912,225 filed July 23, 2001; see // 00013 // http://pair.uspto.gov/cgi-bin/final/home.pl for current status). // 00014 // //////////////////////////////////////////////////////////////////// // 00015 // This file is part of the iLab Neuromorphic Vision C++ Toolkit. // 00016 // // 00017 // The iLab Neuromorphic Vision C++ Toolkit is free software; you can // 00018 // redistribute it and/or modify it under the terms of the GNU General // 00019 // Public License as published by the Free Software Foundation; either // 00020 // version 2 of the License, or (at your option) any later version. // 00021 // // 00022 // The iLab Neuromorphic Vision C++ Toolkit is distributed in the hope // 00023 // that it will be useful, but WITHOUT ANY WARRANTY; without even the // 00024 // implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // 00025 // PURPOSE. See the GNU General Public License for more details. // 00026 // // 00027 // You should have received a copy of the GNU General Public License // 00028 // along with the iLab Neuromorphic Vision C++ Toolkit; if not, write // 00029 // to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, // 00030 // Boston, MA 02111-1307 USA. // 00031 // //////////////////////////////////////////////////////////////////// // 00032 // 00033 // Primary maintainer for this file: Laurent Itti <itti@usc.edu> 00034 // $HeadURL: svn://isvn.usc.edu/software/invt/trunk/saliency/src/Devices/KinectGrabber.H $ 00035 // $Id: KinectGrabber.H 14046 2010-09-25 05:58:24Z itti $ 00036 // 00037 00038 #ifndef KINECTGRABBER_H_DEFINED 00039 #define KINECTGRABBER_H_DEFINED 00040 00041 #ifdef INVT_HAVE_LIBFREENECT 00042 00043 #include <libfreenect.hpp> 00044 00045 #include "Component/ModelParam.H" 00046 #include "Image/Image.H" 00047 #include "Image/Pixels.H" 00048 #include "Transport/FrameIstream.H" 00049 #include "Raster/GenericFrame.H" 00050 #include "Util/SimTime.H" 00051 #include "Util/Types.H" 00052 #include "Video/VideoFormat.H" 00053 #include "rutz/mutex.h" 00054 00055 //! Helper class that implements frame callbacks 00056 class FreenectDev : public Freenect::FreenectDevice { 00057 public: 00058 //! Constructor 00059 FreenectDev(freenect_context *_ctx, int _index) : FreenectDevice(_ctx, _index) { 00060 if (0 != pthread_mutex_init(&itsMutex, NULL)) LFATAL("pthread_mutex_init() failed"); 00061 } 00062 00063 //! Destructor 00064 virtual ~FreenectDev() { 00065 if (0 != pthread_mutex_destroy(&itsMutex)) LERROR("pthread_mutex_destroy() failed"); 00066 } 00067 00068 //! Called by the Kinect driver when an RBG image is received 00069 virtual void VideoCallback(void *rgb, uint32_t timestamp) 00070 { 00071 Image<PixRGB<byte> > img((PixRGB<byte>*)(rgb), FREENECT_FRAME_W, FREENECT_FRAME_H); 00072 { 00073 GVX_MUTEX_LOCK(&itsMutex); 00074 itsColorImage = img; 00075 } 00076 } 00077 00078 //! Called by the Kinect driver when a depth image is received 00079 virtual void DepthCallback(void *depth, uint32_t timestamp) 00080 { 00081 Image<uint16> img(static_cast<uint16*>(depth), FREENECT_FRAME_W, FREENECT_FRAME_H); 00082 { 00083 GVX_MUTEX_LOCK(&itsMutex); 00084 itsDepthImage = img; 00085 } 00086 } 00087 00088 //! Called by users to collect frames 00089 GenericFrame grab() { 00090 // wait until both the color and depth images are available: 00091 while(true) { 00092 { 00093 GVX_MUTEX_LOCK(&itsMutex); 00094 if (itsColorImage.initialized() && itsDepthImage.initialized()) break; // got both images 00095 } 00096 usleep(3000); 00097 } 00098 00099 GVX_MUTEX_LOCK(&itsMutex); 00100 GenericFrame frame(itsColorImage, itsDepthImage); 00101 00102 // invalidate our buffers: 00103 itsColorImage.freeMem(); itsDepthImage.freeMem(); 00104 00105 return frame; 00106 } 00107 00108 private: 00109 Image<PixRGB<byte> > itsColorImage; 00110 Image<uint16> itsDepthImage; 00111 mutable pthread_mutex_t itsMutex; 00112 }; 00113 00114 //! Definition and access functions for Kinect frame grabber 00115 class KinectGrabber : public FrameIstream 00116 { 00117 public: 00118 //! Constructor 00119 KinectGrabber(OptionManager& mgr, 00120 const std::string& descrName = "Kinect Frame Grabber Driver", 00121 const std::string& tagName = "KinectFrameGrabber", 00122 const ParamFlag flags = USE_MY_VAL); 00123 00124 //! Destructor 00125 virtual ~KinectGrabber(); 00126 00127 /// Install a FrameListener 00128 /** We call the listener's onRawFrame() inside each readFrame(). */ 00129 virtual void setListener(rutz::shared_ptr<FrameListener> listener); 00130 00131 //! Return the specifications of the next frame to be returned 00132 virtual GenericFrameSpec peekFrameSpec(); 00133 00134 //! Get the next frame from the frame-grabber 00135 /*! Returns grabbed frame. This call will block until a frame is 00136 ready and has been grabbed. 00137 00138 Beware that the integrity of the GenericFrame object may not 00139 last "very long"; basically, try to be finished using the 00140 GenericFrame object before you attempt to grab the next frame in 00141 the stream. If you need it for longer than that, then you should 00142 use GenericFrame::deepCopyOf() to make a copy of the frame that 00143 can be safely held indefinitely. */ 00144 virtual GenericFrame readFrame(); 00145 00146 protected: 00147 //! get started 00148 virtual void start1(); 00149 00150 //! get stopped 00151 virtual void stop2(); 00152 00153 00154 private: 00155 OModelParam<Dims> itsDims; //!< Dims of grabbed frames 00156 rutz::shared_ptr<FrameListener> itsListener; 00157 00158 rutz::shared_ptr<Freenect::Freenect<FreenectDev> > itsDev; 00159 FreenectDev *itsFdev; 00160 }; 00161 00162 #endif 00163 00164 #endif 00165 00166 // ###################################################################### 00167 /* So things look consistent in everyone's emacs... */ 00168 /* Local Variables: */ 00169 /* indent-tabs-mode: nil */ 00170 /* End: */