/******************************************************************** ** 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/MotionSensitiveTemporalSmoothing.cpp ** ** Module : ICLFilter ** ** Authors: Andre Ueckermann ** ** ** ** ** ** 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. ** ** ** *********************************************************************/ #define __CL_ENABLE_EXCEPTIONS //enables openCL error catching #include #include #include #ifdef HAVE_OPENCL #include #endif using namespace icl::utils; using namespace icl::core; namespace icl{ namespace filter{ #ifdef HAVE_OPENCL static char timeSmoothingKernel[] = "__kernel void \n" "temporalSmoothingFloat(__global float const * inputImages, __global float * outputImage, int const filterSize, int const imgCount, int const w, int const h, int const difference, int const nullvalue, __global float * motionImage) \n" "{ \n" " size_t id = get_global_id(0); \n" " int count=0; \n" " float value=0; \n" " float min=100000; \n" " float max=0; \n" " for(int i=0; imax) max=inputImages[i*w*h+id]; \n" " } \n" " } \n" " if(count==0){ \n" " outputImage[id]=nullvalue; \n" " motionImage[id]=0.0; \n" " }else{ \n" " if((max-min)>difference){ \n" " outputImage[id]=inputImages[(imgCount-1)*w*h+id]; \n" " motionImage[id]=255.0; \n" " }else{ \n" " outputImage[id]=value/(float)count; \n" " motionImage[id]=0.0; \n" " } \n" " } \n" "} \n" "__kernel void \n" "temporalSmoothingChar(__global uchar const * inputImages, __global uchar * outputImage, int const filterSize, int const imgCount, int const w, int const h, int difference, int nullvalue, __global float * motionImage) \n" "{ \n" " size_t id = get_global_id(0); \n" " int count=0; \n" " uint value=0; \n" " uint min=100000; \n" " uint max=0; \n" " for(int i=0; imax) max=inputImages[i*w*h+id]; \n" " } \n" " } \n" " if(count==0){ \n" " outputImage[id]=nullvalue; \n" " motionImage[id]=0.0; \n" " }else{ \n" " if((max-min)>difference){ \n" " outputImage[id]=inputImages[(imgCount-1)*w*h+id]; \n" " motionImage[id]=255.0; \n" " }else{ \n" " outputImage[id]=(uchar)((float)value/(float)count); \n" " motionImage[id]=0.0; \n" " } \n" " } \n" "} \n" ; #endif MotionSensitiveTemporalSmoothing::MotionSensitiveTemporalSmoothing(int iNullValue, int iMaxFilterSize){ //addProperty("use opencl","flag","",true); //addProperty("filter size","range:slider","[1,15]",10); //addProperty("difference","range:slider","[1,15]",10); size=utils::Size(0,0); numChannels=0; maxFilterSize=iMaxFilterSize; nullValue=iNullValue; currentFilterSize=6; currentDifference=10; useCL=true; } MotionSensitiveTemporalSmoothing::~MotionSensitiveTemporalSmoothing(){ for(int i=clPointer.size()-1; i>=0; i--){ delete &clPointer.at(i); } clPointer.clear(); } void MotionSensitiveTemporalSmoothing::init(int iChannels, core::depth iDepth, utils::Size iSize){ std::cout<<"maxFilterSize: "<=0; i--){ delete &clPointer.at(i); } clPointer.clear(); for(int i=0; isetFilterSize(currentFilterSize); clElement->setDifference(currentDifference); clElement->setUseCL(useCL); clPointer.push_back(clElement); } } void MotionSensitiveTemporalSmoothing::apply(const ImgBase *poSrc, ImgBase **ppoDst){ ICLASSERT_RETURN( poSrc ); ICLASSERT_RETURN( ppoDst ); ICLASSERT_RETURN( poSrc != *ppoDst); //filterSize = getPropertyValue("filter size"); //useCL = getPropertyValue("use opencl"); //difference = getPropertyValue("difference"); if(!poSrc->hasFullROI()) throw ICLException("MotionSensitiveTemporalSmoothing::apply: no roi supported"); if(poSrc->getDepth () != depth8u && poSrc->getDepth() != depth32f) throw ICLException("MotionSensitiveTemporalSmoothing::apply: depth 32f and 8u only"); if(!prepare (ppoDst, poSrc)) return; if(poSrc->getChannels() != numChannels || poSrc->getDepth() != depth || poSrc->getSize() != size){ init(poSrc->getChannels(), poSrc->getDepth(), poSrc->getSize()); } if(poSrc->getDepth() == depth8u){ Img8u src = *poSrc->as8u(); Img8u &dst = *(*ppoDst)->as8u(); for(int i=0; itemporalSmoothingC(in); dst.replaceChannel(i, &out, 0); } }else{ Img32f src = *poSrc->as32f(); Img32f &dst = *(*ppoDst)->as32f(); for(int i=0; itemporalSmoothingF(in); dst.replaceChannel(i, &out, 0); } } } void MotionSensitiveTemporalSmoothing::setUseCL(bool use){ //setPropertyValue("use opencl",use); useCL=use; for(unsigned int i=0; isetUseCL(use); } } void MotionSensitiveTemporalSmoothing::setFilterSize(int filterSize){ //setPropertyValue("filter size",filterSize); currentFilterSize=filterSize; for(unsigned int i=0; isetFilterSize(filterSize); } } void MotionSensitiveTemporalSmoothing::setDifference(int difference){ //setPropertyValue("difference",difference); currentDifference=difference; for(unsigned int i=0; isetDifference(difference); } } Img32f MotionSensitiveTemporalSmoothing::getMotionImage(){ return clPointer.at(0)->getMotionImage(); } bool MotionSensitiveTemporalSmoothing::isCLActive(){ return useCL; } TemporalSmoothingCL::TemporalSmoothingCL(utils::Size size, core::depth depth, int iMaxFilterSize, int iNullValue){ w=size.width; h=size.height; d=depth; maxFilterSize=iMaxFilterSize; nullValue=iNullValue; filterSize=maxFilterSize/2; currentFilterSize=maxFilterSize/2; currentDifference=10; imgCount=0; useCL=true; #ifdef HAVE_OPENCL //create openCL context motionImage.setSize(Size(w,h)); motionImage.setChannels(1); if(depth==depth32f){ for(int i=0; i platformList;//get number of available openCL platforms int selectedDevice=0;//initially select platform 0 try{ if(cl::Platform::get(&platformList)==CL_SUCCESS){ std::cout<<"openCL platform found"< deviceList; if(platformList.at(i).getDevices(CL_DEVICE_TYPE_GPU, &deviceList)==CL_SUCCESS){ std::cout<<"GPU-DEVICE(S) FOUND"<(); std::cout<<"selected devices: "<maxFilterSize){ filterSize=maxFilterSize; std::cout<<"set filter size to maximum ("<(1,outputImageArrayF),false); }catch (cl::Error err) {//catch openCL errors std::cout<< "ERROR: "<< err.what()<< "("<< err.err()<< ")"<max) max=inputImagesF.at(i)(x,y,0); } } if(count==0){ outputImageF(x,y,0)=nullValue; }else{ if((max-min)>currentDifference){ outputImageF(x,y,0)=inputImagesF.at(imgCount-1)(x,y,0); }else{ outputImageF(x,y,0)=value/count; } } } } } return outputImageF; } Img8u TemporalSmoothingCL::temporalSmoothingC(Img8u &inputImage){ if(filterSize>maxFilterSize){ filterSize=maxFilterSize; std::cout<<"set filter size to maximum ("<(1,outputImageArrayC),false); }catch (cl::Error err) {//catch openCL errors std::cout<< "ERROR: "<< err.what()<< "("<< err.err()<< ")"<max) max=inputImagesC.at(i)(x,y,0); } } if(count==0){ outputImageC(x,y,0)=nullValue; }else{ if((max-min)>currentDifference){ outputImageC(x,y,0)=inputImagesC.at(imgCount-1)(x,y,0); }else{ outputImageC(x,y,0)=(unsigned char)((float)value/(float)count); } } } } } return outputImageC; } void TemporalSmoothingCL::setUseCL(bool use){ useCL=use; } void TemporalSmoothingCL::setFilterSize(int iFilterSize){ filterSize=iFilterSize; } void TemporalSmoothingCL::setDifference(int iDifference){ currentDifference=iDifference; } Img32f TemporalSmoothingCL::getMotionImage(){ if(useCL==true && clReady==true){ #ifdef HAVE_OPENCL queue.enqueueReadBuffer(//read output from kernel motionImageBuffer, CL_TRUE, // block 0, w*h * sizeof(float), (float*) motionImageArray); motionImage = Img32f(Size(w,h),1,std::vector(1,motionImageArray),false); #endif } return motionImage; } bool TemporalSmoothingCL::isCLReady(){ return clReady; } bool TemporalSmoothingCL::isCLActive(){ return useCL; } } // namespace filter }