source: tags/release-1.0.5/src/ATrous/atrous_2d_reconstruct.cc

Last change on this file was 175, checked in by Matthew Whiting, 18 years ago

Introduced some simple inline functions to duchamp.hh to make the printing of progress bars simpler and of a more unified fashion.

File size: 7.1 KB
Line 
1#include <iostream>
2#include <iomanip>
3#include <math.h>
4#include <duchamp.hh>
5#include <ATrous/atrous.hh>
6#include <Utils/utils.hh>
7
8using std::endl;
9using std::setw;
10
11void atrous2DReconstruct(long &xdim, long &ydim, float *&input, float *&output, Param &par)
12{
13  /**
14   *  atrous2DReconstruct(xdim, ydim, input, output, par)
15   *
16   *  A routine that uses the a trous wavelet method to reconstruct a
17   *   2-dimensional image.
18   *  The Param object "par" contains all necessary info about the filter and
19   *   reconstruction parameters, although a Filter object has to be declared
20   *   elsewhere previously.
21   *  The input array is in "input", of dimensions "xdim"x"ydim", and the
22   *   reconstructed array is in "output".
23   */
24
25  extern Filter reconFilter;
26  bool flagBlank=par.getFlagBlankPix();
27  float blankPixValue = par.getBlankPixVal();
28  long size = xdim * ydim;
29  long mindim = xdim;
30  if (ydim<mindim) mindim = ydim;
31  int numScales = reconFilter.getNumScales(mindim);
32  double *sigmaFactors = new double[numScales+1];
33  for(int i=0;i<=numScales;i++){
34    if(i<=reconFilter.maxFactor(2))
35      sigmaFactors[i] = reconFilter.sigmaFactor(2,i);
36    else sigmaFactors[i] = sigmaFactors[i-1] / 2.;
37  }
38
39  float mean,sigma,originalSigma,originalMean,oldsigma,newsigma;
40  bool *isGood = new bool[size];
41  for(int pos=0;pos<size;pos++) isGood[pos] = !par.isBlank(input[pos]);
42 
43  float *array = new float[size];
44  int goodSize=0;
45  for(int i=0;i<size;i++) if(isGood[i]) array[goodSize++] = input[i];
46  findMedianStats(array,goodSize,originalMean,originalSigma);
47  originalSigma /= correctionFactor; // correct from MADFM to sigma estimator.
48  delete [] array;
49 
50  float *coeffs    = new float[size];
51  float *wavelet   = new float[size];
52
53  for(int pos=0;pos<size;pos++) output[pos]=0.;
54
55  int filterwidth = reconFilter.width();
56  int filterHW = filterwidth/2;
57  double *filter = new double[filterwidth*filterwidth];
58  for(int i=0;i<filterwidth;i++){
59    for(int j=0;j<filterwidth;j++){
60      filter[i*filterwidth+j] = reconFilter.coeff(i) * reconFilter.coeff(j);
61    }
62  }
63
64  int *xLim1 = new int[ydim];
65  for(int i=0;i<ydim;i++) xLim1[i] = 0;
66  int *yLim1 = new int[xdim];
67  for(int i=0;i<xdim;i++) yLim1[i] = 0;
68  int *xLim2 = new int[ydim];
69  for(int i=0;i<ydim;i++) xLim2[i] = xdim-1;
70  int *yLim2 = new int[xdim];
71  for(int i=0;i<xdim;i++) yLim2[i] = ydim-1;
72
73  if(par.getFlagBlankPix()){
74    float avGapX = 0, avGapY = 0;
75    for(int row=0;row<ydim;row++){
76      int ct1 = 0;
77      int ct2 = xdim - 1;
78      while((ct1<ct2)&&(par.isBlank(input[row*xdim+ct1]))) ct1++;
79      while((ct2>ct1)&&(par.isBlank(input[row*xdim+ct2]))) ct2--;
80      xLim1[row] = ct1;
81      xLim2[row] = ct2;
82      avGapX += ct2 - ct1;
83    }
84    avGapX /= float(ydim);
85   
86    for(int col=0;col<xdim;col++){
87      int ct1=0;
88      int ct2=ydim-1;
89      while((ct1<ct2)&&(par.isBlank(input[col+xdim*ct1]))) ct1++;
90      while((ct2>ct1)&&(par.isBlank(input[col+xdim*ct2]))) ct2--;
91      yLim1[col] = ct1;
92      yLim2[col] = ct2;
93      avGapY += ct2 - ct1;
94    }
95    avGapY /= float(xdim);
96   
97    mindim = int(avGapX);
98    if(avGapY < avGapX) mindim = int(avGapY);
99    numScales = reconFilter.getNumScales(mindim);
100  }
101
102  float threshold;
103  int iteration=0;
104  newsigma = 1.e9;
105  for(int i=0;i<size;i++) output[i] = 0;
106  do{
107    if(par.isVerbose()) {
108      std::cout << "Iteration #"<<setw(2)<<++iteration<<":";
109      printBackSpace(13);
110    }
111
112    // first, get the value of oldsigma and set it to the previous
113    //   newsigma value
114    oldsigma = newsigma;
115    // we are transforming the residual array
116    for(int i=0;i<size;i++)  coeffs[i] = input[i] - output[i]; 
117
118    int spacing = 1;
119    for(int scale = 1; scale<numScales; scale++){
120
121      if(par.isVerbose()){
122        std::cout << "Scale ";
123        std::cout << setw(2)<<scale<<" / "<<setw(2)<<numScales;
124        printBackSpace(13);
125        std::cout <<std::flush;
126      }
127
128      for(int ypos = 0; ypos<ydim; ypos++){
129        for(int xpos = 0; xpos<xdim; xpos++){
130          // loops over each pixel in the image
131          int pos = ypos*xdim + xpos;
132         
133          wavelet[pos] = coeffs[pos];
134
135          if(!isGood[pos]) wavelet[pos] = 0.;
136          else{
137
138            int filterpos = -1;
139            for(int yoffset=-filterHW; yoffset<=filterHW; yoffset++){
140              int y = ypos + spacing*yoffset;
141              // Boundary conditions -- assume reflection at boundaries.
142              // Use limits as calculated above
143//            if(yLim1[xpos]!=yLim2[xpos]){
144//              // if these are equal we will get into an infinite loop here
145//              while((y<yLim1[xpos])||(y>yLim2[xpos])){
146//                if(y<yLim1[xpos]) y = 2*yLim1[xpos] - y;     
147//                else if(y>yLim2[xpos]) y = 2*yLim2[xpos] - y;     
148//              }
149//            }
150              int oldrow = y * xdim;
151         
152              for(int xoffset=-filterHW; xoffset<=filterHW; xoffset++){
153                int x = xpos + spacing*xoffset;
154                // Boundary conditions -- assume reflection at boundaries.
155                // Use limits as calculated above
156//              if(xLim1[ypos]!=xLim2[ypos]){
157//                // if these are equal we will get into an infinite loop here
158//                while((x<xLim1[ypos])||(x>xLim2[ypos])){
159//                  if(x<xLim1[ypos]) x = 2*xLim1[ypos] - x;     
160//                  else if(x>xLim2[ypos]) x = 2*xLim2[ypos] - x;     
161//                }
162//              }
163
164                int oldpos = oldrow + x;
165
166                float oldCoeff;
167                if((y>=yLim1[xpos])&&(y<=yLim2[xpos])&&
168                   (x>=xLim1[ypos])&&(x<=xLim2[ypos])  )
169                  oldCoeff = coeffs[oldpos];
170                else oldCoeff = 0.;
171
172                filterpos++;
173
174                if(isGood[pos]) wavelet[pos] -= filter[filterpos] * oldCoeff;
175//                wavelet[pos] -= filter[filterpos] * coeffs[oldpos];
176
177              } //-> end of xoffset loop
178            } //-> end of yoffset loop
179          } //-> end of else{ ( from if(!isGood[pos])  )
180       
181        } //-> end of xpos loop
182      } //-> end of ypos loop
183
184      // Need to do this after we've done *all* the convolving
185      for(int pos=0;pos<size;pos++) coeffs[pos] = coeffs[pos] - wavelet[pos];
186
187      // Have found wavelet coeffs for this scale -- now threshold   
188      if(scale>=par.getMinScale()){
189        array = new float[size];
190        goodSize=0;
191        for(int pos=0;pos<size;pos++){
192          if(isGood[pos]) array[goodSize++] = wavelet[pos];
193        }
194        findMedianStats(array,goodSize,mean,sigma);
195        delete [] array;
196
197        threshold = mean +
198          par.getAtrousCut() * originalSigma * sigmaFactors[scale];
199        for(int pos=0;pos<size;pos++){
200          if(!isGood[pos]) output[pos] = blankPixValue;
201          // preserve the Blank pixel values in the output.
202          else if( fabs(wavelet[pos]) > threshold )
203            output[pos] += wavelet[pos];
204        }
205      }
206      spacing *= 2;
207
208    } // END OF LOOP OVER SCALES
209
210    for(int pos=0;pos<size;pos++) if(isGood[pos]) output[pos] += coeffs[pos];
211
212    array = new float[size];
213    goodSize=0;
214    for(int i=0;i<size;i++){
215      if(isGood[i]) array[goodSize++] = input[i] - output[i];
216    }
217    findMedianStats(array,goodSize,mean,newsigma);
218    newsigma /= correctionFactor; // correct from MADFM to sigma estimator.
219    delete [] array;
220   
221    if(par.isVerbose()) printBackSpace(15);
222
223  } while( (iteration==1) ||
224           (fabs(oldsigma-newsigma)/newsigma > reconTolerance) );
225
226  if(par.isVerbose()) std::cout << "Completed "<<iteration<<" iterations. ";
227
228  delete [] xLim1,xLim2,yLim1,yLim2;
229  delete [] coeffs;
230  delete [] wavelet;
231  delete [] isGood;
232  delete [] filter;
233  delete [] sigmaFactors;
234}
235   
236   
Note: See TracBrowser for help on using the repository browser.