// ----------------------------------------------------------------------- // atrous_transform.cc: Simplified a trous transform functions - only used // for testing purposes. // ----------------------------------------------------------------------- // Copyright (C) 2006, Matthew Whiting, ATNF // // This program is free software; you can redistribute it and/or modify it // under the terms of the GNU General Public License as published by the // Free Software Foundation; either version 2 of the License, or (at your // option) any later version. // // Duchamp is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License // for more details. // // You should have received a copy of the GNU General Public License // along with Duchamp; if not, write to the Free Software Foundation, // Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA // // Correspondence concerning Duchamp may be directed to: // Internet email: Matthew.Whiting [at] atnf.csiro.au // Postal address: Dr. Matthew Whiting // Australia Telescope National Facility, CSIRO // PO Box 76 // Epping NSW 1710 // AUSTRALIA // ----------------------------------------------------------------------- #include #include #include #include #include #include namespace duchamp{ /***********************************************************************/ ///// 1-DIMENSIONAL TRANSFORM /***********************************************************************/ // template // void atrousTransform(long &length, T *&spectrum, T *&coeffs, T *&wavelet) // { // int filterHW = filterwidth/2; // int numScales = getNumScales(length); // delete [] coeffs; // coeffs = new T[(numScales+1)*length]; // delete [] wavelet; // wavelet = new T[(numScales+1)*length]; // for(int i=0;i=length) x = 2*(length-1) - x; // reflection. // // if(x<0) x = x+length; // boundary conditions are // // if(x>=length) x = x-length; // continuous. // coeffs[(scale+1)*length+pos] += filter1D[offset+filterHW] * // coeffs[scale*length+x]; // } // wavelet[(scale+1)*length+pos] = coeffs[scale*length+pos] - // coeffs[(scale+1)*length+pos]; // } // spacing *= 2; // } // } void atrousTransform(size_t &length, int &numScales, float *spectrum, double *coeffs, double *wavelet, duchamp::Param &par) { duchamp::Filter reconFilter = par.filter(); int filterHW = reconFilter.width()/2; for(int i=0;i=length) x = 2*(length-1) - x; // reflection. // if(x<0) x = x+length; // boundary conditions are // if(x>=length) x = x-length; // continuous. // coeffs[(scale+1)*length+pos] += filter1D[offset+filterHW] * // coeffs[scale*length+x]; coeffs[(scale+1)*length+pos] += reconFilter.coeff(offset+filterHW) * coeffs[scale*length+x]; } wavelet[(scale+1)*length+pos] = coeffs[scale*length+pos] - coeffs[(scale+1)*length+pos]; } spacing *= 2; } } void atrousTransform(size_t &length, float *spectrum, float *coeffs, float *wavelet, duchamp::Param &par) { duchamp::Filter reconFilter = par.filter(); int filterHW = reconFilter.width()/2; int numScales = reconFilter.getNumScales(length); delete [] coeffs; coeffs = new float[(numScales+1)*length]; delete [] wavelet; wavelet = new float[(numScales+1)*length]; for(int i=0;i=length) x = 2*(length-1) - x; // reflection. // if(x<0) x = x+length; // boundary conditions are // if(x>=length) x = x-length; // continuous. // coeffs[(scale+1)*length+pos] += filter1D[offset+filterHW] * // coeffs[scale*length+x]; coeffs[(scale+1)*length+pos] += reconFilter.coeff(offset+filterHW) * coeffs[scale*length+x]; } wavelet[(scale+1)*length+pos] = coeffs[scale*length+pos] - coeffs[(scale+1)*length+pos]; } spacing *= 2; } } /***********************************************************************/ ///// 2-DIMENSIONAL TRANSFORM /***********************************************************************/ void atrousTransform2D(size_t &xdim, size_t &ydim, int &numScales, float *input, double *coeffs, double *wavelet, duchamp::Param &par) { duchamp::Filter reconFilter = par.filter(); float blankPixValue = par.getBlankPixVal(); int filterHW = reconFilter.width()/2; double *filter = new double[reconFilter.width()*reconFilter.width()]; for(int i=0;ixLim1)&&(input[row*xdim+xLim1]==blankPixValue)) xLim2--; // } // for(int col=0;colyLim1)&&(input[col+xdim*yLim1]==blankPixValue)) yLim2--; // } // std::cerr << "X Limits: "<ct1)&&(input[row*xdim+ct2]==blankPixValue) ) ct2--; xLim1[row] = ct1; xLim2[row] = ct2; std::cerr<ct1)&&(input[col+xdim*ct2]==blankPixValue) ) ct2--; yLim1[col] = ct1; yLim2[col] = ct2; } std::vector isGood(size); for(int pos=0;pos=ydim) y = 2*(ydim-1) - y; // reflection. // while((yyLim2)){ // if(yyLim2) y = 2*yLim2 - y; // reflection. // } // boundary conditions are reflection. for(int xoffset=-filterHW; xoffset<=filterHW; xoffset++){ int x = xpos + spacing*xoffset; int newx; //if(x<0) x = -x; // boundary conditions are // if(x>=xdim) x = 2*(xdim-1) - x; // reflection. //while((xxLim2)){ // if(xxLim2) x = 2*xLim2 - x; // reflection. // } // boundary conditions are reflection. if(yyLim2[xpos]) newy = 2*yLim2[xpos] - y; else newy = y; if(xxLim2[ypos]) newx = 2*xLim2[ypos] - x; else newx=x; x = newx; y = newy; int filterpos = (yoffset+filterHW)*reconFilter.width() + (xoffset+filterHW); int oldpos = y*xdim + x; if(// (x>=0)&&(x=0)&&(y=ydim) y = 2*(ydim-1) - y; // reflection. // for(int xoffset=-filterHW; xoffset<=filterHW; xoffset++){ // int x = xpos + spacing*xoffset; // if(x<0) x = -x; // boundary conditions are // if(x>=xdim) x = 2*(xdim-1) - x; // reflection. // int filterpos = (yoffset+filterHW)*reconFilter.width() + (xoffset+filterHW); // int oldpos = y*xdim + x; // coeffs[pos] += filter[filterpos] * oldcoeffs[oldpos]; // } // } // wavelet[(scale+1)*size+pos] = oldcoeffs[pos] - coeffs[pos]; // } // } // spacing *= 2; // } // delete [] filter; // delete [] oldcoeffs; // } /***********************************************************************/ ///// 3-DIMENSIONAL TRANSFORM /***********************************************************************/ void atrousTransform3D(size_t &xdim, size_t &ydim, size_t &zdim, int &numScales, float *&input, float *&coeffs, float *&wavelet, duchamp::Param &par) { duchamp::Filter reconFilter = par.filter(); float blankPixValue = par.getBlankPixVal(); int filterHW = reconFilter.width()/2; size_t size = xdim * ydim * zdim; float *oldcoeffs = new float[size]; std::cerr << "%"; int fsize = reconFilter.width()*reconFilter.width()*reconFilter.width(); std::cerr << "%"; double *filter = new double[fsize]; for(int i=0;i ASSUMING NO TRIMMING IN SPECTRAL DIRECTION int xLim1 = 0, yLim1 = 0, xLim2 = xdim-1, yLim2 = ydim-1; for(int col=0;colyLim1)&&(input[col+xdim*yLim1]==blankPixValue) ) yLim2--; } for(int row=0;rowxLim1)&&(input[row*xdim+xLim1]==blankPixValue) ) xLim2--; } for(int i=0;i=zdim) z = 2*(zdim-1) - z; // reflection. for(int yoffset=-filterHW; yoffset<=filterHW; yoffset++){ int y = ypos + spacing*yoffset; //if(y<0) y = -y; // boundary conditions are // if(y>=ydim) y = 2*(ydim-1) - y; // reflection. if(yyLim2) y = 2*yLim2 - y; // reflection. for(int xoffset=-filterHW; xoffset<=filterHW; xoffset++){ int x = xpos + spacing*xoffset; //if(x<0) x = -x; // boundary conditions are //if(x>=xdim) x = 2*(xdim-1) - x; // reflection. if(xxLim2) x = 2*xLim2 - x; // reflection. int filterpos = (zoffset+filterHW)*reconFilter.width()*reconFilter.width() + (yoffset+filterHW)*reconFilter.width() + (xoffset+filterHW); int oldpos = z*xdim*ydim + y*xdim + x; if(!par.isBlank(oldcoeffs[oldpos])) coeffs[pos] += filter[filterpos] * oldcoeffs[oldpos]; } } } } wavelet[(scale+1)*size+pos] = oldcoeffs[pos] - coeffs[pos]; } } } spacing *= 2; } std::cerr << "|"; delete [] filter; delete [] oldcoeffs; } // void atrousTransform3D(long &xdim, long &ydim, long &zdim, int &numScales, float *input, float *coeffs, float *wavelet) // { // extern Filter reconFilter; // int filterHW = reconFilter.width()/2; // long size = xdim * ydim * zdim; // float *oldcoeffs = new float[size]; // std::cerr << "%"; // int fsize = reconFilter.width()*reconFilter.width()*reconFilter.width(); // std::cerr << "%"; // double *filter = new double[fsize]; // for(int i=0;i=zdim) z = 2*(zdim-1) - z; // reflection. // for(int yoffset=-filterHW; yoffset<=filterHW; yoffset++){ // int y = ypos + spacing*yoffset; // if(y<0) y = -y; // boundary conditions are // if(y>=ydim) y = 2*(ydim-1) - y; // reflection. // for(int xoffset=-filterHW; xoffset<=filterHW; xoffset++){ // int x = xpos + spacing*xoffset; // if(x<0) x = -x; // boundary conditions are // if(x>=xdim) x = 2*(xdim-1) - x; // reflection. // int filterpos = (zoffset+filterHW)*reconFilter.width()*reconFilter.width() + // (yoffset+filterHW)*reconFilter.width() + (xoffset+filterHW); // int oldpos = z*xdim*ydim + y*xdim + x; // coeffs[pos] += filter[filterpos] * oldcoeffs[oldpos]; // } // } // } // wavelet[(scale+1)*size+pos] = oldcoeffs[pos] - coeffs[pos]; // } // } // } // spacing *= 2; // } // std::cerr << "|"; // delete [] filter; // delete [] oldcoeffs; // } }