/******************************************************************** ** Image Component Library (ICL) ** ** ** ** Copyright (C) 2006-2012 CITEC, University of Bielefeld ** ** Neuroinformatics Group ** ** Website: www.iclcv.org and ** ** http://opensource.cit-ec.de/projects/icl ** ** ** ** File : ICLIO/src/Grabber.cpp ** ** Module : ICLIO ** ** Authors: Christof Elbrechter ** ** ** ** ** ** Commercial License ** ** ICL can be used commercially, please refer to our website ** ** www.iclcv.org for more details. ** ** ** ** GNU General Public License Usage ** ** Alternatively, this file may be used under the terms of the ** ** GNU General Public License version 3.0 as published by the ** ** Free Software Foundation and appearing in the file LICENSE.GPL ** ** included in the packaging of this file. Please review the ** ** following information to ensure the GNU General Public License ** ** version 3.0 requirements will be met: ** ** http://www.gnu.org/copyleft/gpl.html. ** ** ** ** 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 using namespace std; namespace icl{ namespace { inline bool inList(const string &s, const std::vector &vec){ return find(vec.begin(),vec.end(),s) != vec.end(); } } struct Grabber::Data{ Size desiredSize; format desiredFormat; depth desiredDepth; Converter converter; ImgBase *image; WarpOp *warp; Mutex callbackMutex; std::vector callbacks; }; Grabber::Grabber(): data(new Data){ data->desiredSize = Size::null; data->desiredFormat = (format)-1; data->desiredDepth = (depth)-1; data->image = 0; data->warp = 0; } Grabber::~Grabber() { ICL_DELETE( data->image ); ICL_DELETE( data->warp ); ICL_DELETE( data ); } void Grabber::useDesired(depth d, const Size &size, format fmt){ useDesired(d); useDesired(size);useDesired(fmt); } void Grabber::ignoreDesired(){ ignoreDesired(); ignoreDesired(); ignoreDesired(); } void Grabber::setDesiredFormatInternal(format fmt){ data->desiredFormat = fmt; } void Grabber::setDesiredSizeInternal(const Size &size){ data->desiredSize = size; } void Grabber::setDesiredDepthInternal(depth d){ data->desiredDepth = d; } format Grabber::getDesiredFormatInternal() const{ return data->desiredFormat; } depth Grabber::getDesiredDepthInternal() const{ return data->desiredDepth; } Size Grabber::getDesiredSizeInternal() const{ return data->desiredSize; } bool Grabber::supportsProperty(const std::string &property){ return inList(property,getPropertyList()); } string Grabber::translateSteppingRange(const SteppingRange& range){ return str(range); } SteppingRange Grabber::translateSteppingRange(const string &rangeStr){ return parse >(rangeStr); } template static std::string translate_any_vec(const std::vector &v){ std::ostringstream s; s << "{"; for(unsigned int i=0;i static std::vector translate_any_string(const std::string &v){ std::vector vs = tok(v,","); std::vector ts(vs.size()); for(unsigned int i=0; i(strip_quotes(vs[i])); } return ts; } string Grabber::translateDoubleVec(const vector &v){ return translate_any_vec(v); } vector Grabber::translateDoubleVec(const string &s){ return translate_any_string(s); } string Grabber::translateStringVec(const vector &v){ return translate_any_vec(v); } vector Grabber::translateStringVec(const string &v){ return translate_any_string(v); } const ImgBase *Grabber::grab(ImgBase **ppoDst){ const ImgBase *acquired = acquireImage(); // todo, on which image is the warping applied ? // on the aqcuired image or on the adapte image? // for now, we use the adapted which seem to make // much more sence const ImgBase *adapted = adaptGrabResult(acquired,data->warp ? 0 : ppoDst); if(data->warp){ if(ppoDst){ data->warp->apply(adapted, ppoDst); return *ppoDst; }else{ return data->warp->apply(adapted); } }else{ return adapted; } } void Grabber::enableUndistortion(const ImageUndistortion &udist){ enableUndistortion(udist.createWarpMap());//warpMap); } void Grabber::enableUndistortion(const std::string &filename){ enableUndistortion(ImageUndistortion(filename)); } void Grabber::enableUndistortion(const ProgArg &pa){ enableUndistortion(icl::pa(pa.getID(),0).as()); } void Grabber::setUndistortionInterpolationMode(scalemode mode){ if(data->warp){ data->warp->setScaleMode(mode); }else { WARNING_LOG("cannot set undistortion interpolation mode if distortion was not disabled before (skipped)!"); } } bool Grabber::isUndistortionEnabled() const{ return data->warp; } void Grabber::enableUndistortion(const Img32f &warpMap){ if(!data->warp){ data->warp = new WarpOp; } data->warp->setWarpMap(warpMap); data->warp->setScaleMode(interpolateLIN); } void Grabber::disableUndistortion(){ ICL_DELETE(data->warp); } const ImgBase *Grabber::adaptGrabResult(const ImgBase *src, ImgBase **dst){ bool adaptDepth = desiredUsed() && (getDesired() != src->getDepth()); bool adaptSize = desiredUsed() && (getDesired() != src->getSize()); bool adaptFormat = desiredUsed() && (getDesired() != src->getFormat()); if(adaptDepth || adaptSize || adaptFormat){ if(!dst){ dst = &data->image; } ensureCompatible(dst, adaptDepth ? getDesired() : src->getDepth(), adaptSize ? getDesired() : src->getSize(), adaptFormat ? getDesired() : src->getFormat()); data->converter.apply(src,*dst); return *dst; }else{ if(dst){ src->deepCopy(dst); return *dst; }else{ return src; } } } static std::vector filter_unstable_params(const std::vector ps){ std::vector fs; fs.reserve(ps.size()); static std::string unstable[6]={ "trigger-from-software", "trigger-mode", "trigger-polarity", "trigger-power", "trigger-source", "iso-speed" }; for(unsigned int i=0;i ps = get_io_property_list(); if(skipUnstable){ ps = filter_unstable_params(ps); } // f["config.property-list"] = cat(ps,","); this is no longer needed! if(writeDesiredParams){ f.setPrefix("config.desired-params."); f["size"] = desiredUsed() ? str(getDesired()) : str("any"); f["format"] = desiredUsed() ? str(getDesired()) : str("any"); f["depth"] = desiredUsed() ? str(getDesired()) : str("any"); } f.setPrefix("config.properties."); for(unsigned int i=0;i psSupported = get_io_property_list(); if(skipUnstable){ psSupported = filter_unstable_params(psSupported); } f.setPrefix("config.properties."); for(int x=0;x<2;++x){ // do it twice for beeing shure all properties set correctly for(unsigned int i=0;i() == "any"){ useDesired(f["size"]); }else{ ignoreDesired(); } if(f["format"].as() == "any"){ useDesired(f["format"]); }else{ ignoreDesired(); } if(f["depth"].as() == "any"){ useDesired(f["depth"]); }else{ ignoreDesired(); } }catch(...){ std::cerr << "Warning: no desired params were found in given property file" << std::endl; } } } const Img32f *Grabber::getUndistortionWarpMap() const{ return data->warp ? &data->warp->getWarpMap() : 0; } void Grabber::registerCallback(Grabber::callback cb){ Mutex::Locker lock(data->callbackMutex); data->callbacks.push_back(cb); } void Grabber::removeAllCallbacks(){ Mutex::Locker lock(data->callbackMutex); data->callbacks.clear(); } void Grabber::notifyNewImageAvailable(const ImgBase *image){ Mutex::Locker lock(data->callbackMutex); for(size_t i=0;icallbacks.size();++i){ data->callbacks[i](image); } } }