/******************************************************************** ** 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 : ICLFilter/src/ICLFilter/ConvolutionKernel.cpp ** ** Module : ICLFilter ** ** Authors: Christof Elbrechter ** ** ** ** ** ** 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 #ifdef WIN32 #include #endif using namespace icl::utils; namespace icl{ namespace filter{ namespace{ template inline T* deepcopy(const T*src, int dim){ T *cpy = new T[dim]; std::copy(src,src+dim,cpy); return cpy; } template inline T* save_deepcopy(const T*src, int dim){ if(!src || !dim) return 0; T *cpy = new T[dim]; std::copy(src,src+dim,cpy); return cpy; } bool is_convertable_to_int (float *data, int len){ // tests if an element of the given float* has decimals // if it does: return 0, else 1 for(int i=0;i 0,InvalidSizeException(__FUNCTION__)); if(deepCopy){ idata = deepcopy(data,getDim()); }else{ idata = data; } isnull = !idata; } ConvolutionKernel::ConvolutionKernel(float *data, const Size &size, bool deepCopy) throw (InvalidSizeException): size(size),fdata(0),idata(0),factor(1),isnull(false),owned(deepCopy),ft(custom){ ICLASSERT_THROW(getDim() > 0,InvalidSizeException(__FUNCTION__)); if(deepCopy){ fdata = deepcopy(data,getDim()); }else{ fdata = data; } isnull = !fdata; } ConvolutionKernel::ConvolutionKernel(fixedType t, bool useFloats): size(t>9 ? Size(5,5) : Size(3,3)),fdata(0),isnull(false),owned(false),ft(t){ switch(t){ case gauss3x3: idata = GAUSS_3x3; break; case gauss5x5: idata = GAUSS_5x5; break; case sobelX3x3: idata = SOBEL_X_3x3; break; case sobelX5x5: idata = SOBEL_X_5x5; break; case sobelY3x3: idata = SOBEL_Y_3x3; break; case sobelY5x5: idata = SOBEL_Y_5x5; break; case laplace3x3: idata = LAPLACE_3x3; break; case laplace5x5: idata = LAPLACE_5x5; break; default: throw ICLException("invalid fixed convolution kernel type"); } factor = *idata++; if(useFloats){ toFloat(); } } ConvolutionKernel &ConvolutionKernel::operator=(const ConvolutionKernel &other){ if(owned){ ICL_DELETE(idata); ICL_DELETE(fdata); } size = other.size; fdata = 0; idata = 0; factor = other.factor; isnull = other.isnull; owned = other.owned; ft = other.ft; if(owned){ if(other.fdata)fdata = deepcopy(other.fdata,getDim()); if(other.idata)idata = deepcopy(other.idata,getDim()); }else{ fdata = other.fdata; idata = other.idata; } return *this; } ConvolutionKernel::~ConvolutionKernel() { if(owned){ ICL_DELETE(idata); ICL_DELETE(fdata); } } void ConvolutionKernel::toFloat(){ if(idata && !fdata){ fdata = new float[getDim()]; std::transform(idata,idata+getDim(),fdata,std::bind2nd(std::divides(),factor)); if(owned){ ICL_DELETE(idata); }else{ idata = 0; } owned = true; factor = 1.0; } } void ConvolutionKernel::toInt(bool force){ if(fdata && !idata){ if(force || is_convertable_to_int(fdata,getDim())){ idata = new int[getDim()]; std::copy(fdata,fdata+getDim(),idata); if(owned){ ICL_DELETE(fdata); }else{ fdata = 0; } owned = true; } } } void ConvolutionKernel::detach(){ if(!owned){ if(idata) idata = deepcopy(idata,getDim()); if(fdata) fdata = deepcopy(fdata,getDim()); } } } // namespace filter }