// Author: Ce Liu (c) Dec, 2009; celiu@mit.edu // Modified By: Deepak Pathak (c) 2016; pathak@berkeley.edu #pragma once #include "project.hpp" #include "stdio.h" #include "memory.h" #include "ImageProcessing.hpp" #include #include #include #include "Vector.hpp" #include "Stochastic.hpp" #ifndef _MATLAB #include "ImageIO.hpp" #else #include "mex.h" #endif using namespace std; enum collapse_type{collapse_average,collapse_max,collapse_min}; enum color_type{RGB,BGR,DATA,GRAY}; // template class for image template class Image { public: T* pData; protected: int imWidth,imHeight,nChannels; int nPixels,nElements; bool IsDerivativeImage; color_type colorType; public: Image(void); Image(int width,int height,int nchannels=1); Image(const T& value,int _width,int _height,int _nchannels=1); Image(const Image& other); ~Image(void); virtual Image& operator=(const Image& other); virtual inline void computeDimension(){nPixels=imWidth*imHeight;nElements=nPixels*nChannels;}; virtual void allocate(int width,int height,int nchannels=1); template void allocate(const Image& other); virtual void clear(); virtual void reset(); virtual void copyData(const Image& other); void setValue(const T& value); void setValue(const T& value,int _width,int _height,int _nchannels=1); T immax() const { T Max=pData[0]; for(int i=1;i void copy(const Image& other); void im2double(); // function to access the member variables inline const T& operator [] (int index) const {return pData[index];}; inline T& operator[](int index) {return pData[index];}; inline T*& data(){return pData;}; inline const T*& data() const{return (const T*&)pData;}; inline int width() const {return imWidth;}; inline int height() const {return imHeight;}; inline int nchannels() const {return nChannels;}; inline int npixels() const {return nPixels;}; inline int nelements() const {return nElements;}; inline bool isDerivativeImage() const {return IsDerivativeImage;}; inline color_type colortype() const{return colorType;}; void setColorType(int colorVal) { switch (colorVal) { case 1: colorType = GRAY; break; default: colorType = RGB; } return; } bool IsFloat () const; bool IsEmpty() const {if(nElements==0) return true;else return false;}; bool IsInImage(int x,int y) const {if(x>=0 && x=0 && y bool matchDimension (const Image& image) const; bool matchDimension (int width,int height,int nchannels) const; inline void setDerivative(bool isDerivativeImage=true){IsDerivativeImage=isDerivativeImage;}; bool BoundaryCheck() const; // function to move this image to another one template void moveto(Image& image,int x,int y,int width=0,int height=0); // function of basic image operations virtual bool imresize(double ratio); template void imresize(Image& result,double ratio) const; void imresize(int dstWidth,int dstHeight); template void imresize(Image& result,int dstWidth,int dstHeight) const; template void upSampleNN(Image& result,int ratio) const; // image IO's virtual bool saveImage(const char* filename) const; virtual bool loadImage(const char* filename); virtual bool saveImage(ofstream& myfile) const; virtual bool loadImage(ifstream& myfile); // #ifndef _MATLAB // virtual bool imread(const char* filename); // virtual bool imwrite(const char* filename) const; // virtual bool imwrite(const char* filename,ImageIO::ImageType) const; // //virtual bool imread(const QString& filename); // //virtual void imread(const QImage& image); // // //virtual bool imwrite(const QString& filename,int quality=100) const; // //virtual bool imwrite(const QString& filename,ImageIO::ImageType imagetype,int quality=100) const; // //virtual bool imwrite(const QString& fileanme,T min,T max,int quality=100) const; // #else // virtual bool imread(const char* filename) const {return true;}; // virtual bool imwrite(const char* filename) const {return true;}; // #endif template Image dx (bool IsAdvancedFilter=false) const; template void dx(Image& image,bool IsAdvancedFilter=false) const; template Image dy(bool IsAdvancedFilter=false) const; template void dy(Image& image,bool IsAdvancedFilter=false) const; template void dxx(Image& image) const; template void dyy(Image& image) const; template void laplacian(Image& image) const; template void gradientmag(Image& image) const; void GaussianSmoothing(double sigma,int fsize); template void GaussianSmoothing(Image& image,double sigma,int fsize) const; template void GaussianSmoothing_transpose(Image& image,double sigma,int fsize) const; template void smoothing(Image& image,double factor=4); template Image smoothing(double factor=4); void smoothing(double factor=4); // funciton for filtering template void imfilter(Image& image,const double* filter,int fsize) const; template void imfilter(Image& image,const Image& kernel) const; template Image imfilter(const double* filter,int fsize) const; template void imfilter_h(Image& image,double* filter,int fsize) const; template void imfilter_v(Image& image,double* filter,int fsize) const; template void imfilter_hv(Image& image,const double* hfilter,int hfsize,const double* vfilter,int vfsize) const; template void imfilter_hv(Image& image,const Image& hfilter,const Image& vfilter) const; // funciton for filtering transpose template void imfilter_transpose(Image& image,const double* filter,int fsize) const; template void imfilter_transpose(Image& image,const Image& kernel) const; template Image imfilter_transpose(const double* filter,int fsize) const; template void imfilter_h_transpose(Image& image,double* filter,int fsize) const; template void imfilter_v_transpose(Image& image,double* filter,int fsize) const; template void imfilter_hv_transpose(Image& image,const double* hfilter,int hfsize,const double* vfilter,int vfsize) const; template void imfilter_hv_transpose(Image& image,const Image& hfilter,const Image& vfilter) const; // function to desaturating template void desaturate(Image& image) const; void desaturate(); template void collapse(Image& image,collapse_type type = collapse_average) const; void collapse(collapse_type type = collapse_average); void flip_horizontal(Image& image); void flip_horizontal(); // function to concatenate images template void concatenate(Image& destImage,const Image& addImage) const; template void concatenate(Image& destImage,const Image& addImage,double ratio) const; template Image concatenate(const Image& addImage) const; // function to separate the channels of the image template void separate(unsigned firstNChannels,Image& image1,Image& image2) const; // function to sample patch template void getPatch(Image& patch,double x,double y,int fsize) const; // function to crop the image template void crop(Image& patch,int Left,int Top,int Width,int Height) const; // basic numerics of images template void Multiply(const Image& image1,const Image& image2); template void MultiplyAcross(const Image& image1,const Image& image2); template void Multiply(const Image& image1,const Image& image2,const Image& image3); template void Multiplywith(const Image& image1); template void MultiplywithAcross(const Image& image1); void Multiplywith(double value); template void Add(const Image& image1,const Image& image2); template void Add(const Image& image1,const Image& image2,double ratio); void Add(const T value); template void Add(const Image& image1,const double value); template void Add(const Image& image1); template void Subtract(const Image& image1,const Image& image2); // arestmetic operators void square(); // exp void Exp(double sigma = 1); // function to normalize an image void normalize(Image& image); // function to threshold an image void threshold(); // function to compute the statistics of the image double norm2() const; double sum() const; template double innerproduct(Image& image) const; // function to bilateral smooth flow field template void BilateralFiltering(Image& other,int fsize,double filter_signa,double range_sigma); // function to bilateral smooth an image //Image BilateralFiltering(int fsize,double filter_sigma,double range_sigma); void imBilateralFiltering(Image& result,int fsize,double filter_sigma,double range_sigma); template int kmeansIndex(int pixelIndex,T1& minDistance,const T2* pDictionary,int nVocabulary, int nDim); // convert an image into visual words based on a dictionary template void ConvertToVisualWords(Image& result,const T2* pDictionary,int nDim,int nVocabulary); // get the histogram of an image region // the range is [0,imWidth] (x) and [0,imHeight] (y) template Vector histogramRegion(int nBins,double left,double top,double right,double bottom) const; // function for bicubic image interpolation template inline void BicubicCoeff(double a[][4],const T* pIm,const T1* pImDx,const T1* pImDy,const T1* pImDxDy,const int offsets[][2]) const; template void warpImageBicubic(Image& output,const Image& imdx,const Image& imdy, const Image& imdxdy,const Image& vx,const Image& vy) const; template void warpImageBicubic(Image& output,const Image& vx,const Image& vy) const; template void warpImageBicubicCoeff(Image& Coeff) const; template void warpImageBicubic(Image& output,const Image& coeff,const Image& vx,const Image& vy) const; template void warpImageBicubicRef(const Image& ref,Image& output,const Image& imdx,const Image& imdy, const Image& imdxdy,const Image& vx,const Image& vy) const; template void warpImageBicubicRef(const Image& ref,Image& output,const Image& vx,const Image& vy) const; template void warpImageBicubicRef(const Image& ref,Image& output,const Image& coeff,const Image& vx,const Image& vy) const; template void warpImageBicubicRef(const Image& ref,Image& output,const Image& flow) const; template void DissembleFlow(Image& vx,Image& vy) const; // function for image warping template void warpImage(Image& output,const Image& vx,const Image& vy) const; // function for image warping transpose template void warpImage_transpose(Image& output,const Image& vx,const Image& vy) const; // function for image warping template void warpImage(Image& output,const Image& flow) const; // function for image warping transpose template void warpImage_transpose(Image& output,const Image& flow) const; // function to get the max T max() const; // function to get min T min() const; void generate2DGuasisan(int winsize,double sigma) { clear(); imWidth = imHeight = winsize*2+1; nChannels = 1; computeDimension(); ImageProcessing::generate2DGaussian(pData,winsize,sigma); } void generate1DGaussian(int winsize,double sigma) { clear(); imWidth = winsize*2+1; imHeight = 1; nChannels = 1; computeDimension(); ImageProcessing::generate1DGaussian(pData,winsize,sigma); } template void subSampleKernelBy2(Image& output) const { int winsize = (imWidth-1)/2; int winsize_s = winsize/2; int winlen_s = winsize_s*2+1; if(!output.matchDimension(winlen_s,1,1)) output.allocate(winlen_s,1,1); output.pData[winsize_s] = pData[winsize]; for(int i = 0;i void LoadMatlabImageCore(const mxArray* image,bool IsImageScaleCovnersion=true); template void ConvertFromMatlab(const T1* pMatlabPlane,int _width,int _height,int _nchannels); void OutputToMatlab(mxArray*& matrix) const; template void ConvertToMatlab(T1* pMatlabPlane) const; #endif }; typedef Image BiImage; typedef Image UCImage; typedef Image IntImage; typedef Image FImage; typedef Image DImage; //------------------------------------------------------------------------------------------ // constructor //------------------------------------------------------------------------------------------ template Image::Image() { pData=NULL; imWidth=imHeight=nChannels=nPixels=nElements=0; colorType=RGB; IsDerivativeImage=false; } //------------------------------------------------------------------------------------------ // constructor with specified dimensions //------------------------------------------------------------------------------------------ template Image::Image(int width,int height,int nchannels) { imWidth=width; imHeight=height; nChannels=nchannels; computeDimension(); pData=NULL; pData=new T[nElements]; if(nElements>0) memset(pData,0,sizeof(T)*nElements); IsDerivativeImage=false; } template Image::Image(const T& value,int _width,int _height,int _nchannels) { pData=NULL; allocate(_width,_height,_nchannels); setValue(value); } #ifndef _MATLAB //template //Image::Image(const QImage& image) //{ // pData=NULL; // imread(image); //} #endif template void Image::allocate(int width,int height,int nchannels) { clear(); imWidth=width; imHeight=height; nChannels=nchannels; computeDimension(); pData=NULL; if(nElements>0) { pData=new T[nElements]; memset(pData,0,sizeof(T)*nElements); } } template template void Image::allocate(const Image &other) { allocate(other.width(),other.height(),other.nchannels()); IsDerivativeImage = other.isDerivativeImage(); colorType = other.colortype(); } //------------------------------------------------------------------------------------------ // copy constructor //------------------------------------------------------------------------------------------ template Image::Image(const Image& other) { imWidth=imHeight=nChannels=nElements=0; pData=NULL; copyData(other); } //------------------------------------------------------------------------------------------ // destructor //------------------------------------------------------------------------------------------ template Image::~Image() { if(pData!=NULL) delete []pData; } //------------------------------------------------------------------------------------------ // clear the image //------------------------------------------------------------------------------------------ template void Image::clear() { if(pData!=NULL) delete []pData; pData=NULL; imWidth=imHeight=nChannels=nPixels=nElements=0; } //------------------------------------------------------------------------------------------ // reset the image (reset the buffer to zero) //------------------------------------------------------------------------------------------ template void Image::reset() { if(pData!=NULL) memset(pData,0,sizeof(T)*nElements); } template void Image::setValue(const T &value) { for(int i=0;i void Image::setValue(const T& value,int _width,int _height,int _nchannels) { if(imWidth!=_width || imHeight!=_height || nChannels!=_nchannels) allocate(_width,_height,_nchannels); setValue(value); } //------------------------------------------------------------------------------------------ // copy from other image //------------------------------------------------------------------------------------------ template void Image::copyData(const Image& other) { imWidth=other.imWidth; imHeight=other.imHeight; nChannels=other.nChannels; nPixels=other.nPixels; IsDerivativeImage=other.IsDerivativeImage; colorType = other.colorType; if(nElements!=other.nElements) { nElements=other.nElements; if(pData!=NULL) delete []pData; pData=NULL; pData=new T[nElements]; } if(nElements>0) memcpy(pData,other.pData,sizeof(T)*nElements); } template template void Image::copy(const Image& other) { clear(); imWidth=other.width(); imHeight=other.height(); nChannels=other.nchannels(); computeDimension(); IsDerivativeImage=other.isDerivativeImage(); colorType = other.colortype(); pData=NULL; pData=new T[nElements]; const T1*& srcData=other.data(); for(int i=0;i void Image::im2double() { if(IsFloat()) for(int i=0;i Image& Image::operator=(const Image& other) { copyData(other); return *this; } template bool Image::IsFloat() const { if(typeid(T)==typeid(float) || typeid(T)==typeid(double) || typeid(T)==typeid(long double)) return true; else return false; } template template bool Image::matchDimension(const Image& image) const { if(imWidth==image.width() && imHeight==image.height() && nChannels==image.nchannels()) return true; else return false; } template bool Image::matchDimension(int width, int height, int nchannels) const { if(imWidth==width && imHeight==height && nChannels==nchannels) return true; else return false; } //------------------------------------------------------------------------------------------ // function to move this image to a dest image at (x,y) with specified width and height //------------------------------------------------------------------------------------------ template template void Image::moveto(Image& image,int x0,int y0,int width,int height) { if(width==0) width=imWidth; if(height==0) height=imHeight; int NChannels=__min(nChannels,image.nchannels()); int x,y; for(int i=0;i=image.height()) break; for(int j=0;j=image.width()) break; for(int k=0;k bool Image::imresize(double ratio) { if(pData==NULL) return false; T* pDstData; int DstWidth,DstHeight; DstWidth=(double)imWidth*ratio; DstHeight=(double)imHeight*ratio; pDstData=new T[DstWidth*DstHeight*nChannels]; ImageProcessing::ResizeImage(pData,pDstData,imWidth,imHeight,nChannels,ratio); delete []pData; pData=pDstData; imWidth=DstWidth; imHeight=DstHeight; computeDimension(); return true; } template template void Image::imresize(Image& result,double ratio) const { int DstWidth,DstHeight; DstWidth=(double)imWidth*ratio; DstHeight=(double)imHeight*ratio; if(result.width()!=DstWidth || result.height()!=DstHeight || result.nchannels()!=nChannels) result.allocate(DstWidth,DstHeight,nChannels); else result.reset(); ImageProcessing::ResizeImage(pData,result.data(),imWidth,imHeight,nChannels,ratio); } template template void Image::imresize(Image& result,int DstWidth,int DstHeight) const { if(result.width()!=DstWidth || result.height()!=DstHeight || result.nchannels()!=nChannels) result.allocate(DstWidth,DstHeight,nChannels); else result.reset(); ImageProcessing::ResizeImage(pData,result.data(),imWidth,imHeight,nChannels,DstWidth,DstHeight); } template void Image::imresize(int dstWidth,int dstHeight) { DImage foo(dstWidth,dstHeight,nChannels); ImageProcessing::ResizeImage(pData,foo.data(),imWidth,imHeight,nChannels,dstWidth,dstHeight); copyData(foo); } template template void Image::upSampleNN(Image& output,int ratio) const { int width = imWidth*ratio; int height = imHeight*ratio; if(!output.matchDimension(width,height,nChannels)) output.allocate(width,height,nChannels); for(int i = 0; i bool Image::saveImage(const char *filename) const { ofstream myfile(filename,ios::out | ios::binary); if(myfile.is_open()) { bool foo = saveImage(myfile); myfile.close(); return foo; } else return false; } template bool Image::saveImage(ofstream& myfile) const { char type[16]; sprintf(type,"%s",typeid(T).name()); myfile.write(type,16); myfile.write((char *)&imWidth,sizeof(int)); myfile.write((char *)&imHeight,sizeof(int)); myfile.write((char *)&nChannels,sizeof(int)); myfile.write((char *)&IsDerivativeImage,sizeof(bool)); myfile.write((char *)pData,sizeof(T)*nElements); return true; } template bool Image::loadImage(const char *filename) { ifstream myfile(filename, ios::in | ios::binary); if(myfile.is_open()) { bool foo = loadImage(myfile); myfile.close(); return foo; } else return false; } template bool Image::loadImage(ifstream& myfile) { char type[16]; myfile.read(type,16); #ifdef _LINUX_MAC if(strcasecmp(type,"uint16")==0) sprintf(type,"unsigned short"); if(strcasecmp(type,"uint32")==0) sprintf(type,"unsigned int"); if(strcasecmp(type,typeid(T).name())!=0) { cout<<"The type of the image is different from the type of the object!"< // bool Image::imread(const char* filename) // { // clear(); // if(ImageIO::loadImage(filename,pData,imWidth,imHeight,nChannels)) // { // computeDimension(); // colorType = BGR; // when we use qt or opencv to load the image, it's often BGR // return true; // } // return false; // } //template //bool Image::imread(const QString &filename) //{ // clear(); // if(ImageIO::loadImage(filename,pData,imWidth,imHeight,nChannels)) // { // computeDimension(); // return true; // } // return false; //} // //template //void Image::imread(const QImage& image) //{ // clear(); // ImageIO::loadImage(image,pData,imWidth,imHeight,nChannels); // computeDimension(); //} // //------------------------------------------------------------------------------------------ // function to write the image //------------------------------------------------------------------------------------------ // template // bool Image::imwrite(const char* filename) const // { // // ImageIO::ImageType type; // if(IsDerivativeImage) // type=ImageIO::derivative; // else // type=ImageIO::standard; // return ImageIO::saveImage(filename,pData,imWidth,imHeight,nChannels,type); // } // template // bool Image::imwrite(const char* filename,ImageIO::ImageType type) const // { // return ImageIO::saveImage(filename,pData,imWidth,imHeight,nChannels,type); // } //template //bool Image::imwrite(const QString &filename, ImageIO::ImageType imagetype, int quality) const //{ // return ImageIO::writeImage(filename,(const T*&)pData,imWidth,imHeight,nChannels,imagetype,quality); //} // //template //bool Image::imwrite(const QString &filename, T min, T max, int quality) const //{ // return ImageIO::writeImage(filename,(const T*&)pData,imWidth,imHeight,nChannels,min,max,quality); //} #endif //------------------------------------------------------------------------------------------ // function to get x-derivative of the image //------------------------------------------------------------------------------------------ template template void Image::dx(Image& result,bool IsAdvancedFilter) const { if(matchDimension(result)==false) result.allocate(imWidth,imHeight,nChannels); result.reset(); result.setDerivative(); T1*& data=result.data(); int i,j,k,offset; if(IsAdvancedFilter==false) for(i=0;i template Image Image::dx(bool IsAdvancedFilter) const { Image result; dx(result,IsAdvancedFilter); return result; } //------------------------------------------------------------------------------------------ // function to get y-derivative of the image //------------------------------------------------------------------------------------------ template template void Image::dy(Image& result,bool IsAdvancedFilter) const { if(matchDimension(result)==false) result.allocate(imWidth,imHeight,nChannels); result.setDerivative(); T1*& data=result.data(); int i,j,k,offset; if(IsAdvancedFilter==false) for(i=0;i template Image Image::dy(bool IsAdvancedFilter) const { Image result; dy(result,IsAdvancedFilter); return result; } //------------------------------------------------------------------------------------------ // function to compute the second order derivative //------------------------------------------------------------------------------------------ template template void Image::dxx(Image &image) const { if(!matchDimension(image)) image.allocate(imWidth,imHeight,nChannels); T1* pDstData=image.data(); if(nChannels==1) // if there is only one image channel for(int i=0;i template void Image::dyy(Image& image) const { if(!matchDimension(image)) image.allocate(imWidth,imHeight,nChannels); T1* pDstData=image.data(); if(nChannels==1) for(int i=0;i template void Image::laplacian(Image &image) const { if(!matchDimension(image)) image.allocate(*this); image.setDerivative(true); ImageProcessing::Laplacian(pData,image.data(),imWidth,imHeight,nChannels); } //------------------------------------------------------------------------------------------ // function to compute the gradient magnitude of the image //------------------------------------------------------------------------------------------ template template void Image::gradientmag(Image &image) const { if(image.width()!=imWidth || image.height()!=imHeight) image.allocate(imWidth,imHeight); DImage Ix,Iy; dx(Ix,true); dy(Iy,true); double temp; double* imagedata=image.data(); const double *Ixdata=Ix.data(),*Iydata=Iy.data(); for(int i=0;i void Image::GaussianSmoothing(double sigma,int fsize) { Image foo; GaussianSmoothing(foo,sigma,fsize); copy(foo); } template template void Image::GaussianSmoothing(Image& image,double sigma,int fsize) const { Image foo; // constructing the 1D gaussian filter double* gFilter; gFilter=new double[fsize*2+1]; double sum=0; sigma=sigma*sigma*2; for(int i=-fsize;i<=fsize;i++) { gFilter[i+fsize]=exp(-(double)(i*i)/sigma); sum+=gFilter[i+fsize]; } for(int i=0;i<2*fsize+1;i++) gFilter[i]/=sum; // apply filtering imfilter_hv(image,gFilter,fsize,gFilter,fsize); delete[] gFilter; } //------------------------------------------------------------------------------------------ // function to do Gaussian smoothing //------------------------------------------------------------------------------------------ template template void Image::GaussianSmoothing_transpose(Image& image,double sigma,int fsize) const { Image foo; // constructing the 1D gaussian filter double* gFilter; gFilter=new double[fsize*2+1]; double sum=0; sigma=sigma*sigma*2; for(int i=-fsize;i<=fsize;i++) { gFilter[i+fsize]=exp(-(double)(i*i)/sigma); sum+=gFilter[i+fsize]; } for(int i=0;i<2*fsize+1;i++) gFilter[i]/=sum; // apply filtering imfilter_hv_transpose(image,gFilter,fsize,gFilter,fsize); delete[] gFilter; } //------------------------------------------------------------------------------------------ // function to smooth the image using a simple 3x3 filter // the filter is [1 factor 1]/(factor+2), applied horizontally and vertically //------------------------------------------------------------------------------------------ template template void Image::smoothing(Image& image,double factor) { // build double filter2D[9]={1,0,1,0, 0, 0,1, 0,1}; filter2D[1]=filter2D[3]=filter2D[5]=filter2D[7]=factor; filter2D[4]=factor*factor; for(int i=0;i<9;i++) filter2D[i]/=(factor+2)*(factor+2); if(matchDimension(image)==false) image.allocate(imWidth,imHeight,nChannels); imfilter(image,filter2D,1); } template template Image Image::smoothing(double factor) { Image result; smoothing(result,factor); return result; } template void Image::smoothing(double factor) { Image result(imWidth,imHeight,nChannels); smoothing(result,factor); copyData(result); } //------------------------------------------------------------------------------------------ // function of image filtering //------------------------------------------------------------------------------------------ template template void Image::imfilter(Image& image,const double* filter,int fsize) const { if(matchDimension(image)==false) image.allocate(imWidth,imHeight,nChannels); ImageProcessing::filtering(pData,image.data(),imWidth,imHeight,nChannels,filter,fsize); } template template void Image::imfilter(Image& image,const Image& kernel) const { if(kernel.width()!=kernel.height()) { cout<<"Error in Image::imfilter(Image& image,const Image& kernel)"< template Image Image::imfilter(const double *filter, int fsize) const { Image result; imfilter(result,filter,fsize); return result; } template template void Image::imfilter_h(Image& image,double* filter,int fsize) const { if(matchDimension(image)==false) image.allocate(imWidth,imHeight,nChannels); ImageProcessing::hfiltering(pData,image.data(),imWidth,imHeight,nChannels,filter,fsize); } template template void Image::imfilter_v(Image& image,double* filter,int fsize) const { if(matchDimension(image)==false) image.allocate(imWidth,imHeight,nChannels); ImageProcessing::vfiltering(pData,image.data(),imWidth,imHeight,nChannels,filter,fsize); } template template void Image::imfilter_hv(Image &image, const double *hfilter, int hfsize, const double *vfilter, int vfsize) const { if(matchDimension(image)==false) image.allocate(imWidth,imHeight,nChannels); T1* pTempBuffer; pTempBuffer=new T1[nElements]; ImageProcessing::hfiltering(pData,pTempBuffer,imWidth,imHeight,nChannels,hfilter,hfsize); ImageProcessing::vfiltering(pTempBuffer,image.data(),imWidth,imHeight,nChannels,vfilter,vfsize); delete[] pTempBuffer; } template template void Image::imfilter_hv(Image& image,const Image& hfilter,const Image& vfilter) const { int hfsize = (__max(hfilter.width(),hfilter.height())-1)/2; int vfsize = (__max(vfilter.width(),vfilter.height())-1)/2; imfilter_hv(image,hfilter.data(),hfsize,vfilter.data(),vfsize); } template bool Image::BoundaryCheck() const { for(int i = 0;i-1E10)) { cout<<"Error, bad data!"< template void Image::imfilter_transpose(Image& image,const double* filter,int fsize) const { if(matchDimension(image)==false) image.allocate(imWidth,imHeight,nChannels); ImageProcessing::filtering_transpose(pData,image.data(),imWidth,imHeight,nChannels,filter,fsize); } template template void Image::imfilter_transpose(Image& image,const Image& kernel) const { if(kernel.width()!=kernel.height()) { cout<<"Error in Image::imfilter(Image& image,const Image& kernel)"< template Image Image::imfilter_transpose(const double *filter, int fsize) const { Image result; imfilter_transpose(result,filter,fsize); return result; } template template void Image::imfilter_h_transpose(Image& image,double* filter,int fsize) const { if(matchDimension(image)==false) image.allocate(imWidth,imHeight,nChannels); ImageProcessing::hfiltering_transpose(pData,image.data(),imWidth,imHeight,nChannels,filter,fsize); } template template void Image::imfilter_v_transpose(Image& image,double* filter,int fsize) const { if(matchDimension(image)==false) image.allocate(imWidth,imHeight,nChannels); ImageProcessing::vfiltering_transpose(pData,image.data(),imWidth,imHeight,nChannels,filter,fsize); } template template void Image::imfilter_hv_transpose(Image &image, const double *hfilter, int hfsize, const double *vfilter, int vfsize) const { if(matchDimension(image)==false) image.allocate(imWidth,imHeight,nChannels); Image temp(imWidth,imHeight,nChannels); //imwrite("input.jpg"); ImageProcessing::vfiltering_transpose(pData,temp.data(),imWidth,imHeight,nChannels,vfilter,vfsize); //temp.imwrite("temp.jpg"); ImageProcessing::hfiltering_transpose(temp.data(),image.data(),imWidth,imHeight,nChannels,hfilter,hfsize); } template template void Image::imfilter_hv_transpose(Image& image,const Image& hfilter,const Image& vfilter) const { int hfsize = (__max(hfilter.width(),hfilter.height())-1)/2; int vfsize = (__max(vfilter.width(),vfilter.height())-1)/2; imfilter_hv_transpose(image,hfilter.data(),hfsize,vfilter.data(),vfsize); } //------------------------------------------------------------------------------------------ // function for desaturation //------------------------------------------------------------------------------------------ template template void Image::desaturate(Image &image) const { if(nChannels!=3) { collapse(image); return; } if(!(image.width()==imWidth && image.height()==imHeight && image.nChannels==1)) image.allocate(imWidth,imHeight,1); T1* data=image.data(); int offset; for(int i=0;i void Image::desaturate() { Image temp; desaturate(temp); copyData(temp); } template template void Image::collapse(Image &image,collapse_type type) const { if(!(image.width()==imWidth && image.height()==imHeight && image.nChannels==1)) image.allocate(imWidth,imHeight,1); image.IsDerivativeImage = IsDerivativeImage; if(nChannels == 1) { image.copy(*this); return; } T1* data=image.data(); int offset; double temp; for(int i=0;i void Image::collapse(collapse_type type) { if(nChannels == 1) return; Image result; collapse(result,type); copyData(result); } //------------------------------------------------------------------------------------------ // function to concatenate two images //------------------------------------------------------------------------------------------ template template void Image::concatenate(Image &destImage, const Image &addImage) const { if(addImage.width()!=imWidth || addImage.height()!=imHeight) { destImage.copy(*this); return; } int extNChannels=nChannels+addImage.nchannels(); if(destImage.width()!=imWidth || destImage.height()!=imHeight || destImage.nchannels()!=extNChannels) destImage.allocate(imWidth,imHeight,extNChannels); int offset; T1*& pDestData=destImage.data(); const T2*& pAddData=addImage.data(); for(int i=0;i template void Image::concatenate(Image &destImage, const Image &addImage,double ratio) const { if(addImage.width()!=imWidth || addImage.height()!=imHeight) { destImage.copy(*this); return; } int extNChannels=nChannels+addImage.nchannels(); if(destImage.width()!=imWidth || destImage.height()!=imHeight || destImage.nchannels()!=extNChannels) destImage.allocate(imWidth,imHeight,extNChannels); int offset; T1*& pDestData=destImage.data(); const T2*& pAddData=addImage.data(); for(int i=0;i template Image Image::concatenate(const Image &addImage) const { Image destImage; concatenate(destImage,addImage); return destImage; } //------------------------------------------------------------------------------------------ // function to separate the image into two //------------------------------------------------------------------------------------------ template template void Image::separate(unsigned int firstNChannels, Image &image1, Image &image2) const { image1.IsDerivativeImage=IsDerivativeImage; image2.IsDerivativeImage=IsDerivativeImage; if(firstNChannels>=nChannels) { image1=*this; image2.allocate(imWidth,imHeight,0); return; } if(firstNChannels==0) { image1.allocate(imWidth,imHeight,0); image2=*this; return; } int secondNChannels=nChannels-firstNChannels; if(image1.width()!=imWidth || image1.height()!=imHeight || image1.nchannels()!=firstNChannels) image1.allocate(imWidth,imHeight,firstNChannels); if(image2.width()!=imWidth || image2.height()!=imHeight || image2.nchannels()!=secondNChannels) image2.allocate(imWidth,imHeight,secondNChannels); for(int i=0;i template void Image::getPatch(Image& patch,double x,double y,int wsize) const { int wlength=wsize*2+1; if(patch.width()!=wlength || patch.height()!=wlength || patch.nchannels()!=nChannels) patch.allocate(wlength,wlength,nChannels); else patch.reset(); ImageProcessing::getPatch(pData,patch.data(),imWidth,imHeight,nChannels,x,y,wsize); } //------------------------------------------------------------------------------------------ // function to crop an image //------------------------------------------------------------------------------------------ template template void Image::crop(Image& patch,int Left,int Top,int Width,int Height) const { if(patch.width()!=Width || patch.height()!=Height || patch.nchannels()!=nChannels) patch.allocate(Width,Height,nChannels); // make sure that the cropping is valid if(Left<0 || Top<0 || Left>=imWidth || Top>=imHeight) { cout<<"The cropping coordinate is outside the image boundary!"<imWidth || Height+Top>imHeight) { cout<<"The patch to crop is invalid!"< void Image::flip_horizontal(Image& image) { if(!image.matchDimension(*this)) image.allocate(*this); for(int i = 0;i void Image::flip_horizontal() { Image temp(*this); flip_horizontal(temp); copyData(temp); } //------------------------------------------------------------------------------------------ // function to multiply image1, image2 and image3 to the current image //------------------------------------------------------------------------------------------ template template void Image::Multiply(const Image& image1,const Image& image2,const Image& image3) { if(image1.matchDimension(image2)==false || image2.matchDimension(image3)==false) { cout<<"Error in image dimensions--function Image::Multiply()!"< template void Image::Multiply(const Image& image1,const Image& image2) { if(image1.matchDimension(image2)==false) { cout<<"Error in image dimensions--function Image::Multiply()!"< template void Image::MultiplyAcross(const Image& image1,const Image& image2) { if(image1.width() != image2.width() || image1.height()!=image2.height() || image2.nchannels()!=1) { cout<<"Error in image dimensions--function Image::Multiply()!"< template void Image::Multiplywith(const Image &image1) { if(matchDimension(image1)==false) { cout<<"Error in image dimensions--function Image::Multiplywith()!"< template void Image::MultiplywithAcross(const Image &image1) { if(imWidth!=image1.width() || imHeight!=image1.height() || image1.nchannels()!=1) { cout<<"Error in image dimensions--function Image::MultiplywithAcross()!"< void Image::Multiplywith(double value) { for(int i=0;i template void Image::Add(const Image& image1,const Image& image2) { if(image1.matchDimension(image2)==false) { cout<<"Error in image dimensions--function Image::Add()!"< template void Image::Add(const Image& image1,const Image& image2,double ratio) { if(image1.matchDimension(image2)==false) { cout<<"Error in image dimensions--function Image::Add()!"< template void Image::Add(const Image& image1,const double ratio) { if(matchDimension(image1)==false) { cout<<"Error in image dimensions--function Image::Add()!"< template void Image::Add(const Image& image1) { if(matchDimension(image1)==false) { cout<<"Error in image dimensions--function Image::Add()!"< void Image::Add(const T value) { for(int i=0;i template void Image::Subtract(const Image &image1, const Image &image2) { if(image1.matchDimension(image2)==false) { cout<<"Error in image dimensions--function Image::Subtract()!"< void Image::square() { for(int i = 0;i void Image::Exp(double sigma) { for(int i = 0;i void Image::normalize(Image& image) { if(image.width()!=imWidth || image.height()!=imHeight || image.nchannels()!=nChannels) image.allocate(imWidth,imHeight,nChannels); T Max =immax(),Min =immin(); if(Max==Min) return; double ratio=1/(Max-Min); if(IsFloat()==false) ratio*=255; T* data=image.data(); for(int i=0;i double Image::norm2() const { double result=0; for(int i=0;i void Image::threshold() { T ImgMax; if(IsFloat()) ImgMax = 1; else ImgMax = 255; for(int i = 0;i double Image::sum() const { double result=0; for(int i=0;i template double Image::innerproduct(Image &image) const { double result=0; const T1* pData1=image.data(); for(int i=0;i //bool Image::writeImage(QFile &file) const //{ // file.write((char *)&imWidth,sizeof(int)); // file.write((char *)&imHeight,sizeof(int)); // file.write((char *)&nChannels,sizeof(int)); // file.write((char *)&IsDerivativeImage,sizeof(bool)); // if(file.write((char *)pData,sizeof(T)*nElements)!=sizeof(T)*nElements) // return false; // return true; //} // //template //bool Image::readImage(QFile& file) //{ // clear(); // file.read((char *)&imWidth,sizeof(int)); // file.read((char *)&imHeight,sizeof(int)); // file.read((char *)&nChannels,sizeof(int)); // file.read((char *)&IsDerivativeImage,sizeof(bool)); // if(imWidth<0 ||imWidth>100000 || imHeight<0 || imHeight>100000 || nChannels<0 || nChannels>10000) // return false; // allocate(imWidth,imHeight,nChannels); // if(file.read((char *)pData,sizeof(T)*nElements)!=sizeof(T)*nElements) // return false; // return true; //} // //template //bool Image::writeImage(const QString &filename) const //{ // QFile file(filename); // if(file.open(QIODevice::WriteOnly)==false) // return false; // if(!writeImage(file)) // return false; // return true; //} // //template //bool Image::readImage(const QString &filename) //{ // QFile file(filename); // if(file.open(QIODevice::ReadOnly)==false) // return false; // if(!readImage(file)) // return false; // return true; //} #endif template template void Image::BilateralFiltering(Image& other,int fsize,double filter_sigma,double range_sigma) { double *pBuffer; Image result(other); pBuffer=new double[other.nchannels()]; // set spatial weight to save time double *pSpatialWeight; int flength = fsize*2+1; pSpatialWeight = new double[flength*flength]; for(int i=-fsize;i<=fsize;i++) for(int j=-fsize;j<=fsize;j++) pSpatialWeight[(i+fsize)*flength+j+fsize]=exp(-(double)(i*i+j*j)/(2*filter_sigma*filter_sigma)); for(int i=0;i=imWidth || y<0 || y>=imHeight) continue; // compute weight int offset=(y*imWidth+x)*nChannels; double temp=0; for(int k=0;k //Image Image::BilateralFiltering(int fsize,double filter_sigma,double range_sigma) void Image::imBilateralFiltering(Image& result,int fsize,double filter_sigma,double range_sigma) { //Image result(*this); result.allocate(*this); double *pBuffer; pBuffer=new double[nChannels]; // set spatial weight to save time double *pSpatialWeight; int flength = fsize*2+1; pSpatialWeight = new double[flength*flength]; for(int i=-fsize;i<=fsize;i++) for(int j=-fsize;j<=fsize;j++) pSpatialWeight[(i+fsize)*flength+j+fsize]=exp(-(double)(i*i+j*j)/(2*filter_sigma*filter_sigma)); for(int i=0;i=imWidth || y<0 || y>=imHeight) continue; // compute weight int offset=(y*imWidth+x)*nChannels; double temp=0; for(int k=0;k template int Image::kmeansIndex(int pixelIndex,T1& MinDistance,const T2* pDictionary,int nVocabulary,int nDim) { int offset1 = pixelIndex*nChannels; T1 Distance = 0; int index; for(int j = 0;j template void Image::ConvertToVisualWords(Image &result, const T2 *pDictionary, int nDim, int nVocabulary) { if(nChannels !=nDim) { cout<<"The dimension of the vocabulary must match to the nChannels of the image"< template Vector Image::histogramRegion(int nBins,double left,double top,double right,double bottom) const { Vector histogram(nBins); int Left = left,Top = top,Right = right,Bottom = bottom; double dLeft,dTop,dRight,dBottom; dLeft = 1-(left-Left); dTop = 1-(top-Top); if(right > Right) { dRight = right - Right; } else { Right --; dRight = 1; } if(bottom > Bottom) { dBottom = bottom - Bottom; } else { Bottom --; dBottom = 1; } for(int i = Top; i <= Bottom; i++) for(int j = Left; j <= Right; j++) { int offset = (i*imWidth+j)*nChannels; double weight=1; if(Top==Bottom) weight *= (dTop+dBottom-1); else { if(i==Top) weight *= dTop; if(i==Bottom) weight *= dBottom; } if(Left==Right) weight *= (dLeft+dRight-1); else { if(j==Left) weight *= dLeft; if(j==Right) weight *= dRight; } for(int k = 0;k template void Image::warpImageBicubic(Image& output,const Image& vx,const Image& vy) const { double dfilter[3] = {-0.5,0,0.5}; DImage imdx,imdy,imdxdy; imfilter_h(imdx,dfilter,1); imfilter_v(imdy,dfilter,1); imdx.imfilter_v(imdxdy,dfilter,1); warpImageBicubic(output,imdx,imdy,imdxdy,vx,vy); } template template void Image::warpImageBicubic(Image& output,const Image& imdx,const Image& imdy,const Image& imdxdy, const Image& vx,const Image& vy) const { T* pIm = pData; const T1* pImDx = imdx.data(); const T1* pImDy = imdy.data(); const T1* pImDxDy = imdxdy.data(); int width = vx.width(); int height = vx.height(); if(!output.matchDimension(width,height,nChannels)) output.allocate(width,height,nChannels); double a[4][4]; int offsets[2][2]; T ImgMax; if(IsFloat()) ImgMax = 1; else ImgMax = 255; for(int i = 0; i template void Image::warpImageBicubic(Image& output,const Image& coeff,const Image& vx,const Image& vy) const { T* pIm = pData; int width = vx.width(); int height = vx.height(); if(!output.matchDimension(width,height,nChannels)) output.allocate(width,height,nChannels); double a[4][4]; T ImgMax; if(IsFloat()) ImgMax = 1; else ImgMax = 255; for(int i = 0; i template void Image::BicubicCoeff(double a[][4],const T* pIm,const T1* pImDx,const T1* pImDy,const T1* pImDxDy,const int offsets[][2]) const { a[0][0] = pIm[offsets[0][0]]; a[1][0] = pImDx[offsets[0][0]]; a[2][0] = -3*pIm[offsets[0][0]] + 3*pIm[offsets[1][0]] -2*pImDx[offsets[0][0]] - pImDx[offsets[1][0]]; a[3][0] = 2*pIm[offsets[0][0]] - 2*pIm[offsets[1][0]] + pImDx[offsets[0][0]] +pImDx[offsets[1][0]]; a[0][1] = pImDy[offsets[0][0]]; a[1][1] = pImDxDy[offsets[0][0]]; a[2][1] = -3*pImDy[offsets[0][0]] + 3*pImDy[offsets[1][0]] - 2*pImDxDy[offsets[0][0]] - pImDxDy[offsets[1][0]]; a[3][1] = 2*pImDy[offsets[0][0]] - 2*pImDy[offsets[1][0]] + pImDxDy[offsets[0][0]] + pImDxDy[offsets[1][0]]; a[0][2] = -3*pIm[offsets[0][0]] + 3*pIm[offsets[0][1]] -2*pImDy[offsets[0][0]] - pImDy[offsets[0][1]]; a[1][2] = -3*pImDx[offsets[0][0]] + 3*pImDx[offsets[0][1]] -2*pImDxDy[offsets[0][0]] - pImDxDy[offsets[0][1]]; a[2][2] = 9*pIm[offsets[0][0]] - 9*pIm[offsets[1][0]] - 9*pIm[offsets[0][1]] + 9*pIm[offsets[1][1]] + 6*pImDx[offsets[0][0]] + 3*pImDx[offsets[1][0]] - 6*pImDx[offsets[0][1]] - 3*pImDx[offsets[1][1]] + 6*pImDy[offsets[0][0]] - 6*pImDy[offsets[1][0]] + 3*pImDy[offsets[0][1]] - 3*pImDy[offsets[1][1]] + 4*pImDxDy[offsets[0][0]] + 2*pImDxDy[offsets[1][0]] + 2*pImDxDy[offsets[0][1]] + pImDxDy[offsets[1][1]]; a[3][2] = -6*pIm[offsets[0][0]] + 6*pIm[offsets[1][0]] + 6*pIm[offsets[0][1]] - 6*pIm[offsets[1][1]] + (-3)*pImDx[offsets[0][0]] - 3*pImDx[offsets[1][0]] + 3*pImDx[offsets[0][1]] + 3*pImDx[offsets[1][1]] + (-4)*pImDy[offsets[0][0]] + 4*pImDy[offsets[1][0]] - 2*pImDy[offsets[0][1]] + 2*pImDy[offsets[1][1]] + (-2)*pImDxDy[offsets[0][0]] - 2*pImDxDy[offsets[1][0]] - pImDxDy[offsets[0][1]] - pImDxDy[offsets[1][1]]; a[0][3] = 2*pIm[offsets[0][0]] - 2*pIm[offsets[0][1]] + pImDy[offsets[0][0]] + pImDy[offsets[0][1]]; a[1][3] = 2*pImDx[offsets[0][0]] - 2*pImDx[offsets[0][1]] + pImDxDy[offsets[0][0]] + pImDxDy[offsets[0][1]]; a[2][3] = -6*pIm[offsets[0][0]] + 6*pIm[offsets[1][0]] + 6*pIm[offsets[0][1]] - 6*pIm[offsets[1][1]] + (-4)*pImDx[offsets[0][0]] - 2*pImDx[offsets[1][0]] + 4*pImDx[offsets[0][1]] + 2*pImDx[offsets[1][1]] + (-3)*pImDy[offsets[0][0]] + 3*pImDy[offsets[1][0]] - 3*pImDy[offsets[0][1]] + 3*pImDy[offsets[1][1]] + (-2)*pImDxDy[offsets[0][0]] - pImDxDy[offsets[1][0]] - 2*pImDxDy[offsets[0][1]] - pImDxDy[offsets[1][1]]; a[3][3] = 4*pIm[offsets[0][0]] - 4*pIm[offsets[1][0]] - 4*pIm[offsets[0][1]] + 4*pIm[offsets[1][1]] + 2*pImDx[offsets[0][0]] + 2*pImDx[offsets[1][0]] - 2*pImDx[offsets[0][1]] - 2*pImDx[offsets[1][1]] + 2*pImDy[offsets[0][0]] - 2*pImDy[offsets[1][0]] + 2*pImDy[offsets[0][1]] - 2*pImDy[offsets[1][1]] + pImDxDy[offsets[0][0]] + pImDxDy[offsets[1][0]] + pImDxDy[offsets[0][1]] + pImDxDy[offsets[1][1]]; } template template void Image::warpImageBicubicCoeff(Image& output) const { // generate derivatie filters Image imdx,imdy,imdxdy; double dfilter[3] = {-0.5,0,0.5}; imfilter_h(imdx,dfilter,1); imfilter_v(imdy,dfilter,1); imdx.imfilter_v(imdxdy,dfilter,1); T* pIm = pData; const T1* pImDx = imdx.data(); const T1* pImDy = imdy.data(); const T1* pImDxDy = imdxdy.data(); if(!output.matchDimension(imWidth,imHeight,nChannels*16)) output.allocate(imWidth,imHeight,nChannels*16); double a[4][4]; int offsets[2][2]; for(int i = 0; i template void Image::warpImageBicubicRef(const Image& ref,Image& output,const Image& vx,const Image& vy) const { double dfilter[3] = {-0.5,0,0.5}; DImage imdx,imdy,imdxdy; imfilter_h(imdx,dfilter,1); imfilter_v(imdy,dfilter,1); imdx.imfilter_v(imdxdy,dfilter,1); warpImageBicubicRef(ref,output,imdx,imdy,imdxdy,vx,vy); } template template void Image::warpImageBicubicRef(const Image& ref,Image& output,const Image& flow) const { DImage vx,vy; flow.DissembleFlow(vx,vy); warpImageBicubicRef(ref,output,vx,vy); } template template void Image::DissembleFlow(Image& vx,Image& vy) const { if(!vx.matchDimension(imWidth,imHeight,1)) vx.allocate(imWidth,imHeight,1); if(!vy.matchDimension(imWidth,imHeight,1)) vy.allocate(imWidth,imHeight,1); for(int i =0;i template void Image::warpImageBicubicRef(const Image& ref,Image& output,const Image& imdx,const Image& imdy,const Image& imdxdy, const Image& vx,const Image& vy) const { T* pIm = pData; const T1* pImDx = imdx.data(); const T1* pImDy = imdy.data(); const T1* pImDxDy = imdxdy.data(); int width = vx.width(); int height = vx.height(); if(!output.matchDimension(width,height,nChannels)) output.allocate(width,height,nChannels); double a[4][4]; int offsets[2][2]; T ImgMax; if(IsFloat()) ImgMax = 1; else ImgMax = 255; for(int i = 0; iimWidth-1 || y<0 || y>imHeight-1) { for(int k = 0; k-100000)) // bound the values // output.pData[offset*nChannels+k] = ref.pData[offset*nChannels+k]; } } } template template void Image::warpImageBicubicRef(const Image& ref,Image& output,const Image& coeff,const Image& vx,const Image& vy) const { T* pIm = pData; int width = vx.width(); int height = vx.height(); if(!output.matchDimension(width,height,nChannels)) output.allocate(width,height,nChannels); double a[4][4]; T ImgMax; if(IsFloat()) ImgMax = 1; else ImgMax = 255; for(int i = 0; iimWidth-1 || y<0 || y>imHeight-1) { for(int k = 0; k-100000)) // bound the values // output.pData[offset*nChannels+k] = ref.pData[offset*nChannels+k]; } } } template template void Image::warpImage(Image &output, const Image& vx, const Image& vy) const { if(!output.matchDimension(*this)) output.allocate(*this); ImageProcessing::warpImage(output.data(),pData,vx.data(),vy.data(),imWidth,imHeight,nChannels); } template template void Image::warpImage_transpose(Image &output, const Image& vx, const Image& vy) const { if(!output.matchDimension(*this)) output.allocate(*this); ImageProcessing::warpImage_transpose(output.data(),pData,vx.data(),vy.data(),imWidth,imHeight,nChannels); } template template void Image::warpImage(Image &output, const Image& flow) const { if(!output.matchDimension(*this)) output.allocate(*this); ImageProcessing::warpImage(output.data(),pData,flow.data(),imWidth,imHeight,nChannels); } template template void Image::warpImage_transpose(Image &output, const Image& flow) const { if(!output.matchDimension(*this)) output.allocate(*this); ImageProcessing::warpImage_transpose(output.data(),pData,flow.data(),imWidth,imHeight,nChannels); } template T Image::max() const { T Max = pData[0]; for(int i = 0;i T Image::min() const { T Min = pData[0]; for(int i = 0;i template void Image::LoadMatlabImageCore(const mxArray *image,bool IsImageScaleCovnersion) { int nDim = mxGetNumberOfDimensions(image); const int* imDim = mxGetDimensions(image); if(nDim==2) allocate(imDim[1],imDim[0]); else if(nDim==3) allocate(imDim[1],imDim[0],imDim[2]); else mexErrMsgTxt("The image doesn't have the appropriate dimension!"); T1* pMatlabPlane=(T1*)mxGetData(image); bool IsMatlabFloat; if(typeid(T1)==typeid(float) || typeid(T1)==typeid(double) || typeid(T1)==typeid(long double)) IsMatlabFloat=true; else IsMatlabFloat=false; bool isfloat=IsFloat(); if(isfloat==IsMatlabFloat || IsImageScaleCovnersion==false) { ConvertFromMatlab(pMatlabPlane,imWidth,imHeight,nChannels); return; } int offset=0; if(isfloat==true) for(int i=0;i bool Image::LoadMatlabImage(const mxArray* matrix,bool IsImageScaleCovnersion) { colorType = RGB; // the color is RGB when we use matlab to load the image if(mxIsClass(matrix,"uint8")) { LoadMatlabImageCore(matrix,IsImageScaleCovnersion); return true; } if(mxIsClass(matrix,"int8")) { LoadMatlabImageCore(matrix,IsImageScaleCovnersion); return true; } if(mxIsClass(matrix,"int32")) { LoadMatlabImageCore(matrix,IsImageScaleCovnersion); return true; } if(mxIsClass(matrix,"uint32")) { LoadMatlabImageCore(matrix,IsImageScaleCovnersion); return true; } if(mxIsClass(matrix,"int16")) { LoadMatlabImageCore(matrix,IsImageScaleCovnersion); return true; } if(mxIsClass(matrix,"uint16")) { LoadMatlabImageCore(matrix,IsImageScaleCovnersion); return true; } if(mxIsClass(matrix,"single")) { LoadMatlabImageCore(matrix,IsImageScaleCovnersion); return true; } if(mxIsClass(matrix,"double")) { LoadMatlabImageCore(matrix,IsImageScaleCovnersion); return true; } mexErrMsgTxt("Unknown type of the image!"); return false; } template template void Image::ConvertFromMatlab(const T1 *pMatlabPlane, int _width, int _height, int _nchannels) { if(imWidth!=_width || imHeight!=_height || nChannels!=_nchannels) allocate(_width,_height,_nchannels); int offset=0; for(int i=0;i template void Image::ConvertToMatlab(T1 *pMatlabPlane) const { int offset=0; for(int i=0;i void Image::OutputToMatlab(mxArray *&matrix) const { int dims[3]; dims[0]=imHeight; dims[1]=imWidth; dims[2]=nChannels; int nDims; nDims = (nChannels ==1)? 2:3; if(typeid(T) == typeid(unsigned char)) matrix=mxCreateNumericArray(nDims, dims,mxUINT8_CLASS, mxREAL); if(typeid(T) == typeid(char)) matrix=mxCreateNumericArray(nDims, dims,mxINT8_CLASS, mxREAL); if(typeid(T) == typeid(short int)) matrix=mxCreateNumericArray(nDims, dims,mxINT16_CLASS, mxREAL); if(typeid(T) == typeid(unsigned short int)) matrix=mxCreateNumericArray(nDims, dims,mxUINT16_CLASS, mxREAL); if(typeid(T) == typeid(int)) matrix=mxCreateNumericArray(nDims, dims,mxINT32_CLASS, mxREAL); if(typeid(T) == typeid(unsigned int)) matrix=mxCreateNumericArray(nDims, dims,mxUINT32_CLASS, mxREAL); if(typeid(T) == typeid(float)) matrix=mxCreateNumericArray(nDims, dims,mxSINGLE_CLASS, mxREAL); if(typeid(T) == typeid(double)) matrix=mxCreateNumericArray(nDims, dims,mxDOUBLE_CLASS, mxREAL); ConvertToMatlab((T*)mxGetData(matrix)); } #endif