// 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; }
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 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; } } } }
void rect(ImageFeature &img, const uint x, const uint y, const uint w, const uint h, const ::std::vector<double> &color, bool dash) { uint dashCounterMax = 3; uint dashCounter = dashCounterMax; uint dashMode = 1; // upper line for(uint i = x; i < x + w; ++i) { dashCounter--; if (dashCounter == 0) { dashCounter = dashCounterMax; dashMode = 1 - dashMode; } for(uint c = 0; c < img.zsize(); ++c) { if (!dash || (dashMode == 1)) { img(i, y, c) = color[c]; } } } // right line for(uint i = y; i < y + h; ++i) { dashCounter--; if (dashCounter == 0) { dashCounter = dashCounterMax; dashMode = 1 - dashMode; } for(uint c = 0; c < img.zsize(); ++c) { if (!dash || (dashMode == 1)) { img(x + w - 1, i, c) = color[c]; } } } // lower line for(int i = x + w - 1; i >= (int) x; --i) { dashCounter--; if (dashCounter == 0) { dashCounter = dashCounterMax; dashMode = 1 - dashMode; } for(uint c = 0; c < img.zsize(); ++c) { if (!dash || (dashMode == 1)) { img(i, y + h - 1, c)=color[c]; } } } // left line for(int i = y + h - 1; i >= (int) y; --i) { dashCounter--; if (dashCounter == 0) { dashCounter = dashCounterMax; dashMode = 1 - dashMode; } for(uint c = 0; c < img.zsize(); ++c) { if (!dash || (dashMode == 1)) { img(x, i, c) = color[c]; } } } }
void box(ImageFeature &img, const uint centerx, const uint centery, const vector<double> &color, const uint winsize) { for(uint x=centerx-winsize;x<=centerx+winsize;++x) { if(inImage(img,x,centery+winsize)) {for(uint c=0;c<img.zsize();++c) {img(x,centery+winsize,c)=color[c];}} if(inImage(img,x,centery-winsize)) {for(uint c=0;c<img.zsize();++c) {img(x,centery-winsize,c)=color[c];}} } for(uint y=centery-winsize;y<=centery+winsize;++y) { if(inImage(img,centerx+winsize,y)) {for(uint c=0;c<img.zsize();++c) {img(centerx+winsize,y,c)=color[c];}} if(inImage(img,centerx-winsize,y)) {for(uint c=0;c<img.zsize();++c) {img(centerx-winsize,y,c)=color[c];}} } }
void diagcross(ImageFeature &img, const uint x, const uint y,const vector<double>& color,const uint len) { //mark center if (inImage(img,x,y)) {for(uint c=0;c<img.zsize();++c) {img(x,y,c)=color[c];}} //mark outer pars for(uint i=1;i<=len;++i) { if(inImage(img,x+i,y+i)) {for(uint c=0;c<img.zsize();++c) {img(x+i,y+i,c)=color[c];}} if(inImage(img,x-i,y-i)) {for(uint c=0;c<img.zsize();++c) {img(x-i,y-i,c)=color[c];}} if(inImage(img,x-i,y+i)) {for(uint c=0;c<img.zsize();++c) {img(x-i,y+i,c)=color[c];}} if(inImage(img,x+i,y-i)) {for(uint c=0;c<img.zsize();++c) {img(x+i,y-i,c)=color[c];}} } }
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; }
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 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; }
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; }
ImageFeature getPatch(const ImageFeature &image, const uint left, const uint top, const uint right, const uint bottom) { DBG(50) << "get image patch from (" << left << "," << top << ") to (" << right << "," << bottom << ") " << endl; ImageFeature result(right-left+1, bottom-top+1,image.zsize()); for(uint x=left;x<=right;++x) { for(uint y=top;y<=bottom;++y) { for(uint z=0;z<image.zsize();++z) { if(x<image.xsize() && y<image.ysize() && x>0 && y>0) { result(x-left,y-top,z)=image(x,y,z); } } } } 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 }
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 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 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)]; } } } }
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 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))); } } } }
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; } } } }
ImageFeature getPatch(const ImageFeature &image, const uint xpos, const uint ypos, const uint winsize) { uint dim=2*winsize+1; ImageFeature result(dim,dim,image.zsize()); for(int x=(int)xpos-(int)winsize;x<=(int)xpos+(int)winsize;++x) { for(int y=(int)ypos-(int)winsize;y<=(int)ypos+(int)winsize;++y) { for(uint z=0;z<image.zsize();++z) { if(inImage(image,x,y,z)) { result(x+winsize-xpos,y+winsize-ypos,z)=image(x,y,z); } else { result(x+winsize-xpos,y+winsize-ypos,z)=0.0; } } } } return result; }
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 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 cutoff(ImageFeature &img, const double minimum, const double maximum) { 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)=max(minimum,img(x,y,c)); img(x,y,c)=min(maximum,img(x,y,c)); } } } }
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; } } } }
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 power(ImageFeature &img1, int p) { for (uint z = 0; z < img1.zsize(); z++) for (uint x = 0; x < img1.xsize(); x++) for (uint y = 0; y < img1.ysize(); y++) { double tmp = 1.0; double val = img1(x, y, z); for (int t = 0; t < p; t++) { tmp *= val; } img1(x, y, z) = tmp; } }
ImageFeature calculate(const ImageFeature &img) { ImageFeature result(img.xsize(), img.ysize(), 3); ImageFeature tmp; // process the layers for(uint z=0;z<img.zsize();++z) { tmp=directionality(img,z); add(result,tmp,0); tmp=coarseness(img,z); add(result,tmp,1); tmp=contrast(img,z); add(result,tmp,2); } divide(result,img.zsize()); // normalize(result); // result.save("result.png"); return result; }
void signedPower(ImageFeature &img1, int p) { for (uint z = 0; z < img1.zsize(); z++) for (uint x = 0; x < img1.xsize(); x++) for (uint y = 0; y < img1.ysize(); y++) { double tmp = 1.0; for (int t = 0; t < p; t++) { tmp *= img1(x, y, z); } if ((img1(x, y, z) < 0.0) && ((p % 2) == 0)) { tmp *= -1.0; } img1(x, y, z) = tmp; } }