source: trunk/src/ATrous/atrous_2d_reconstruct.cc @ 270

Last change on this file since 270 was 270, checked in by Matthew Whiting, 17 years ago

A large set of changes, each of which small ones from compiling with the -Wall flag (plus the -Wno-sign-compare flag -- as we don't care about warnings about comparing ints and unsigned ints).

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