source: tags/release-0.9.2/ATrous/atrous_2d_reconstruct.cc @ 201

Last change on this file since 201 was 86, checked in by Matthew Whiting, 18 years ago

Large commit, mostly removing dud commented code, and adding comments and
documentation to the existing code. No new features.

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