ImageFeature fft(const ImageFeature &img) { ImageFeature result(img.xsize(),img.ysize(),2); #ifdef HAVE_FFT_LIBRARY fftw_complex FIMG[img.xsize()][img.ysize()]; for(uint x=0;x<img.xsize();++x) { for(uint y=0;y<img.ysize();++y) { FIMG[x][y].re=img(x,y,0); FIMG[x][y].im=0; } } fftwnd_plan plan = fftw2d_create_plan(img.xsize(),img.ysize(), FFTW_FORWARD, FFTW_ESTIMATE | FFTW_IN_PLACE); fftwnd_one(plan,&FIMG[0][0],NULL); fftwnd_destroy_plan(plan); for(uint x=0;x<img.xsize();++x) { for(uint y=0;y<img.ysize();++y) { result(x,y,0)=FIMG[x][y].re; result(x,y,1)=FIMG[x][y].im; } } #else #warning "FFT is used without FFT library enabled." ERR << "FFT not available, thus returning empty image instead of fourier transformed version. All that comes now is probably bogus." << endl; #endif return result; }
void convolve(ImageFeature &img, const ImageFeature &filter) { ImageFeature copy=img; int height2=filter.ysize()/2; int width2=filter.xsize()/2; double tmp; for(uint c=0;c<img.zsize();++c) { for(uint x=0;x<img.xsize();++x) { for(uint y=0;y<img.ysize();++y) { tmp=0.0; for(int i=-width2;i<=width2;++i) { int xx=x+i; if(xx<int(img.xsize()) && int(xx) >= 0) { for(int j=-height2;j<=height2;++j) { int yy=y+j; if(int(yy)>=0 && yy < int(img.ysize())) { tmp+=filter(i+width2,j+height2,0)*copy(xx,yy,c); } } } } img(x,y,c)=tmp; } } } }
void histogramNormalization(ImageFeature &img) { const uint bins=256; vector<int> H(bins); vector<double> T(bins); for(uint c=0;c<img.zsize();++c) { //DBG(10) << "c=" << c << endl; for(uint x=0;x<img.xsize();++x) { for(uint y=0;y<img.ysize();++y) { ++H[int(img(x,y,c)*255)]; } } for(uint p=1;p<bins;++p) { H[p]+=H[p-1]; } for(uint p=0;p<bins;++p) { T[p]=(1.0/double(img.size()))*double(H[p]); } for(uint x=0;x<img.xsize();++x) { for(uint y=0;y<img.ysize();++y) { img(x,y,c)=T[int(img(x,y,c)*255)]; } } } }
// default for type is set in imagelib.hpp // type = 0: maximum (as in HSV) // type = 1: mean // type = 2: luminance (use only for RGB images!) ImageFeature makeGray(const ImageFeature &img, const uint type) { ImageFeature result(img.xsize(), img.ysize(),1) ; double value; if( (type == 2) && (img.zsize() != 3) ) { ERR << "Image has invalid color resolution!" << endl; return result; } for(uint x=0;x<img.xsize();++x) { for(uint y=0;y<img.ysize();++y) { value=0.0; switch(type){ case 0: //max for(uint c=0;c<img.zsize();++c) { value=::std::max(value,img(x,y,c)); } break; case 1: //mean for(uint c=0;c<img.zsize();++c) { value+=img(x,y,c); } value/=img.zsize(); break; case 2: // luminance value = 0.3 * img(x,y,0) + 0.59 * img(x,y,1) + 0.11 * img(x,y,2); break; } result(x,y,0)=value; } } return result; }
ImageFeature DifferenceOfGaussian::difference(const ImageFeature& img1, const ImageFeature& img2) { ImageFeature newImage = ImageFeature(img1.xsize(), img1.ysize(), 1); for (int x = 0; x < (int) newImage.xsize(); x++) { for (int y = 0; y < (int) newImage.ysize(); y++) { newImage(x, y, 0) = img1(x, y, 0) - img2(x, y, 0); } } return newImage; }
ImageFeature localvariance(const ImageFeature &image, const uint winsize) { ImageFeature result(image.xsize(),image.ysize(),1); for(uint x=winsize;x<image.xsize()-winsize;++x) { for(uint y=winsize;y<image.ysize()-winsize;++y) { result(x,y,0)=localvariance(image, winsize, x,y); } } return result; }
void setPatch(ImageFeature& image, const uint xpos, const uint ypos, const ImageFeature &patch) { DBG(50) << "set image patch from (" << xpos << "," << ypos << ") to (" << xpos+patch.xsize() << "," << ypos+patch.ysize() << ") " << endl; for(uint x=0;x<patch.xsize();++x) { for(uint y=0;y<patch.ysize();++y) { for(uint z=0;z<patch.zsize();++z) { if(x+xpos<image.xsize() && y+ypos<image.ysize()) { image(x+xpos,y+ypos,z)=patch(x,y,z); } } } } }
void multiply(ImageFeature &img1, const ImageFeature& img2) { if ((img1.xsize() != img2.xsize()) || (img1.ysize() != img2.ysize()) || (img1.zsize() != img2.zsize())) { DBG(10) << "image features have different sizes, cannot be multiplied."; } for (uint z = 0; z < img1.zsize(); z++) for (uint x = 0; x < img1.xsize(); x++) for (uint y = 0; y < img1.ysize(); y++) { img1(x, y, z) = img1(x, y, z) * img2(x, y, z); } }
ImageFeature rotate90(const ImageFeature &img) { uint X=img.xsize(); ImageFeature result(img.ysize(),img.xsize(),img.zsize()); for(uint x=0;x<img.ysize();++x) { for(uint y=0;y<img.xsize();++y) { for(uint z=0;z<img.zsize();++z) { result(x,y,z)=img(y,X-x-1,z); } } } return result; }
ImageFeature zeropad(const ImageFeature& image, uint xpad, uint ypad) { ImageFeature result(image.xsize()+2*xpad, image.ysize()+2*ypad, image.zsize()); for(uint x=xpad;x<image.xsize()+xpad;++x) { for(uint y=ypad;y<image.ysize()+ypad;++y) { for(uint c=0;c<image.zsize();++c) { result(x,y,c)=image(x-xpad,y-ypad,c); } } } return result; }
ImageFeature flip(const ImageFeature &img) { ImageFeature result(img.xsize(),img.ysize(),img.zsize()); for(uint x=0;x<img.xsize();++x) { for(uint y=0;y<img.ysize();++y) { for(uint z=0;z<img.zsize();++z) { result(img.xsize()-x-1,y,z)=img(x,y,z); } } } return result; }
ImageFeature localEntropy(const ImageFeature &image, const uint winsize) { ImageFeature result(image.xsize(), image.ysize(), image.zsize()); for(uint x=0;x<image.xsize();++x) { for(uint y=0;y<image.ysize();++y) { for(uint z=0; z<image.zsize();++z) { result(x,y,z)=localEntropy(image, x,y,z,winsize); } } } return result; }
void meanandvariance(const ImageFeature &img, double &mean, double &variance, const uint layer) { mean=0.0; variance=0.0; for(uint y=0;y<img.ysize();++y) { for(uint x=0;x<img.xsize();++x) { mean+=img(x,y,layer); variance+=img(x,y,layer)*img(x,y,layer); } } uint size=img.xsize()*img.ysize(); mean/=double(size); variance/=double(size); variance-=mean*mean; }
ImageFeature threshold(const ImageFeature &image, const double threshold) { ImageFeature result(image.xsize(), image.ysize(), image.zsize()); for(uint x=0;x<image.xsize();++x) { for(uint y=0;y<image.ysize();++y) { for(uint z=0;z<image.zsize();++z) { if(image(x,y,z)>=threshold) { result(x,y,z)=1.0; } else { result(x,y,z)=0.0; } } } } return result; }
InterpolatingImage::InterpolatingImage(const ImageFeature& image, uint splinedegree) : sourceImage_(image), splinedegree_(splinedegree) { #ifdef HAVE_INTERPOL_LIBRARY coeff_=new float*[image.zsize()]; for(uint i=0; i<image.zsize(); ++i) { coeff_[i]=new float[image.xsize()*image.ysize()]; for(uint x=0; x<image.xsize(); ++x) { for(uint y=0; y<image.ysize(); ++y) { coeff_[i][y*image.xsize()+x]=float(image(x,y,i)); } } SamplesToCoefficients(coeff_[i],image.xsize(),image.ysize(),splinedegree); } #endif }
double efficientLocalMean(const int x,const int y,const int k,const ImageFeature &laufendeSumme) { int k2=k/2; int dimx=laufendeSumme.xsize(); int dimy=laufendeSumme.ysize(); //wanting average over area: (y-k2,x-k2) ... (y+k2-1, x+k2-1) int starty=y-k2; int startx=x-k2; int stopy=y+k2-1; int stopx=x+k2-1; if(starty<0) starty=0; if(startx<0) startx=0; if(stopx>dimx-1) stopx=dimx-1; if(stopy>dimy-1) stopy=dimy-1; double unten, links, oben, obenlinks; if(startx-1<0) links=0; else links=laufendeSumme(startx-1,stopy,0); if(starty-1<0) oben=0; else oben=laufendeSumme(stopx,starty-1,0); if((starty-1 < 0) || (startx-1 <0)) obenlinks=0; else obenlinks=laufendeSumme(startx-1,starty-1,0); unten=laufendeSumme(stopx,stopy,0); // cout << "obenlinks=" << obenlinks << " oben=" << oben << " links=" << links << " unten=" <<unten << endl; int counter=(stopy-starty+1)*(stopx-startx+1); return (unten-links-oben+obenlinks)/counter; }
//default values for fact_eq and offset are set in imagelib.hpp.... by paredes void equalize(ImageFeature &image, uint wndsize, double bnd, uint c, double fact_eq, uint offset) { double fact_orig=1.0-fact_eq; int xdim=image.xsize(); int ydim=image.ysize(); int i,j,xini,xend,yini,yend; ImageFeature acu(xdim,ydim,1); ImageFeature divisor(xdim,ydim,1); for(i=0; i < int(ydim-wndsize); i+=offset) { yini = i; yend = i+wndsize; for(j=0; j < int(xdim-wndsize); j+=offset) { xini = j; xend = j+wndsize; eq_histo(xini,xend,yini,yend,image,c,acu,divisor); } } for(j=0; j < ydim; j++) { for(i=0; i < xdim; i++) { if ( (image(i,j,c) > bnd) && (divisor(i,j,0) > 0.0) ) { image(i,j,c)=fact_eq*(acu(i,j,0)/divisor(i,j,0)) + fact_orig*image(i,j,c); // weighted average between original and equalized image } } } }
void add(ImageFeature &a, const ImageFeature &b, const uint z) { for(uint x=0;x<a.xsize();++x) { for(uint y=0;y<a.ysize();++y) { a(x,y,z)+=b(x,y,0); } } }
void LocalFeatureExtractor::extractPatches(ImageFeature &img, const ::std::vector<FeatureExtractionPosition> &positions, LocalFeatures &lf) { if(settings_.padding>0) { img=zeropad(img,settings_.padding, settings_.padding); } lf.winsize_=settings_.winsize; lf.padding_=settings_.padding; lf.numberOfFeatures_=positions.size(); lf.zsize_=img.zsize(); int windiameter=2*settings_.winsize+1; lf.dim_=windiameter*windiameter*img.zsize(); lf.imageSizeX_=img.xsize(); lf.imageSizeY_=img.ysize(); lf.filename_=img.filename(); int savesize=settings_.winsize*2+1; lf.positions_=positions; lf.data_.resize(positions.size()); for(uint i=0;i<positions.size();++i) { const FeatureExtractionPosition &pos=positions[i]; ImageFeature p=getPatch(img,pos.x,pos.y,pos.s); if(uint(pos.s)!=settings_.winsize) { p=scale(p,savesize,savesize); } lf.data_[i]=toVector(p); } }
void shift(ImageFeature &img, const double offset) { for(uint c=0;c<img.zsize();++c) { for(uint x=0;x<img.xsize();++x) { for(uint y=0;y<img.ysize();++y) { img(x,y,c)+=offset; }}} }
void ImageFeature::append(const ImageFeature& img) { if(img.xsize()==xsize_ && img.ysize() == ysize_) { uint oldsize=data_.size(); data_.resize(data_.size()+img.zsize(),vector<double>(xsize()*ysize())); for(uint c=0;c<img.zsize();++c) { for(uint x=0;x<img.xsize();++x) { for(uint y=0;y<img.ysize();++y) { (*this)(x,y,oldsize+c)=img(x,y,c); } } } zsize_=data_.size(); } else { ERR << "Images not compatible for appending" << endl; } }
void iDCT(ImageFeature &src, ImageFeature &dest) { dest.resize(src.xsize(),src.ysize(),src.zsize()); //NB Not efficient for(uint c=0;c<src.zsize();++c) { uint i,j,k; double sum; // Transform in x direction ImageFeature horizontal(src.xsize(), src.ysize(),1); for (j = 0; j < src.ysize(); j++) { for (i = 0; i < src.xsize(); i++) { sum = 0.0; for (k = 0; k < src.xsize(); k++) { sum += alpha(k,src.xsize())*src(k,j,0)* cos(double(2*i+1)*M_PI*double(k)/(double(2*src.xsize()))); } horizontal(i,j,0) = sum; } } // Transform in y direction for (i = 0; i < src.xsize(); i++) { for (j = 0; j < src.ysize(); j++) { sum = 0.0; for (k = 0; k < src.ysize(); k++) { sum += alpha(k, src.xsize())*horizontal(i,k,0)* cos(double(2*j+1)*M_PI*double(k)/(double(2*src.ysize()))); } dest(i,j,c) = sum; } } } }
double maximum(const ImageFeature &img, uint c) { double max=-1.0; for(uint x=0;x<img.xsize();++x) { for(uint y=0;y<img.ysize();++y) { max=::std::max(max,img(x,y,c)); } } return max; }
void multiply(ImageFeature &img, const double s) { for(uint z=0;z<img.zsize();++z) { for(uint x=0;x<img.xsize();++x) { for(uint y=0;y<img.ysize();++y) { img(x,y,z)*=s; } } } }
void absolute(ImageFeature &img1) { for (uint z = 0; z < img1.zsize(); z++) for (uint x = 0; x < img1.xsize(); x++) for (uint y = 0; y < img1.ysize(); y++) { if (img1(x, y, z) < 0.0) { img1(x, y, z) = -img1(x, y, z); } } }
void gammaCorrection(ImageFeature &img, double gamma) { for(uint c=0;c<img.zsize();++c) { for(uint x=0;x<img.xsize();++x) { for(uint y=0;y<img.ysize();++y) { img(x,y,c)=exp(gamma*log(img(x,y,c))); } } } }
double minimum(const ImageFeature &img, uint c) { double min=numeric_limits<double>::max(); for(uint x=0;x<img.xsize();++x) { for(uint y=0;y<img.ysize();++y) { min=::std::min(min,img(x,y,c)); } } return min; }
void divide(ImageFeature &a, const double &d) { for(uint x=0;x<a.xsize();++x) { for(uint y=0;y<a.ysize();++y) { for(uint z=0;z<a.zsize();++z) { a(x,y,z)/=d; } } } }
void appendHorizontally(ImageFeature &imga, const ImageFeature &imgb) { if(imga.ysize()!=imgb.ysize() || imga.zsize() != imgb.zsize()) { ERR << "Images have to have same width and depth" << endl; } else { ImageFeature tmp(imga); imga.resize(imga.xsize()+imgb.xsize(),imga.ysize(),imga.zsize()); for(uint y=0;y<tmp.ysize();++y) { for(uint z=0;z<tmp.zsize();++z) { for(uint x=0;x<tmp.xsize();++x) { imga(x,y,z)=tmp(x,y,z); } for(uint x=tmp.xsize();x<tmp.xsize()+imgb.xsize();++x) { imga(x,y,z)=imgb(x-tmp.xsize(),y,z); } } } } }
void contrast(ImageFeature &img,const double min, const double max) { double m=max-min; for(uint x=0;x<img.xsize();++x) { for(uint y=0;y<img.ysize();++y) { for(uint z=0;z<img.zsize();++z) { img(x,y,z)=img(x,y,z)*m+min; } } } }