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.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