#include "iclGaborOp.h" #include "iclConvolutionOp.h" #include <iclImgChannel.h> #include <math.h> using namespace std; namespace icl{ GaborOp::GaborOp(){} GaborOp::GaborOp(const Size &kernelSize, std::vector<icl32f> lambdas, std::vector<icl32f> thetas, std::vector<icl32f> psis, std::vector<icl32f> sigmas, std::vector<icl32f> gammas){ m_vecLambdas = lambdas; m_vecThetas = thetas; m_vecPsis = psis; m_vecSigmas = sigmas; m_vecGammas = gammas; m_oKernelSize = kernelSize; updateKernels(); } GaborOp::~GaborOp(){ for(unsigned int i=0;i<m_vecResults.size();++i){ delete m_vecResults[i]; } } void GaborOp::setKernelSize(const Size &size){ m_oKernelSize = size; updateKernels(); } void GaborOp::addLambda(float lambda){ m_vecLambdas.push_back(lambda); } void GaborOp::addTheta(float theta){ m_vecThetas.push_back(theta); } void GaborOp::addPsi(float psi){ m_vecPsis.push_back(psi); } void GaborOp::addSigma(float sigma){ m_vecSigmas.push_back(sigma); } void GaborOp::addGamma(float gamma){ m_vecGammas.push_back(gamma); } void GaborOp::updateKernels(){ m_vecKernels.clear(); for(unsigned int i=0;i<m_vecResults.size();i++){ delete m_vecResults[i]; } m_vecResults.clear(); ICLASSERT_RETURN( m_oKernelSize != Size::null ); for(unsigned int l = 0;l<m_vecLambdas.size();l++){ for(unsigned int t = 0;t<m_vecThetas.size();t++){ for(unsigned int p = 0;p<m_vecPsis.size();p++){ for(unsigned int s = 0;s<m_vecSigmas.size();s++){ for(unsigned int g = 0;g<m_vecGammas.size();g++){ Img32f *k = createKernel(m_oKernelSize, m_vecLambdas[l], m_vecThetas[t], m_vecPsis[p], m_vecSigmas[s], m_vecGammas[g]); m_vecKernels.push_back(*k); m_vecResults.push_back(0); delete k; } } } } } } void GaborOp::apply(const ImgBase *poSrc, ImgBase **ppoDst){ ICLASSERT_RETURN( poSrc ); ICLASSERT_RETURN( ppoDst ); ICLASSERT_RETURN( poSrc != *ppoDst); if(!*ppoDst){ *ppoDst = new Img32f(Size::null,0); } ImgBase *poDst = *ppoDst; poDst->setChannels(0); poDst->setSize(Size::null); for(unsigned int i=0;i<m_vecKernels.size();i++){ ConvolutionOp co(m_vecKernels[i].getData(0),m_oKernelSize, false); co.setCheckOnly(false); co.setClipToROI(true); co.apply(poSrc,&(m_vecResults[i])); poDst->setSize(m_vecResults[i]->getSize()); poDst->asImg<icl32f>()->append(m_vecResults[i]->asImg<icl32f>()); } } vector<icl32f> GaborOp::apply(const ImgBase *poSrc, const Point &p){ ICLASSERT_RETURN_VAL( poSrc && poSrc->getChannels() && poSrc->getSize() != Size::null, vector<icl32f>() ); vector<icl32f> v; Img32f resPix(Size(1,1),poSrc->getChannels()); ImgBase *resPixBase = &resPix; const ImgBase *poSrcROIPix = poSrc->shallowCopy(Rect(p,Size(1,1))); for(unsigned int i=0;i<m_vecKernels.size();i++){ ConvolutionOp co(m_vecKernels[i].getData(0),m_oKernelSize, false); co.setCheckOnly(false); co.setClipToROI(true); co.apply(poSrcROIPix,&resPixBase); for(int c=0;c<resPix.getChannels();c++){ v.push_back(resPix(0,0,c)); } } return v; } Img32f *GaborOp::createKernel(const Size &size, float lambda, float theta, float psi, float sigma, float gamma){ Img32f *poKernelImage = new Img32f (size,1); int xCenter = size.width/2; int yCenter = size.height/2; ImgChannel32f k = pickChannel(poKernelImage,0); gamma *=gamma; sigma *=sigma*2; for(int x=0;x<k.getWidth();++x){ for(int y=0;y<k.getHeight();++y){ float xTrans = xCenter-x; float yTrans = yCenter-y; float x2 = xTrans*cos(theta) + yTrans*sin(theta); float y2 = -xTrans*sin(theta) + yTrans*cos(theta); k(x,y) = exp( -(x2*x2+gamma*y2*y2)/sigma) * cos( (2.0*M_PI*x2)/lambda + psi ); } } return poKernelImage; } }