source: tags/release-1.0.2/src/ATrous/atrous_2d_reconstruct.cc @ 167

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

Changed all instances of fabsf to fabs so that compilation on venice works.
(Mirror commit of rev.125)

File size: 7.0 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++) isGood[pos] = !par.isBlank(input[pos]);
40 
41  float *array = new float[size];
42  int goodSize=0;
43  for(int i=0;i<size;i++) if(isGood[i]) array[goodSize++] = input[i];
44  findMedianStats(array,goodSize,originalMean,originalSigma);
45  originalSigma /= correctionFactor; // correct from MADFM to sigma estimator.
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 filterwidth = reconFilter.width();
54  int filterHW = filterwidth/2;
55  double *filter = new double[filterwidth*filterwidth];
56  for(int i=0;i<filterwidth;i++){
57    for(int j=0;j<filterwidth;j++){
58      filter[i*filterwidth+j] = reconFilter.coeff(i) * reconFilter.coeff(j);
59    }
60  }
61
62  int *xLim1 = new int[ydim];
63  for(int i=0;i<ydim;i++) xLim1[i] = 0;
64  int *yLim1 = new int[xdim];
65  for(int i=0;i<xdim;i++) yLim1[i] = 0;
66  int *xLim2 = new int[ydim];
67  for(int i=0;i<ydim;i++) xLim2[i] = xdim-1;
68  int *yLim2 = new int[xdim];
69  for(int i=0;i<xdim;i++) yLim2[i] = ydim-1;
70
71  if(par.getFlagBlankPix()){
72    float avGapX = 0, avGapY = 0;
73    for(int row=0;row<ydim;row++){
74      int ct1 = 0;
75      int ct2 = xdim - 1;
76      while((ct1<ct2)&&(par.isBlank(input[row*xdim+ct1]))) ct1++;
77      while((ct2>ct1)&&(par.isBlank(input[row*xdim+ct2]))) ct2--;
78      xLim1[row] = ct1;
79      xLim2[row] = ct2;
80      avGapX += ct2 - ct1;
81    }
82    avGapX /= float(ydim);
83   
84    for(int col=0;col<xdim;col++){
85      int ct1=0;
86      int ct2=ydim-1;
87      while((ct1<ct2)&&(par.isBlank(input[col+xdim*ct1]))) ct1++;
88      while((ct2>ct1)&&(par.isBlank(input[col+xdim*ct2]))) ct2--;
89      yLim1[col] = ct1;
90      yLim2[col] = ct2;
91      avGapY += ct2 - ct1;
92    }
93    avGapY /= float(xdim);
94   
95    mindim = int(avGapX);
96    if(avGapY < avGapX) mindim = int(avGapY);
97    numScales = reconFilter.getNumScales(mindim);
98  }
99
100  float threshold;
101  int iteration=0;
102  newsigma = 1.e9;
103  for(int i=0;i<size;i++) output[i] = 0;
104  do{
105    if(par.isVerbose()) std::cout << "Iteration #"<<setw(2)<<++iteration<<":             ";
106    // first, get the value of oldsigma and set it to the previous newsigma value
107    oldsigma = newsigma;
108    // we are transforming the residual array
109    for(int i=0;i<size;i++)  coeffs[i] = input[i] - output[i]; 
110
111    int spacing = 1;
112    for(int scale = 1; scale<numScales; scale++){
113
114      if(par.isVerbose()){
115        std::cout << "Scale ";
116        std::cout << setw(2)<<scale<<" / "<<setw(2)<<numScales
117                  << "\b\b\b\b\b\b\b\b\b\b\b\b\b"<<std::flush;
118      }
119
120      for(int ypos = 0; ypos<ydim; ypos++){
121        for(int xpos = 0; xpos<xdim; xpos++){
122          // loops over each pixel in the image
123          int pos = ypos*xdim + xpos;
124         
125          wavelet[pos] = coeffs[pos];
126
127          if(!isGood[pos]) wavelet[pos] = 0.;
128          else{
129
130            int filterpos = -1;
131            for(int yoffset=-filterHW; yoffset<=filterHW; yoffset++){
132              int y = ypos + spacing*yoffset;
133              // Boundary conditions -- assume reflection at boundaries.
134              // Use limits as calculated above
135//            if(yLim1[xpos]!=yLim2[xpos]){
136//              // if these are equal we will get into an infinite loop here
137//              while((y<yLim1[xpos])||(y>yLim2[xpos])){
138//                if(y<yLim1[xpos]) y = 2*yLim1[xpos] - y;     
139//                else if(y>yLim2[xpos]) y = 2*yLim2[xpos] - y;     
140//              }
141//            }
142              int oldrow = y * xdim;
143         
144              for(int xoffset=-filterHW; xoffset<=filterHW; xoffset++){
145                int x = xpos + spacing*xoffset;
146                // Boundary conditions -- assume reflection at boundaries.
147                // Use limits as calculated above
148//              if(xLim1[ypos]!=xLim2[ypos]){
149//                // if these are equal we will get into an infinite loop here
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
156                int oldpos = oldrow + x;
157
158                float oldCoeff;
159                if((y>=yLim1[xpos])&&(y<=yLim2[xpos])&&(x>=xLim1[ypos])&&(x<=xLim2[ypos]))
160                  oldCoeff = coeffs[oldpos];
161                else oldCoeff = 0.;
162
163                filterpos++;
164
165                if(isGood[pos]) wavelet[pos] -= filter[filterpos] * oldCoeff;
166//                wavelet[pos] -= filter[filterpos] * coeffs[oldpos];
167
168              } //-> end of xoffset loop
169            } //-> end of yoffset loop
170          } //-> end of else{ ( from if(!isGood[pos])  )
171       
172        } //-> end of xpos loop
173      } //-> end of ypos loop
174
175      // Need to do this after we've done *all* the convolving
176      for(int pos=0;pos<size;pos++) coeffs[pos] = coeffs[pos] - wavelet[pos];
177
178      // Have found wavelet coeffs for this scale -- now threshold   
179      if(scale>=par.getMinScale()){
180        array = new float[size];
181        goodSize=0;
182        for(int pos=0;pos<size;pos++) if(isGood[pos]) array[goodSize++] = wavelet[pos];
183        findMedianStats(array,goodSize,mean,sigma);
184        delete [] array;
185
186        threshold = mean + par.getAtrousCut() * originalSigma * sigmaFactors[scale];
187        for(int pos=0;pos<size;pos++){
188          if(!isGood[pos]) output[pos] = blankPixValue; // preserve the Blank pixel values in the output.
189          else if( fabs(wavelet[pos]) > threshold ) output[pos] += wavelet[pos];
190        }
191      }
192      spacing *= 2;
193
194    } // END OF LOOP OVER SCALES
195
196    for(int pos=0;pos<size;pos++) if(isGood[pos]) output[pos] += coeffs[pos];
197
198    array = new float[size];
199    goodSize=0;
200    for(int i=0;i<size;i++) if(isGood[i]) array[goodSize++] = input[i] - output[i];
201    findMedianStats(array,goodSize,mean,newsigma);
202    newsigma /= correctionFactor; // correct from MADFM to sigma estimator.
203    delete [] array;
204   
205    if(par.isVerbose()) std::cout << "\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b";
206
207  } while( (iteration==1) ||
208           (fabs(oldsigma-newsigma)/newsigma > reconTolerance) );
209
210  if(par.isVerbose()) std::cout << "Completed "<<iteration<<" iterations. ";
211
212  delete [] xLim1,xLim2,yLim1,yLim2;
213  delete [] coeffs;
214  delete [] wavelet;
215  delete [] isGood;
216  delete [] filter;
217  delete [] sigmaFactors;
218}
219   
220   
Note: See TracBrowser for help on using the repository browser.