/******************************************************************** ** Image Component Library (ICL) ** ** ** ** Copyright (C) 2006-2013 CITEC, University of Bielefeld ** ** Neuroinformatics Group ** ** Website: www.iclcv.org and ** ** http://opensource.cit-ec.de/projects/icl ** ** ** ** File : ICLIO/src/ICLIO/OpenNIUtils.cpp ** ** Module : ICLIO ** ** Authors: Viktor Richter ** ** ** ** ** ** GNU LESSER GENERAL PUBLIC LICENSE ** ** This file may be used under the terms of the GNU Lesser General ** ** Public License version 3.0 as published by the ** ** ** ** Free Software Foundation and appearing in the file LICENSE.LGPL ** ** included in the packaging of this file. Please review the ** ** following information to ensure the license requirements will ** ** be met: http://www.gnu.org/licenses/lgpl-3.0.txt ** ** ** ** The development of this software was supported by the ** ** Excellence Cluster EXC 277 Cognitive Interaction Technology. ** ** The Excellence Cluster EXC 277 is a grant of the Deutsche ** ** Forschungsgemeinschaft (DFG) in the context of the German ** ** Excellence Initiative. ** ** ** ********************************************************************/ #include #include #include #include #include #include #include #include #include #include using namespace xn; using namespace icl; using namespace utils; using namespace core; using namespace io; using namespace icl_openni; // checks whether status is OK. else throws an Exception. void assertStatus(XnStatus status, bool throwing=true){ if (status != XN_STATUS_OK){ std::ostringstream st; st << "XnStatus != XN_STATUS_OK. Got '" << xnGetStatusString(status) << "'"; ERROR_LOG(st.str()); if(throwing){ throw new ICLException(st.str()); } } } //############################################################################## //############################# OpenNIContext ################################## //############################################################################## OpenNIContext::OpenNIContext() : m_Initialized(false) {} OpenNIContext::~OpenNIContext(){ Mutex::Locker l(m_Lock); if(m_Initialized){ m_Context.Release(); m_Initialized = false; } } OpenNIContext* OpenNIContext::getInst(){ static OpenNIContext inst; Mutex::Locker l(inst.m_Lock); if(!inst.m_Initialized){ XnStatus xn = inst.m_Context.Init(); assertStatus(xn); inst.m_Initialized = true; } return &inst; } XnStatus OpenNIContext::waitAndUpdate(){ XnStatus ret = getInst()->m_Context.WaitAnyUpdateAll(); return ret; } XnStatus OpenNIContext::CreateProductionTree(NodeInfo& tree, ProductionNode& node){ return getInst()->m_Context.CreateProductionTree(tree,node);; } XnStatus OpenNIContext::EnumerateProductionTrees(XnProductionNodeType type, const xn::Query* pQuery, xn::NodeInfoList& TreesList, xn::EnumerationErrors* pErrors) { return getInst()->m_Context.EnumerateProductionTrees(type,pQuery,TreesList,pErrors); } XnStatus OpenNIContext::Create(DepthGenerator *generator){ return generator->Create(getInst()->m_Context); } //############################################################################## //############################# OpenNIMapGenerator ############################# //############################################################################## // Creates the corresponding Generator. OpenNIMapGenerator* OpenNIMapGenerator::createGenerator(std::string id) { // create generator from string if(id == "depth"){ return new OpenNIDepthGenerator(0); } else if(id == "rgb"){ return new OpenNIRgbGenerator(0); } else if(id == "ir") { return new OpenNIIRGenerator(0); } // create generator from string with index std::string type = id.substr(0,id.size()-1); int num = utils::parse(id.substr(id.size()-1, id.npos)); if(type == "depth"){ return new OpenNIDepthGenerator(num); } else if(type == "rgb"){ return new OpenNIRgbGenerator(num); } else if(type == "ir") { return new OpenNIIRGenerator(num); } else { std::ostringstream s; s << "Generator type '" << id << "' not supported."; std::cout << "Unknown generator type '" << id << "'." << std::endl; std::cout << "Supported generator types are: rgb, depth and ir" << std::endl; throw new ICLException(s.str()); } } // creates an info string for MapOutputModes of MapGenerator gen. std::string OpenNIMapGenerator::getMapOutputModeInfo(MapGenerator* gen){ // list all MapOutputModes XnUInt32 count = gen -> GetSupportedMapOutputModesCount(); XnMapOutputMode* modes = new XnMapOutputMode[count]; gen -> GetSupportedMapOutputModes(modes, count); // remove double entries std::vector cleaned; for(unsigned int i = 0; i < count; ++i){ bool added = false; for (unsigned int j = 0; j < cleaned.size(); ++j){ if(modes[i].nXRes == cleaned.at(j) -> nXRes && modes[i].nYRes == cleaned.at(j) -> nYRes && modes[i].nFPS == cleaned.at(j) -> nFPS){ added = true; break; } } if(!added) cleaned.push_back(modes + i); } // create info-string std::ostringstream ret; for(unsigned int i = 0; i < cleaned.size(); ++i){ ret << cleaned.at(i) -> nXRes << "x"; ret << cleaned.at(i) -> nYRes << "x"; ret << cleaned.at(i) -> nFPS << "fps"; if(i+1 < cleaned.size()){ ret << ","; } } // free allocated memory delete[] modes; DEBUG_LOG2("supported map output modes: " << ret.str()); return ret.str(); } // creates a string describing the current MapOutputMode std::string OpenNIMapGenerator::getCurrentMapOutputMode(MapGenerator* gen){ XnMapOutputMode mode; gen -> GetMapOutputMode(mode); std::ostringstream ret; ret << mode.nXRes << "x" << mode.nYRes << "x" << mode.nFPS << "fps"; DEBUG_LOG2("Map output mode: " << ret.str()); return ret.str(); } //############################################################################## //############################# OpenNIDepthGenerator ########################### //############################################################################## // Creates a DepthGenerator from Context OpenNIDepthGenerator::OpenNIDepthGenerator(int num) : m_DepthGenerator(NULL), m_Options(NULL) { XnStatus status = XN_STATUS_ERROR; m_DepthGenerator = new DepthGenerator(); NodeInfoList l; // enumerate depth generators OpenNIContext::EnumerateProductionTrees(XN_NODE_TYPE_DEPTH, NULL , l); int i = 0; // look for generator according to number num for (NodeInfoList::Iterator it = l.Begin(); it != l.End(); ++it, ++i){ if (i == num){ NodeInfo ni = *it; status = OpenNIContext::CreateProductionTree(ni, *m_DepthGenerator); } } if(i <= num){ // not enough generators std::ostringstream s; s << "Demanded depth generator nr " << num << " but only " << i << " available."; DEBUG_LOG(s.str()); throw ICLException(s.str()); } if (status != XN_STATUS_OK){ // error while creating depth generator std::ostringstream s; s << "Generator init error " << xnGetStatusString(status); DEBUG_LOG(s.str()); throw ICLException(s.str()); } // create GeneratorOptions for DepthGenerator m_Options = new DepthGeneratorOptions(m_DepthGenerator); status = m_DepthGenerator -> StartGenerating(); DEBUG_LOG("Done creating OpenNIIRGenerator: " << xnGetStatusString(status)); } // Destructor frees all resouurces OpenNIDepthGenerator::~OpenNIDepthGenerator(){ m_DepthGenerator -> StopGenerating(); DEBUG_LOG2("deleting depth gen"); ICL_DELETE(m_DepthGenerator); ICL_DELETE(m_Options); } // checks whether a new frame is available bool OpenNIDepthGenerator::newFrameAvailable(){ // get data from generator m_DepthGenerator -> GetMetaData(m_DepthMD); // check whether frame number has increased return (m_FrameId != m_DepthMD.FrameID()); } // grab function grabs an image bool OpenNIDepthGenerator::acquireImage(ImgBase* dest){ convertDepthImg(&m_DepthMD, dest -> as16s()); m_FrameId = m_DepthMD.FrameID(); return true; } // tells the type of the Generator OpenNIMapGenerator::Generators OpenNIDepthGenerator::getGeneratorType(){ return OpenNIMapGenerator::DEPTH; } // returns underlying xn::MapGenerator instance MapGenerator* OpenNIDepthGenerator::getMapGenerator(){ return m_DepthGenerator; } ImgBase* OpenNIDepthGenerator::initBuffer(){ return new Img16s(Size(0,0), formatGray); } // getter for MapGeneratorOptions MapGeneratorOptions* OpenNIDepthGenerator::getMapGeneratorOptions(){ return m_Options; } //############################################################################## //############################# OpenNIRgbGenerator ############################# //############################################################################## // Creates a RgbGenerator from Context OpenNIRgbGenerator::OpenNIRgbGenerator(int num) : m_RgbGenerator(NULL), m_Options(NULL) { XnStatus status; // create DepthGenerator. The Kinect rgb-generator did not work without // a depth generator being initialized beforehand. m_DepthGenerator = new DepthGenerator(); if (XN_STATUS_OK != (status = OpenNIContext::Create(m_DepthGenerator))){ std::string error = xnGetStatusString(status); DEBUG_LOG("DepthGenerator init error '" << error << "'"); throw new ICLException(error); } m_RgbGenerator = new ImageGenerator(); NodeInfoList l; // get all rgb-image generators OpenNIContext::EnumerateProductionTrees(XN_NODE_TYPE_IMAGE, NULL , l); int i = 0; // create generator according to num for (NodeInfoList::Iterator it = l.Begin(); it != l.End(); ++it, ++i){ if (i == num){ NodeInfo ni = *it; status = OpenNIContext::CreateProductionTree(ni, *m_RgbGenerator); } } if(i <= num){ // not enough generators found std::ostringstream s; s << "Demanded rgb generator nr " << num << " but only " << i << " available."; DEBUG_LOG(s.str()); throw ICLException(s.str()); } if (status != XN_STATUS_OK){ // error while creating std::string error = xnGetStatusString(status); DEBUG_LOG("ImageGenerator init error '" << error << "'"); throw new ICLException(error); } // create generator options m_Options = new ImageGeneratorOptions(m_RgbGenerator); status = m_RgbGenerator -> StartGenerating(); DEBUG_LOG("Done creating OpenNIRgbGenerator: " << xnGetStatusString(status)); } // Destructor frees all resouurces OpenNIRgbGenerator::~OpenNIRgbGenerator(){ m_RgbGenerator -> StopGenerating(); ICL_DELETE(m_RgbGenerator); ICL_DELETE(m_IrGenerator); ICL_DELETE(m_DepthGenerator); ICL_DELETE(m_Options); } // checks whether a new frame is available bool OpenNIRgbGenerator::newFrameAvailable(){ // get data from generator m_RgbGenerator -> GetMetaData(m_RgbMD); // check whether frame number has increased return (m_FrameId != m_RgbMD.FrameID()); } // grab function grabs an image bool OpenNIRgbGenerator::acquireImage(ImgBase* dest){ // get data and write to image if(m_RgbMD.PixelFormat() == XN_PIXEL_FORMAT_RGB24){ convertRGBImg(&m_RgbMD, dest->as8u()); } else if(m_RgbMD.PixelFormat() == XN_PIXEL_FORMAT_YUV422){ convertYuv422Img(&m_RgbMD, dest->as8u()); } else if(m_RgbMD.PixelFormat() == XN_PIXEL_FORMAT_GRAYSCALE_8_BIT){ convertGrayScale8Img(&m_RgbMD, dest->as8u()); } else { ERROR_LOG("Error: OpenNI Pixel Format '" << m_RgbMD.PixelFormat() << "' not supported." ); } m_FrameId = m_RgbMD.FrameID(); return true; } // tells the type of the Generator OpenNIMapGenerator::Generators OpenNIRgbGenerator::getGeneratorType(){ return OpenNIMapGenerator::RGB; } // returns underlying xn::MapGenerator instance MapGenerator* OpenNIRgbGenerator::getMapGenerator(){ return m_RgbGenerator; } Img8u* OpenNIRgbGenerator::initBuffer(){ return new Img8u(Size(0,0), formatRGB); } // getter for MapGeneratorOptions MapGeneratorOptions* OpenNIRgbGenerator::getMapGeneratorOptions(){ return m_Options; } //############################################################################## //############################# OpenNIIRGenerator ############################# //############################################################################## // Creates a IrGenerator from Context OpenNIIRGenerator::OpenNIIRGenerator(int num) : m_IrGenerator(NULL), m_Options(NULL) { XnStatus status = XN_STATUS_ERROR; m_IrGenerator = new IRGenerator(); NodeInfoList l; // enumerate ir generators OpenNIContext::EnumerateProductionTrees(XN_NODE_TYPE_IR, NULL , l); int i = 0; // create generator according to num for (NodeInfoList::Iterator it = l.Begin(); it != l.End(); ++it, ++i){ if (i == num){ NodeInfo ni = *it; status = OpenNIContext::CreateProductionTree(ni, *m_IrGenerator); } } if(i <= num){ // not enough generators std::ostringstream s; s << "Demanded ir generator nr " << num << " but only " << i << " available."; DEBUG_LOG(s.str()); throw ICLException(s.str()); } if (XN_STATUS_OK != status){ // error while creating generator std::string error = xnGetStatusString(status); DEBUG_LOG("IRGenerator init error '" << error << "'"); throw new ICLException(error); } // somehow my kinect did not create the ir images before setting it to // this MapOutputMode. XnMapOutputMode mo; mo.nFPS = 30; mo.nXRes = 640; mo.nYRes = 480; assertStatus(m_IrGenerator -> SetMapOutputMode(mo),false); // create generator options m_Options = new MapGeneratorOptions(m_IrGenerator); status = m_IrGenerator -> StartGenerating(); DEBUG_LOG("Done creating OpenNIIRGenerator: " << xnGetStatusString(status)); } // Destructor frees all resouurces OpenNIIRGenerator::~OpenNIIRGenerator(){ m_IrGenerator -> StopGenerating(); ICL_DELETE(m_IrGenerator); ICL_DELETE(m_Options); } // checks whether a new frame is available bool OpenNIIRGenerator::newFrameAvailable(){ // get data from generator m_IrGenerator -> GetMetaData(m_IrMD); // check whether frame number has increased return (m_FrameId != m_IrMD.FrameID()); } // grab function grabs an image bool OpenNIIRGenerator::acquireImage(ImgBase* dest){ // get data wnd write image convertIRImg(&m_IrMD, dest -> as16s()); m_FrameId = m_IrMD.FrameID(); return true; } // tells the type of the Generator OpenNIMapGenerator::Generators OpenNIIRGenerator::getGeneratorType(){ return OpenNIMapGenerator::IR; } // returns underlying xn::MapGenerator instance MapGenerator* OpenNIIRGenerator::getMapGenerator(){ return m_IrGenerator; } Img16s* OpenNIIRGenerator::initBuffer(){ return new Img16s(Size(0,0), formatGray); } // getter for MapGeneratorOptions MapGeneratorOptions* OpenNIIRGenerator::getMapGeneratorOptions(){ return m_Options; } //############################################################################## //############################# MapGeneratorOptions ############################ //############################################################################## // tells whether a MapOutputMode is supported by a MapGenerator bool isSupportedMapOutputMode(MapGenerator* gen, XnMapOutputMode* mode){ // list modes XnUInt32 count = gen -> GetSupportedMapOutputModesCount(); XnMapOutputMode* modes = new XnMapOutputMode[count]; gen -> GetSupportedMapOutputModes(modes, count); // check whether one is equivalent for(unsigned int i = 0; i < count; ++i){ if(modes[i].nXRes == mode->nXRes && modes[i].nYRes == mode->nYRes && modes[i].nFPS == mode->nFPS ){ return true; } } return false; } // sets the current MapOutputMode from string. void setCurrentMapOutputmode(MapGenerator* gen, const std::string &value){ // fill XnMapOutputMode instance from string char delimiter; XnMapOutputMode mode; std::stringstream t; t << value; t >> mode.nXRes; t >> delimiter; t >> mode.nYRes; t >> delimiter; t >> mode.nFPS; // when supported, set to new mode. if(isSupportedMapOutputMode(gen, &mode)){ //XnStatus st = gen -> SetMapOutputMode(mode); //DEBUG_LOG2(xnGetStatusString(st)); gen -> SetMapOutputMode(mode); } else { DEBUG_LOG2("mode " << value << " not supported."); } } // checks whether name is a GeneralIntCapability bool isGeneralIntCapability(const std::string &name){ if (name == XN_CAPABILITY_BRIGHTNESS || name == XN_CAPABILITY_CONTRAST || name == XN_CAPABILITY_HUE || name == XN_CAPABILITY_SATURATION || name == XN_CAPABILITY_SHARPNESS || name == XN_CAPABILITY_GAMMA || name == XN_CAPABILITY_COLOR_TEMPERATURE || name == XN_CAPABILITY_BACKLIGHT_COMPENSATION || name == XN_CAPABILITY_GAIN || name == XN_CAPABILITY_PAN || name == XN_CAPABILITY_TILT || name == XN_CAPABILITY_ROLL || name == XN_CAPABILITY_ZOOM || name == XN_CAPABILITY_EXPOSURE || name == XN_CAPABILITY_IRIS || name == XN_CAPABILITY_FOCUS || name == XN_CAPABILITY_LOW_LIGHT_COMPENSATION){ return true; } return false; } // gets the GeneralIntCapability corresponding to name. GeneralIntCapability getGeneralIntCapability(xn::MapGenerator* gen, const std::string &name){ if (name == XN_CAPABILITY_BRIGHTNESS){ return gen -> GetBrightnessCap(); } else if (name == XN_CAPABILITY_CONTRAST){ return gen -> GetContrastCap(); } else if (name == XN_CAPABILITY_HUE){ return gen -> GetHueCap(); } else if (name == XN_CAPABILITY_SATURATION){ return gen -> GetSaturationCap(); } else if (name == XN_CAPABILITY_SHARPNESS){ return gen -> GetSharpnessCap(); } else if (name == XN_CAPABILITY_GAMMA){ return gen -> GetGammaCap(); } else if (name == XN_CAPABILITY_COLOR_TEMPERATURE){ return gen -> GetWhiteBalanceCap(); } else if (name == XN_CAPABILITY_BACKLIGHT_COMPENSATION){ return gen -> GetBacklightCompensationCap(); } else if (name == XN_CAPABILITY_GAIN){ return gen -> GetGainCap(); } else if (name == XN_CAPABILITY_PAN){ return gen -> GetPanCap(); } else if (name == XN_CAPABILITY_TILT){ return gen -> GetTiltCap(); } else if (name == XN_CAPABILITY_ROLL){ return gen -> GetRollCap(); } else if (name == XN_CAPABILITY_ZOOM){ return gen -> GetZoomCap(); } else if (name == XN_CAPABILITY_EXPOSURE){ return gen -> GetExposureCap(); } else if (name == XN_CAPABILITY_IRIS){ return gen -> GetIrisCap(); } else if (name == XN_CAPABILITY_FOCUS){ return gen -> GetFocusCap(); } else if (name == XN_CAPABILITY_LOW_LIGHT_COMPENSATION){ return gen -> GetLowLightCompensationCap(); } throw ICLException("unknown int capability"); } // checks whether the GeneralIntCapability supports auto-mode bool isGeneralIntAutoSupported(GeneralIntCapability &cap){ XnInt32 min, max, step, def; XnBool sauto; cap.GetRange(min, max, step, def, sauto); return sauto; } // sets a GeneralIntCapability to Default. void setGeneralIntCapabilityDefault(GeneralIntCapability cap){ XnInt32 min, max, step, def; XnBool sauto; cap.GetRange(min, max, step, def, sauto); cap.Set(def); } // returns the string-value of a GeneralIntCapability std::string generalIntCapabilityValue(GeneralIntCapability cap){ std::ostringstream ret; ret << cap.Get(); return ret.str(); } // checks whether property is an auto-GeneralIntCapability bool isGeneralIntAutoCapability(const std::string &property){ if (property.size() <= 4){ // Auto capabilities have 'Auto' prepended. return false; } std::string prop = property.substr(4); if (!isGeneralIntCapability(prop)){ return false; } return true; } // sets a GeneralIntCapability from name and value string. bool setGeneralIntCapability(xn::MapGenerator* gen, const std::string &property, const std::string &value){ // set when its a GeneralIntCapability if(isGeneralIntCapability(property)){ getGeneralIntCapability(gen, property).Set(parse(value)); return true; } // when its an auto-capability set accordingly if(isGeneralIntAutoCapability(property)){ if(value == "On"){ getGeneralIntCapability(gen, property).Set(XN_AUTO_CONTROL); } else { GeneralIntCapability cap = getGeneralIntCapability(gen, property); setGeneralIntCapabilityDefault(cap); } return true; } return false; } // checks whether property is a cropping property bool isCropping(const std::string &property){ if (property == "Cropping Enabled" || property == "Cropping offset X" || property == "Cropping offset Y" || property == "Cropping size X" || property == "Cropping size Y"){ return true; } return false; } // returns the string-value of the andi-flicker capability of MapGenerator std::string antiFlickerCapabilityValue(xn::MapGenerator* gen){ // yeah anti-flicker is power-line-freq... XnPowerLineFrequency curr = gen -> GetAntiFlickerCap().GetPowerLineFrequency(); if(curr == XN_POWER_LINE_FREQUENCY_OFF){ return "Power line frequency OFF"; } else if (curr == XN_POWER_LINE_FREQUENCY_50_HZ){ return "Power line frequency 50Hz"; } else if (curr == XN_POWER_LINE_FREQUENCY_60_HZ){ return "Power line frequency 60Hz"; } else { return "error"; } } // sets anti flicker capability from string void antiFlickerCapabilitySet(xn::MapGenerator* gen, std::string value){ AntiFlickerCapability cap = gen -> GetAntiFlickerCap(); if(value == "Power line frequency OFF"){ cap.SetPowerLineFrequency(XN_POWER_LINE_FREQUENCY_OFF); } else if (value == "Power line frequency 50Hz"){ cap.SetPowerLineFrequency(XN_POWER_LINE_FREQUENCY_50_HZ); } else if (value == "Power line frequency 60Hz"){ cap.SetPowerLineFrequency(XN_POWER_LINE_FREQUENCY_60_HZ); } } // sets a cropping property from name and value string void setCropping(xn::MapGenerator* gen, const std::string &property, const std::string &value) { XnCropping crop; gen -> GetCroppingCap().GetCropping(crop); // go through all cropping properties and set the one named by property-string if (property == "Cropping Enabled"){ crop.bEnabled = parse(value); } else { unsigned int val = parse(value); XnMapOutputMode mode; gen -> GetMapOutputMode(mode); if (property == "Cropping offset X"){ if(val + crop.nXSize <= mode.nXRes){ crop.nXOffset = val; } } else if (property == "Cropping offset Y"){ if(val + crop.nYSize <= mode.nYRes){ crop.nYOffset = val; } } else if (property == "Cropping size X"){ if(val + crop.nXOffset <= mode.nXRes){ crop.nXSize = val; } } else if (property == "Cropping size Y"){ if(val + crop.nXOffset <= mode.nYRes){ crop.nYSize = val; } } } gen -> GetCroppingCap().SetCropping(crop); } // sets alternative viewpoit void alternativeViewPiontCapabilitySet(xn::MapGenerator* gen, const std::string &value, std::map &pn_map) { // get alt. viewpoint capapility AlternativeViewPointCapability avc = gen -> GetAlternativeViewPointCap(); ProductionNode n; XnStatus status = XN_STATUS_OK; // if self, reset viewpoint to default. if(value == "self"){ status = avc.ResetViewPoint(); } else { // get the ProductionNode named by value from Map std::map::iterator it = pn_map.find(value); if (it != pn_map.end()) { if(avc.IsViewPointSupported(pn_map[value])){ // set alt viewpoint. status = avc.SetViewPoint(pn_map[value]); } if(status != XN_STATUS_OK){ DEBUG_LOG("Setting Viewpoint returned error: " << xnGetStatusString(status)); } } else { DEBUG_LOG("ProductinNode " << value << " for alt. Viewpoint not found."); } } } // creates string representation of alt. viewpoint capability value std::string alternativeViewPiontCapabilityValue(xn::MapGenerator* gen, std::map &pn_map) { AlternativeViewPointCapability avc = gen -> GetAlternativeViewPointCap(); std::map::iterator it; for(it = pn_map.begin(); it != pn_map.end(); ++it){ if(avc.IsViewPointAs((*it).second)){ return (*it).first; } } return "self"; } // creates info string for alt viewpoint capability std::string alternativeViewPiontCapabilityInfo(xn::MapGenerator* gen, std::map &pn_map) { AlternativeViewPointCapability avc = gen -> GetAlternativeViewPointCap(); std::ostringstream ret; ret << "self,"; std::map::iterator it; for(it = pn_map.begin(); it != pn_map.end(); ++it){ if(avc.IsViewPointSupported((*it).second)){ ret << (*it).first << ","; } } return ret.str(); } // fills a Map with available ProductionNodes. used for altern. viewpoint. void fillProductionNodeMap(std::map &pn_map) { ProductionNode n; XnStatus status = XN_STATUS_OK; NodeInfoList l; // RGB OpenNIContext::EnumerateProductionTrees(XN_NODE_TYPE_IMAGE, NULL , l); int i = 0; for (NodeInfoList::Iterator it = l.Begin(); it != l.End(); ++it, ++i){ std::ostringstream tmp; tmp << "rgb"; if(i) tmp << i; NodeInfo ni = *it; status = OpenNIContext::CreateProductionTree(ni, n); if(status == XN_STATUS_OK){ pn_map[tmp.str()] = n; } else { DEBUG_LOG("error while creating Production tree: " << xnGetStatusString(status)); } } // DEPTH OpenNIContext::EnumerateProductionTrees(XN_NODE_TYPE_DEPTH, NULL , l); i = 0; for (NodeInfoList::Iterator it = l.Begin(); it != l.End(); ++it, ++i){ std::ostringstream tmp; tmp << "depth"; if(i) tmp << i; NodeInfo ni = *it; status = OpenNIContext::CreateProductionTree(ni, n); if(status == XN_STATUS_OK){ pn_map[tmp.str()] = n; } else { DEBUG_LOG("error while creating Production tree: " << xnGetStatusString(status)); } } // IR OpenNIContext::EnumerateProductionTrees(XN_NODE_TYPE_IR, NULL , l); i = 0; for (NodeInfoList::Iterator it = l.Begin(); it != l.End(); ++it, ++i){ std::ostringstream tmp; tmp << "ir"; if(i) tmp << i; NodeInfo ni = *it; status = OpenNIContext::CreateProductionTree(ni, n); if(status == XN_STATUS_OK){ pn_map[tmp.str()] = n; } else { DEBUG_LOG("error while creating Production tree: " << xnGetStatusString(status)); } } // AUDIO OpenNIContext::EnumerateProductionTrees(XN_NODE_TYPE_AUDIO, NULL , l); i = 0; for (NodeInfoList::Iterator it = l.Begin(); it != l.End(); ++it, ++i){ std::ostringstream tmp; tmp << "audio"; if(i) tmp << i; NodeInfo ni = *it; status = OpenNIContext::CreateProductionTree(ni, n); if(status == XN_STATUS_OK){ pn_map[tmp.str()] = n; } else { DEBUG_LOG("error while creating Production tree: " << xnGetStatusString(status)); } } } // fills capabilities list. MapGeneratorOptions::MapGeneratorOptions(xn::MapGenerator* generator) : m_Generator(generator) { fillProductionNodeMap(m_ProductionNodeMap); //Configurable addProperty("map output mode", "menu", OpenNIMapGenerator::getMapOutputModeInfo(m_Generator), OpenNIMapGenerator::getCurrentMapOutputMode(m_Generator), 0, "The map output mode of the used MapGenerator"); //fillProductionNodeMap(m_Generator -> GetContext(), m_ProductionNodeMap); if(m_Generator -> IsCapabilitySupported(XN_CAPABILITY_CROPPING)){ // get max map output in every for x and y unsigned int x = 0; unsigned int y = 0; XnUInt32 count = m_Generator -> GetSupportedMapOutputModesCount(); XnMapOutputMode* modes = new XnMapOutputMode[count]; m_Generator -> GetSupportedMapOutputModes(modes, count); for(unsigned int i = 0; i < count; ++i){ x = (modes[i].nXRes > x) ? modes[i].nXRes : x; y = (modes[i].nYRes > y) ? modes[i].nYRes : y; } // cropping info XnCropping crop; m_Generator -> GetCroppingCap().GetCropping(crop); addProperty("Cropping Enabled", "flag", "", crop.bEnabled, 0, "Whether cropping should be used." ); addProperty("Cropping offset X", "range", str(SteppingRange(0, x, 1)), crop.nXOffset, 0, "The X offset of the cropping from (0,0)." "Needs to be set regarding cropping size and image size." ); addProperty("Cropping offset Y", "range", str(SteppingRange(0, y, 1)), crop.nYOffset, 0, "The Y offset of the cropping from (0,0). " "Needs to be set regarding cropping size and image size." ); addProperty("Cropping size X", "range", str(SteppingRange(0, x, 1)), crop.nXSize, 0, "The X size cropped image. Needs to be set " "regarding cropping size and image size." ); addProperty("Cropping size Y", "range", str(SteppingRange(0, y, 1)), crop.nYSize, 0, "The Y size cropped image. Needs to be set " "regarding cropping size and image size." ); } if(m_Generator -> IsCapabilitySupported(XN_CAPABILITY_ANTI_FLICKER)){ addProperty(XN_CAPABILITY_ANTI_FLICKER, "menu", "Power line frequency OFF," "Power line frequency 50Hz,Power line frequency 60Hz", antiFlickerCapabilityValue(m_Generator), 0, "" ); } if(m_Generator -> IsCapabilitySupported(XN_CAPABILITY_ALTERNATIVE_VIEW_POINT)){ addProperty(XN_CAPABILITY_ALTERNATIVE_VIEW_POINT, "menu", alternativeViewPiontCapabilityInfo(m_Generator, m_ProductionNodeMap), alternativeViewPiontCapabilityValue(m_Generator, m_ProductionNodeMap), 0, "" ); } if(m_Generator -> IsCapabilitySupported(XN_CAPABILITY_MIRROR)){ addProperty(XN_CAPABILITY_MIRROR, "flag", "", m_Generator -> GetMirrorCap().IsMirrored(), 0, "Flips the image vertically." ); } addGeneralIntProperty(XN_CAPABILITY_BRIGHTNESS); addGeneralIntProperty(XN_CAPABILITY_CONTRAST); addGeneralIntProperty(XN_CAPABILITY_HUE); addGeneralIntProperty(XN_CAPABILITY_SATURATION); addGeneralIntProperty(XN_CAPABILITY_SHARPNESS); addGeneralIntProperty(XN_CAPABILITY_GAMMA); addGeneralIntProperty(XN_CAPABILITY_COLOR_TEMPERATURE); addGeneralIntProperty(XN_CAPABILITY_BACKLIGHT_COMPENSATION); addGeneralIntProperty(XN_CAPABILITY_GAIN); addGeneralIntProperty(XN_CAPABILITY_PAN); addGeneralIntProperty(XN_CAPABILITY_TILT); addGeneralIntProperty(XN_CAPABILITY_ROLL); addGeneralIntProperty(XN_CAPABILITY_ZOOM); addGeneralIntProperty(XN_CAPABILITY_EXPOSURE); addGeneralIntProperty(XN_CAPABILITY_IRIS); addGeneralIntProperty(XN_CAPABILITY_FOCUS); addGeneralIntProperty(XN_CAPABILITY_LOW_LIGHT_COMPENSATION); Configurable::registerCallback( utils::function(this,&MapGeneratorOptions::processPropertyChange)); } // callback for changed configurable properties void MapGeneratorOptions::processPropertyChange( const utils::Configurable::Property &prop) { if(isCropping(prop.name)){ setCropping(m_Generator, prop.name, prop.value); } else if (prop.name == XN_CAPABILITY_ANTI_FLICKER){ antiFlickerCapabilitySet(m_Generator, prop.value); } else if (prop.name == XN_CAPABILITY_ALTERNATIVE_VIEW_POINT){ alternativeViewPiontCapabilitySet(m_Generator, prop.value, m_ProductionNodeMap); } else if (prop.name == XN_CAPABILITY_MIRROR){ m_Generator -> GetMirrorCap().SetMirror(parse(prop.value)); } else if (setGeneralIntCapability(m_Generator, prop.name, prop.value)){ // nothing to do setting is done in condition } else if (prop.name == "map output mode"){ setCurrentMapOutputmode(m_Generator, prop.value); } } // adds a GeneralIntCapability as property void MapGeneratorOptions::addGeneralIntProperty(const std::string name) { // only add if supported if(!m_Generator -> IsCapabilitySupported(name.c_str())){ return; } GeneralIntCapability cap = getGeneralIntCapability(m_Generator, name); // when auto is supported add the auto-version too. if(isGeneralIntAutoSupported(cap)){ std::ostringstream tmp; tmp << "Auto" << name; addProperty(tmp.str(),"flag", "", generalIntCapabilityValue(cap), 0, "Automaticly set corresponding porperty."); } // get info XnInt32 min, max, step, def; XnBool sauto; cap.GetRange(min, max, step, def, sauto); std::ostringstream inf; inf << "[" << min << "," << max << "]:" << step; addProperty(name, "range", inf.str(), cap.Get(), 0, ""); } //############################################################################## //############################# DepthGeneratorOptions ########################## //############################################################################## // constructor DepthGeneratorOptions::DepthGeneratorOptions(xn::DepthGenerator* generator) : MapGeneratorOptions(generator), m_DepthGenerator(generator) { addProperty("max depth", "info", "", m_DepthGenerator -> GetDeviceMaxDepth(), 0, "The maximum depth value of this grabber."); // field of view XnFieldOfView fov; m_DepthGenerator -> GetFieldOfView(fov); addProperty("field of view X", "info", "", fov.fHFOV, 0, "Horizontal field of view."); addProperty("field of view Y", "info", "", fov.fVFOV, 0, "Vertical field of view."); XnUInt64 gmcMode = 0; m_DepthGenerator->GetIntProperty("GmcMode", gmcMode); addProperty("GmcMode", "flag", "", gmcMode, 0, "GmcMode"); Configurable::registerCallback( utils::function(this,&DepthGeneratorOptions::processPropertyChange)); } // callback for changed configurable properties void DepthGeneratorOptions::processPropertyChange(const utils::Configurable::Property &prop){ if(prop.name == "GmcMode"){ if (prop.value == "false"){ assertStatus(m_DepthGenerator->SetIntProperty("GmcMode", 0)); } else { assertStatus(m_DepthGenerator->SetIntProperty("GmcMode", 1)); } } } //############################################################################## //############################# ImageGeneratorOptions ########################## //############################################################################## // constructor ImageGeneratorOptions::ImageGeneratorOptions(xn::ImageGenerator* generator) : MapGeneratorOptions(generator), m_ImageGenerator(generator) { // construnct Pixel Format - format string std::ostringstream format; if (m_ImageGenerator -> IsPixelFormatSupported(XN_PIXEL_FORMAT_RGB24)){ format << "rgb24,"; } if (m_ImageGenerator -> IsPixelFormatSupported(XN_PIXEL_FORMAT_YUV422)){ format << "yuv422,"; } if (m_ImageGenerator -> IsPixelFormatSupported(XN_PIXEL_FORMAT_GRAYSCALE_8_BIT)){ format << "grayscale8,"; } if (m_ImageGenerator -> IsPixelFormatSupported(XN_PIXEL_FORMAT_GRAYSCALE_16_BIT)){ format << "grayscale16,"; } if (m_ImageGenerator -> IsPixelFormatSupported(XN_PIXEL_FORMAT_MJPEG)){ format << "mjpeg,"; } std::string value = ""; XnPixelFormat pf = m_ImageGenerator -> GetPixelFormat(); switch(pf){ case XN_PIXEL_FORMAT_RGB24: value = "rgb24"; break; case XN_PIXEL_FORMAT_YUV422: value = "yuv422"; break; case XN_PIXEL_FORMAT_GRAYSCALE_8_BIT: value = "grayscale8"; break; case XN_PIXEL_FORMAT_GRAYSCALE_16_BIT: value = "grayscale16"; break; case XN_PIXEL_FORMAT_MJPEG: value = "mjpeg"; break; default: DEBUG_LOG("Unknown Pixel Format " << m_ImageGenerator -> GetPixelFormat()); value = "rgb24"; } addProperty("Pixel Format", "menu", format.str(), value, 0, "The pixel format of the aquired image."); Configurable::registerCallback( utils::function(this,&ImageGeneratorOptions::processPropertyChange)); } // callback for changed configurable properties void ImageGeneratorOptions::processPropertyChange(const utils::Configurable::Property &prop){ if(prop.name == "Pixel Format"){ if (prop.value == "rgb24"){ if (m_ImageGenerator -> IsPixelFormatSupported(XN_PIXEL_FORMAT_RGB24)){ assertStatus(m_ImageGenerator -> SetPixelFormat(XN_PIXEL_FORMAT_RGB24),false); } } if (prop.value == "yuv422"){ if (m_ImageGenerator -> IsPixelFormatSupported(XN_PIXEL_FORMAT_YUV422)){ assertStatus(m_ImageGenerator -> SetPixelFormat(XN_PIXEL_FORMAT_YUV422),false); } } if (prop.value == "grayscale8"){ if (m_ImageGenerator -> IsPixelFormatSupported(XN_PIXEL_FORMAT_GRAYSCALE_8_BIT)){ assertStatus(m_ImageGenerator -> SetPixelFormat(XN_PIXEL_FORMAT_GRAYSCALE_8_BIT),false); } } if (prop.value == "grayscale16"){ if (m_ImageGenerator -> IsPixelFormatSupported(XN_PIXEL_FORMAT_GRAYSCALE_16_BIT)){ assertStatus(m_ImageGenerator -> SetPixelFormat(XN_PIXEL_FORMAT_GRAYSCALE_16_BIT),false); } } if (prop.value == "mjpeg"){ if (m_ImageGenerator -> IsPixelFormatSupported(XN_PIXEL_FORMAT_MJPEG)){ assertStatus(m_ImageGenerator -> SetPixelFormat(XN_PIXEL_FORMAT_MJPEG),false); } } } }