Image Component Library (ICL)
|
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