Image Component Library (ICL)
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
OpenNIUtils.h
Go to the documentation of this file.
00001 /********************************************************************
00002 **                Image Component Library (ICL)                    **
00003 **                                                                 **
00004 ** Copyright (C) 2006-2013 CITEC, University of Bielefeld          **
00005 **                         Neuroinformatics Group                  **
00006 ** Website: www.iclcv.org and                                      **
00007 **          http://opensource.cit-ec.de/projects/icl               **
00008 **                                                                 **
00009 ** File   : ICLIO/src/ICLIO/OpenNIUtils.h                          **
00010 ** Module : ICLIO                                                  **
00011 ** Authors: Viktor Richter                                         **
00012 **                                                                 **
00013 **                                                                 **
00014 ** GNU LESSER GENERAL PUBLIC LICENSE                               **
00015 ** This file may be used under the terms of the GNU Lesser General **
00016 ** Public License version 3.0 as published by the                  **
00017 **                                                                 **
00018 ** Free Software Foundation and appearing in the file LICENSE.LGPL **
00019 ** included in the packaging of this file.  Please review the      **
00020 ** following information to ensure the license requirements will   **
00021 ** be met: http://www.gnu.org/licenses/lgpl-3.0.txt                **
00022 **                                                                 **
00023 ** The development of this software was supported by the           **
00024 ** Excellence Cluster EXC 277 Cognitive Interaction Technology.    **
00025 ** The Excellence Cluster EXC 277 is a grant of the Deutsche       **
00026 ** Forschungsgemeinschaft (DFG) in the context of the German       **
00027 ** Excellence Initiative.                                          **
00028 **                                                                 **
00029 ********************************************************************/
00030 
00031 #pragma once
00032 
00033 #include <ICLCore/ImgBase.h>
00034 #include <ICLUtils/Mutex.h>
00035 #include <ICLUtils/Thread.h>
00036 #include <ICLUtils/Configurable.h>
00037 #include <ICLCore/CCFunctions.h>
00038 
00039 #include <ICLIO/OpenNIIncludes.h>
00040 
00041 #include <map>
00042 #include <limits>
00043 #include <set>
00044 
00045 namespace icl {
00046   namespace io{
00047 
00048     namespace icl_openni {
00049 
00051       template<class T>
00052       core::Img<T>* convertDepthImg(xn::DepthMetaData* src, core::Img<T>* dst){
00053         float max = 0;
00054         if (std::numeric_limits<T>::max() < src -> ZRes()){
00055           max = ((float) std::numeric_limits<T>::max()) / ((float) src -> ZRes());
00056         }
00057 
00058         dst -> setSize(utils::Size(src -> XRes(), src -> YRes()));
00059         T* data = dst -> getData(0);
00060         // draw DEPTH image
00061         const XnDepthPixel* pDepthRow = src -> Data();
00062         if(!max){
00063           for (unsigned int y = 0; y < src -> YRes(); ++y){
00064             for (unsigned int x = 0; x < src -> XRes(); ++x, ++pDepthRow, ++data){
00065               *data = *pDepthRow;
00066             }
00067           }
00068         } else {
00069           for (unsigned int y = 0; y < src -> YRes(); ++y){
00070             for (unsigned int x = 0; x < src -> XRes(); ++x, ++pDepthRow, ++data){
00071               *data = *pDepthRow * max;
00072             }
00073           }
00074         }
00075         return dst;
00076       }
00077 
00079       inline core::Img16s* convertIRImg(xn::IRMetaData* src, core::Img16s* dst){
00080         dst -> setSize(utils::Size(src -> XRes(), src -> YRes()));
00081         icl16s* data = dst -> getData(0);
00082         const XnIRPixel* pIRRow = src -> Data();
00083         // draw grayscale image
00084         for (unsigned int y = 0; y < src -> YRes(); ++y){
00085           for (unsigned int x = 0; x < src -> XRes(); ++x, ++pIRRow, ++data){
00086             *data = *pIRRow;
00087           }
00088         }
00089         return dst;
00090       }
00091 
00096       inline core::Img8u* convertRGBImg(xn::ImageMetaData* src, core::Img8u* dst){
00097         dst -> setSize(utils::Size(src -> XRes(), src -> YRes()));
00098         dst -> setFormat(core::formatRGB);
00099         // draw RGB image
00100         icl8u* rChannel = dst -> getData(0);
00101         icl8u* gChannel = dst -> getData(1);
00102         icl8u* bChannel = dst -> getData(2);
00103         const XnRGB24Pixel* rgbPixel = src -> RGB24Data();
00104         for (unsigned int y = 0; y < src -> YRes(); ++y){
00105           for (unsigned int x = 0; x < src -> XRes(); ++x, ++rgbPixel, ++rChannel,
00106                ++gChannel, ++bChannel)
00107           {
00108             *rChannel = rgbPixel -> nRed;
00109             *gChannel = rgbPixel -> nGreen;
00110             *bChannel = rgbPixel -> nBlue;
00111           }
00112         }
00113         return dst;
00114       }
00115 
00116 
00121       inline core::Img8u* convertYuv422Img(xn::ImageMetaData* src, core::Img8u* dst){
00122         dst -> setSize(utils::Size(src -> XRes(), src -> YRes()));
00123         dst -> setFormat(core::formatRGB);
00124         // draw RGB image
00125         icl8u* rChannel = dst -> getData(0);
00126         icl8u* gChannel = dst -> getData(1);
00127         icl8u* bChannel = dst -> getData(2);
00128         const XnYUV422DoublePixel* yuvPixel = src -> YUV422Data();
00129         icl32s r,g,b;
00130         for (int i = 0; i < dst-> getDim()/2 ; ++i){
00131           icl::core::cc_util_yuv_to_rgb(yuvPixel->nY1,yuvPixel->nU,yuvPixel->nV,r,g,b);
00132           *rChannel = r; ++rChannel;
00133           *gChannel = g; ++gChannel;
00134           *bChannel = b; ++bChannel;
00135           icl::core::cc_util_yuv_to_rgb(yuvPixel->nY2,yuvPixel->nU,yuvPixel->nV,r,g,b);
00136           *rChannel = r; ++rChannel;
00137           *gChannel = g; ++gChannel;
00138           *bChannel = b; ++bChannel;
00139           ++yuvPixel;
00140         }
00141         return dst;
00142       }
00143 
00148       inline core::Img8u* convertGrayScale8Img(xn::ImageMetaData* src, core::Img8u* dst){
00149         dst -> setSize(utils::Size(src -> XRes(), src -> YRes()));
00150         dst -> setFormat(core::formatGray);
00151         // draw RGB image
00152         icl8u* gChannel = dst -> getData(0);
00153         const XnGrayscale8Pixel* grayPixel = src -> Grayscale8Data();
00154         for (int i = 0; i < dst-> getDim() ; ++i){
00155           *gChannel = *grayPixel;
00156           ++gChannel; ++grayPixel;
00157         }
00158         return dst;
00159       }
00160 
00162       template<typename T>
00163       class ReadWriteBufferHandler {
00164         public:
00166           virtual T* initBuffer() = 0;
00167       };
00168 
00170 
00174       template<typename T>
00175       class ReadWriteBuffer {
00176         public:
00178           ReadWriteBuffer(ReadWriteBufferHandler<T>* buffer_handler)
00179             : m_Mutex(), m_Write(0), m_Next(1), m_Read(2)
00180           {
00181             utils::Mutex::Locker l(m_Mutex);
00182             m_BufferHandler = buffer_handler;
00183             m_Buffers[0] = m_BufferHandler -> initBuffer();
00184             m_Buffers[1] = m_BufferHandler -> initBuffer();
00185             m_Buffers[2] = m_BufferHandler -> initBuffer();
00186             m_ResetBuffers[0] = false;
00187             m_ResetBuffers[1] = false;
00188             m_ResetBuffers[2] = false;
00189           }
00190 
00192           ~ReadWriteBuffer(){
00193             utils::Mutex::Locker l(m_Mutex);
00194             ICL_DELETE(m_Buffers[0]);
00195             ICL_DELETE(m_Buffers[1]);
00196             ICL_DELETE(m_Buffers[2]);
00197           }
00198 
00200 
00204           T* getNextReadBuffer(){
00205             utils::Mutex::Locker l(m_Mutex);
00206             if(m_Avail){
00207               // new buffer is available.
00208               std::swap(m_Next, m_Read);
00209               m_Avail = false;
00210             }
00211             return m_Buffers[m_Read];
00212           }
00213 
00215 
00229           T* getNextReadBuffer(bool omit_double_frames=false,
00230                                int omit_max_wait_millis=1000,
00231                                int omit_sleep_micros=1000){
00232             T* tmp = NULL;
00233             utils::Time t = utils::Time::now();
00234             while (true){
00235               m_Mutex.lock();
00236               if(m_Avail){
00237                 // new buffer is available.
00238                 std::swap(m_Next, m_Read);
00239                 m_Avail = false;
00240                 tmp = m_Buffers[m_Read];
00241                 m_Mutex.unlock();
00242                 break;
00243               } else if(!omit_double_frames){
00244                 tmp = m_Buffers[m_Read];
00245                 m_Mutex.unlock();
00246                 break;
00247               }
00248               m_Mutex.unlock();
00249               if(t.age().toMilliSeconds() > omit_max_wait_millis){
00250                 break;
00251               }
00252               utils::Thread::usleep(omit_sleep_micros);
00253             }
00254             return tmp;
00255           }
00256 
00258 
00262           T* getNextWriteBuffer(){
00263             utils::Mutex::Locker l(m_Mutex);
00264             // swap write buffer and next buffer.
00265             std::swap(m_Next, m_Write);
00266             // new buffer is available for reading.
00267             m_Avail = true;
00268             // reset buffer when needed
00269             if(m_ResetBuffers[m_Write]){
00270               ICL_DELETE(m_Buffers[m_Write]);
00271               m_Buffers[m_Write] = m_BufferHandler -> initBuffer();
00272               m_ResetBuffers[m_Write] = false;
00273             }
00274             // return new write buffer.
00275             return m_Buffers[m_Write];
00276           }
00277 
00279           void setReset(){
00280             utils::Mutex::Locker l(m_Mutex);
00281             m_ResetBuffers[0] = true;
00282             m_ResetBuffers[1] = true;
00283             m_ResetBuffers[2] = true;
00284           }
00285 
00287           void switchHandler(ReadWriteBufferHandler<T>* new_handler){
00288             utils::Mutex::Locker l(m_Mutex);
00289             m_BufferHandler = new_handler;
00290             m_ResetBuffers[0] = true;
00291             m_ResetBuffers[1] = true;
00292             m_ResetBuffers[2] = true;
00293           }
00294 
00296           bool newAvailable(){
00297             utils::Mutex::Locker l(m_Mutex);
00298             return m_Avail;
00299           }
00300 
00301         private:
00303           ReadWriteBufferHandler<T>* m_BufferHandler;
00305           T*  m_Buffers[3];
00307           bool  m_ResetBuffers[3];
00309           utils::Mutex m_Mutex;
00311           int m_Write;
00313           int m_Next;
00315           int m_Read;
00317           bool m_Avail;
00318       };
00319 
00321       class OpenNIContext : public utils::Uncopyable {
00322         private:
00324           OpenNIContext();
00325 
00327           ~OpenNIContext();
00328 
00330           static OpenNIContext* getInst();
00331 
00332         public:
00333 
00335           static XnStatus waitAndUpdate();
00336 
00338           static XnStatus CreateProductionTree(xn::NodeInfo& Tree, xn::ProductionNode& node);
00339 
00341           static XnStatus EnumerateProductionTrees(XnProductionNodeType type,
00342                                                    const xn::Query* pQuery,
00343                                                    xn::NodeInfoList& TreesList,
00344                                                    xn::EnumerationErrors* pErrors = NULL);
00345 
00347           static XnStatus Create(xn::DepthGenerator* generator);
00348 
00349         private:
00351           utils::Mutex m_Lock;
00353           bool m_Initialized;
00355           xn::Context m_Context;
00356       };
00357 
00359       class MapGeneratorOptions : public utils::Configurable {
00360         public:
00362           MapGeneratorOptions(xn::MapGenerator* generator);
00363 
00365           void processPropertyChange(const utils::Configurable::Property &prop);
00366 
00368           void addGeneralIntProperty(const std::string name);
00369 
00370         private:
00372           xn::MapGenerator* m_Generator;
00374           std::vector<std::string> m_Capabilities;
00376           std::map<std::string, xn::ProductionNode> m_ProductionNodeMap;
00377       };
00378 
00380       class DepthGeneratorOptions : public MapGeneratorOptions {
00381         public:
00383           DepthGeneratorOptions(xn::DepthGenerator* generator);
00384 
00385         private:
00387           xn::DepthGenerator* m_DepthGenerator;
00388       };
00389 
00391       class ImageGeneratorOptions : public MapGeneratorOptions {
00392         public:
00394           ImageGeneratorOptions(xn::ImageGenerator* generator);
00395 
00397           void processPropertyChange(const utils::Configurable::Property &prop);
00398 
00399         private:
00401           xn::ImageGenerator* m_ImageGenerator;
00402       };
00403 
00405       class OpenNIMapGenerator : public ReadWriteBufferHandler<core::ImgBase> {
00406         public:
00407 
00409           enum Generators {
00410             RGB,
00411             DEPTH,
00412             IR,
00413             NOT_SPECIFIED = -1
00414           };
00415 
00417           virtual bool acquireImage(core::ImgBase* dest) = 0;
00419           virtual bool newFrameAvailable() = 0;
00421           virtual Generators getGeneratorType() = 0;
00423           virtual xn::MapGenerator* getMapGenerator() = 0;
00425           virtual core::ImgBase* initBuffer() = 0;
00427           virtual MapGeneratorOptions* getMapGeneratorOptions() = 0;
00428 
00429 
00431           static OpenNIMapGenerator* createGenerator(std::string id);
00433           static std::string getMapOutputModeInfo(xn::MapGenerator* gen);
00435           static std::string getCurrentMapOutputMode(xn::MapGenerator* gen);
00436       };
00437 
00439       class OpenNIDepthGenerator : public OpenNIMapGenerator {
00440         public:
00442           OpenNIDepthGenerator(int num);
00444           ~OpenNIDepthGenerator();
00445 
00447           bool acquireImage(core::ImgBase* dest);
00449           bool newFrameAvailable();
00451           Generators getGeneratorType();
00453           xn::MapGenerator* getMapGenerator();
00455           core::ImgBase* initBuffer();
00457           MapGeneratorOptions* getMapGeneratorOptions();
00458 
00459         private:
00461           xn::DepthGenerator* m_DepthGenerator;
00463           xn::DepthMetaData m_DepthMD;
00465           MapGeneratorOptions* m_Options;
00467           unsigned int m_FrameId;
00468       };
00469 
00471       class OpenNIRgbGenerator : public OpenNIMapGenerator {
00472         public:
00474           OpenNIRgbGenerator(int num);
00476           ~OpenNIRgbGenerator();
00477 
00479           bool acquireImage(core::ImgBase* dest);
00481           bool newFrameAvailable();
00483           Generators getGeneratorType();
00485           xn::MapGenerator* getMapGenerator();
00487           core::Img8u* initBuffer();
00489           MapGeneratorOptions* getMapGeneratorOptions();
00490 
00491         private:
00493           xn::NodeInfo* m_DeviceInfo;
00495           xn::ImageGenerator* m_RgbGenerator;
00497           unsigned int m_FrameId;
00499 
00503           xn::DepthGenerator* m_DepthGenerator;
00504           xn::IRGenerator* m_IrGenerator;
00506           xn::ImageMetaData m_RgbMD;
00508           MapGeneratorOptions* m_Options;
00509       };
00510 
00512       class OpenNIIRGenerator : public OpenNIMapGenerator {
00513         public:
00515           OpenNIIRGenerator(int num);
00517           ~OpenNIIRGenerator();
00518 
00520           bool acquireImage(core::ImgBase* dest);
00522           bool newFrameAvailable();
00524           Generators getGeneratorType();
00526           xn::MapGenerator* getMapGenerator();
00528           core::Img16s* initBuffer();
00530           MapGeneratorOptions* getMapGeneratorOptions();
00531 
00532         private:
00534           xn::NodeInfo* m_DeviceInfo;
00536           xn::IRGenerator* m_IrGenerator;
00538           xn::IRMetaData m_IrMD;
00540           MapGeneratorOptions* m_Options;
00542           unsigned int m_FrameId;
00543       };
00544 
00545     } // namespace icl_openni
00546 
00547   } // namespace io
00548 } // namespace icl
00549 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines