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.GPL  **
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 
00038 #include <ICLIO/OpenNIIncludes.h>
00039 
00040 #include <map>
00041 #include <limits>
00042 
00043 namespace icl {
00044   namespace io{
00045 
00046     namespace icl_openni {
00047 
00049       template<class T>
00050       core::Img<T>* convertDepthImg(xn::DepthMetaData* src, core::Img<T>* dst){
00051         float max = 0;
00052         if (std::numeric_limits<T>::max() < src -> ZRes()){
00053           max = ((float) std::numeric_limits<T>::max()) / ((float) src -> ZRes());
00054         }
00055 
00056         dst -> setSize(utils::Size(src -> XRes(), src -> YRes()));
00057         T* data = dst -> getData(0);
00058         // draw DEPTH image
00059         const XnDepthPixel* pDepthRow = src -> Data();
00060         if(!max){
00061           for (unsigned int y = 0; y < src -> YRes(); ++y){
00062             for (unsigned int x = 0; x < src -> XRes(); ++x, ++pDepthRow, ++data){
00063               *data = *pDepthRow;
00064             }
00065           }
00066         } else {
00067           for (unsigned int y = 0; y < src -> YRes(); ++y){
00068             for (unsigned int x = 0; x < src -> XRes(); ++x, ++pDepthRow, ++data){
00069               *data = *pDepthRow * max;
00070             }
00071           }
00072         }
00073         return dst;
00074       }
00075 
00077       inline core::Img16s* convertIRImg(xn::IRMetaData* src, core::Img16s* dst){
00078         dst -> setSize(utils::Size(src -> XRes(), src -> YRes()));
00079         icl16s* data = dst -> getData(0);
00080         const XnIRPixel* pIRRow = src -> Data();
00081         // draw grayscale image
00082         for (unsigned int y = 0; y < src -> YRes(); ++y){
00083           for (unsigned int x = 0; x < src -> XRes(); ++x, ++pIRRow, ++data){
00084             *data = *pIRRow;
00085           }
00086         }
00087         return dst;
00088       }
00089 
00094       inline core::Img8u* convertRGBImg(xn::ImageMetaData* src, core::Img8u* dst){
00095         dst -> setSize(utils::Size(src -> XRes(), src -> YRes()));
00096         // draw RGB image
00097         icl8u* rChannel = dst -> getData(0);
00098         icl8u* gChannel = dst -> getData(1);
00099         icl8u* bChannel = dst -> getData(2);
00100         const XnRGB24Pixel* rgbPixel = src -> RGB24Data();
00101         for (unsigned int y = 0; y < src -> YRes(); ++y){
00102           for (unsigned int x = 0; x < src -> XRes(); ++x, ++rgbPixel, ++rChannel,
00103                ++gChannel, ++bChannel)
00104           {
00105             *rChannel = rgbPixel -> nRed;
00106             *gChannel = rgbPixel -> nGreen;
00107             *bChannel = rgbPixel -> nBlue;
00108           }
00109         }
00110         return dst;
00111       }
00112 
00114       template<typename T>
00115       class ReadWriteBufferHandler {
00116         public:
00118           virtual T* initBuffer() = 0;
00119       };
00120 
00122 
00126       template<typename T>
00127       class ReadWriteBuffer {
00128         public:
00130           ReadWriteBuffer(ReadWriteBufferHandler<T>* buffer_handler)
00131             : m_Mutex(), m_Write(0), m_Next(1), m_Read(2)
00132           {
00133             utils::Mutex::Locker l(m_Mutex);
00134             m_BufferHandler = buffer_handler;
00135             m_Buffers[0] = m_BufferHandler -> initBuffer();
00136             m_Buffers[1] = m_BufferHandler -> initBuffer();
00137             m_Buffers[2] = m_BufferHandler -> initBuffer();
00138             m_ResetBuffers[0] = false;
00139             m_ResetBuffers[1] = false;
00140             m_ResetBuffers[2] = false;
00141           }
00142 
00144           ~ReadWriteBuffer(){
00145             utils::Mutex::Locker l(m_Mutex);
00146             ICL_DELETE(m_Buffers[0]);
00147             ICL_DELETE(m_Buffers[1]);
00148             ICL_DELETE(m_Buffers[2]);
00149           }
00150 
00152 
00156           T* getNextReadBuffer(){
00157             utils::Mutex::Locker l(m_Mutex);
00158             if(m_Avail){
00159               // new buffer is available.
00160               std::swap(m_Next, m_Read);
00161               m_Avail = false;
00162             }
00163             return m_Buffers[m_Read];
00164           }
00165 
00167 
00181           T* getNextReadBuffer(bool omit_double_frames=false,
00182                                int omit_max_wait_millis=1000,
00183                                int omit_sleep_micros=1000){
00184             T* tmp = NULL;
00185             utils::Time t = utils::Time::now();
00186             while (true){
00187               m_Mutex.lock();
00188               if(m_Avail){
00189                 // new buffer is available.
00190                 std::swap(m_Next, m_Read);
00191                 m_Avail = false;
00192                 tmp = m_Buffers[m_Read];
00193                 m_Mutex.unlock();
00194                 break;
00195               } else if(!omit_double_frames){
00196                 tmp = m_Buffers[m_Read];
00197                 m_Mutex.unlock();
00198                 break;
00199               }
00200               m_Mutex.unlock();
00201               if(t.age().toMilliSeconds() > omit_max_wait_millis){
00202                 break;
00203               }
00204               utils::Thread::usleep(omit_sleep_micros);
00205             }
00206             return tmp;
00207           }
00208 
00210 
00214           T* getNextWriteBuffer(){
00215             utils::Mutex::Locker l(m_Mutex);
00216             // swap write buffer and next buffer.
00217             std::swap(m_Next, m_Write);
00218             // new buffer is available for reading.
00219             m_Avail = true;
00220             // reset buffer when needed
00221             if(m_ResetBuffers[m_Write]){
00222               ICL_DELETE(m_Buffers[m_Write]);
00223               m_Buffers[m_Write] = m_BufferHandler -> initBuffer();
00224               m_ResetBuffers[m_Write] = false;
00225             }
00226             // return new write buffer.
00227             return m_Buffers[m_Write];
00228           }
00229 
00231           void setReset(){
00232             utils::Mutex::Locker l(m_Mutex);
00233             m_ResetBuffers[0] = true;
00234             m_ResetBuffers[1] = true;
00235             m_ResetBuffers[2] = true;
00236           }
00237 
00239           void switchHandler(ReadWriteBufferHandler<T>* new_handler){
00240             utils::Mutex::Locker l(m_Mutex);
00241             m_BufferHandler = new_handler;
00242             m_ResetBuffers[0] = true;
00243             m_ResetBuffers[1] = true;
00244             m_ResetBuffers[2] = true;
00245           }
00246 
00248           bool newAvailable(){
00249             utils::Mutex::Locker l(m_Mutex);
00250             return m_Avail;
00251           }
00252 
00253         private:
00255           ReadWriteBufferHandler<T>* m_BufferHandler;
00257           T*  m_Buffers[3];
00259           bool  m_ResetBuffers[3];
00261           utils::Mutex m_Mutex;
00263           int m_Write;
00265           int m_Next;
00267           int m_Read;
00269           bool m_Avail;
00270       };
00271 
00273       class MapGeneratorOptions : public utils::Configurable {
00274         public:
00276           MapGeneratorOptions(xn::MapGenerator* generator, xn::Context* context);
00277 
00279           void processPropertyChange(const utils::Configurable::Property &prop);
00280 
00282           void addGeneralIntProperty(const std::string name);
00283 
00284         private:
00286           xn::MapGenerator* m_Generator;
00288           std::vector<std::string> m_Capabilities;
00290           std::map<std::string, xn::ProductionNode> m_ProductionNodeMap;
00291       };
00292 
00294       class DepthGeneratorOptions : public MapGeneratorOptions {
00295         public:
00297           DepthGeneratorOptions(xn::DepthGenerator* generator, xn::Context* context);
00298 
00299         private:
00301           xn::DepthGenerator* m_DepthGenerator;
00302       };
00303 
00305       class ImageGeneratorOptions : public MapGeneratorOptions {
00306         public:
00308           ImageGeneratorOptions(xn::ImageGenerator* generator, xn::Context* context);
00309 
00311           void processPropertyChange(const utils::Configurable::Property &prop);
00312 
00313         private:
00315           xn::ImageGenerator* m_ImageGenerator;
00316       };
00317 
00319       class OpenNIMapGenerator : public ReadWriteBufferHandler<core::ImgBase> {
00320         public:
00321 
00323           enum Generators {
00324             RGB,
00325             DEPTH,
00326             IR,
00327             NOT_SPECIFIED = -1
00328           };
00329 
00331           virtual bool acquireImage(core::ImgBase* dest) = 0;
00333           virtual Generators getGeneratorType() = 0;
00335           virtual xn::MapGenerator* getMapGenerator() = 0;
00337           virtual core::ImgBase* initBuffer() = 0;
00339           virtual MapGeneratorOptions* getMapGeneratorOptions() = 0;
00340 
00341 
00343           static OpenNIMapGenerator* createGenerator(xn::Context* context,
00344                                                      std::string id);
00346           static std::string getMapOutputModeInfo(xn::MapGenerator* gen);
00348           static std::string getCurrentMapOutputMode(xn::MapGenerator* gen);
00349       };
00350 
00352       class OpenNIDepthGenerator : public OpenNIMapGenerator {
00353         public:
00355           OpenNIDepthGenerator(xn::Context* context, int num);
00357           ~OpenNIDepthGenerator();
00358 
00360           bool acquireImage(core::ImgBase* dest);
00362           Generators getGeneratorType();
00364           xn::MapGenerator* getMapGenerator();
00366           core::ImgBase* initBuffer();
00368           MapGeneratorOptions* getMapGeneratorOptions();
00369 
00370         private:
00372           xn::Context* m_Context;
00374           xn::DepthGenerator* m_DepthGenerator;
00376           xn::DepthMetaData m_DepthMD;
00378           MapGeneratorOptions* m_Options;
00379       };
00380 
00382       class OpenNIRgbGenerator : public OpenNIMapGenerator {
00383         public:
00385           OpenNIRgbGenerator(xn::Context* context, int num);
00387           ~OpenNIRgbGenerator();
00388 
00390           bool acquireImage(core::ImgBase* dest);
00392           Generators getGeneratorType();
00394           xn::MapGenerator* getMapGenerator();
00396           core::Img8u* initBuffer();
00398           MapGeneratorOptions* getMapGeneratorOptions();
00399 
00400         private:
00402           xn::Context* m_Context;
00404           xn::NodeInfo* m_DeviceInfo;
00406           xn::ImageGenerator* m_RgbGenerator;
00408 
00412           xn::DepthGenerator* m_DepthGenerator;
00413           xn::IRGenerator* m_IrGenerator;
00415           xn::ImageMetaData m_RgbMD;
00417           MapGeneratorOptions* m_Options;
00418       };
00419 
00421       class OpenNIIRGenerator : public OpenNIMapGenerator {
00422         public:
00424           OpenNIIRGenerator(xn::Context* context, int num);
00426           ~OpenNIIRGenerator();
00427 
00429           bool acquireImage(core::ImgBase* dest);
00431           Generators getGeneratorType();
00433           xn::MapGenerator* getMapGenerator();
00435           core::Img16s* initBuffer();
00437           MapGeneratorOptions* getMapGeneratorOptions();
00438 
00439         private:
00441           xn::Context* m_Context;
00443           xn::NodeInfo* m_DeviceInfo;
00445           xn::IRGenerator* m_IrGenerator;
00447           xn::IRMetaData m_IrMD;
00449           MapGeneratorOptions* m_Options;
00450       };
00451 
00452     } // namespace icl_openni
00453 
00454   } // namespace io
00455 } // namespace icl
00456 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines