/******************************************************************** ** 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 : ICLFilter/src/WarpOp.cpp ** ** Module : ICLFilter ** ** 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 using namespace icl::utils; using namespace icl::core; namespace icl{ namespace filter{ template T interpolate_pixel_nn(float x, float y, const Channel &src){ if(x < 0) return T(0); return src(round(x),round(y)); } template T interpolate_pixel_lin(float x, float y, const Channel &src){ float fX0 = x - floor(x), fX1 = 1.0 - fX0; float fY0 = y - floor(y), fY1 = 1.0 - fY0; int xll = (int) x; int yll = (int) y; const T* pLL = &src(xll,yll); float a = *pLL; // a b float b = *(++pLL); // c d pLL += src.getWidth(); float d = *pLL; float c = *(--pLL); return fX1 * (fY1*a + fY0*c) + fX0 * (fY1*b + fY0*d); } template &src)> static inline void apply_warp_2(const Channel32f warpMap[2], const Channel &src, Channel &dst, const Size &size){ for(int x=0;x static void apply_warp(const Channel32f warpMap[2], const Img&src, Img &dst, scalemode mode){ for(int c=0;c s = src[c]; Channel d = dst[c]; if(mode == interpolateNN){ apply_warp_2 >(warpMap,s,d,s.getSize()); }else if(mode == interpolateLIN){ apply_warp_2 >(warpMap,s,d,s.getSize()); }else{ ERROR_LOG("region average interpolation mode does not work here!"); return; } } } #ifdef HAVE_IPP template<> void apply_warp(const Channel32f warpMap[2], const Img &src, Img &dst, scalemode mode){ for(int c=0;c void apply_warp(const Channel32f warpMap[2], const Img &src, Img &dst, scalemode mode){ for(int c=0;c and #endif void prepare_warp_table_inplace(Img32f &warpMap){ const Rect r = warpMap.getImageRect(); Channel32f cs[2]; warpMap.extractChannels(cs); const Size size = warpMap.getSize(); for(int x=0;xhasFullROI()){ ERROR_LOG("warp op does currently not support ROI"); return; } if(!UnaryOp::prepare(dst,src->getDepth(),src->getSize(), src->getFormat(),src->getChannels(), src->getROI(),src->getTime())){ ERROR_LOG("unable to prepare destination image (returning)"); return; } Channel32f cwm[2]; if(src->getSize() != m_warpMap.getSize()){ if(m_allowWarpMapScaling){ if(m_scaledWarpMap.getSize() != src->getSize()){ m_scaledWarpMap.setSize(src->getSize()); m_warpMap.scaledCopy(&m_scaledWarpMap); prepare_warp_table_inplace(m_scaledWarpMap); } m_scaledWarpMap.extractChannels(cwm); }else{ ERROR_LOG("warp map size and image size are not equal\n" "warp map can be scaled using\n" "setAllowWarpMapScaling(true)"); return; } }else{ m_warpMap.extractChannels(cwm); } switch(src->getDepth()){ #define ICL_INSTANTIATE_DEPTH(D) \ case depth##D: \ apply_warp(cwm,*src->asImg(), \ *(*dst)->asImg(),m_scaleMode); \ break; ICL_INSTANTIATE_ALL_DEPTHS; default: ICL_INVALID_DEPTH; #undef ICL_INSTANTIATE_DEPTH } } } // namespace filter }