source: trunk/src/ATrous/atrous_1d_reconstruct.cc @ 274

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

Largely just cleaning up #include and "using namespace" statements to prevent unnecessary declarations.

File size: 5.2 KB
Line 
1#include <iostream>
2#include <iomanip>
3#include <math.h>
4#include <duchamp.hh>
5#include <param.hh>
6#include <Utils/utils.hh>
7#include <Utils/feedback.hh>
8#include <ATrous/atrous.hh>
9#include <ATrous/filter.hh>
10#include <Utils/Statistics.hh>
11using Statistics::madfmToSigma;
12
13void atrous1DReconstruct(long &xdim, float *&input, float *&output, Param &par)
14{
15  /**
16   *  A routine that uses the a trous wavelet method to reconstruct a
17   *   1-dimensional spectrum.
18   *  The Param object "par" contains all necessary info about the filter and
19   *   reconstruction parameters.
20   *
21   *  If all pixels are BLANK (and we are testing for BLANKs), the
22   *  reconstruction will simply give BLANKs back, so we return the
23   *  input array as the output array.
24   *
25   *  \param xdim The length of the spectrum.
26   *  \param input The input spectrum.
27   *  \param output The returned reconstructed spectrum. This array needs to
28   *    be declared beforehand.
29   *  \param par The Param set.
30   */
31
32  const float SNR_THRESH=par.getAtrousCut();
33  const int MIN_SCALE=par.getMinScale();
34
35  float blankPixValue = par.getBlankPixVal();
36  int numScales = par.filter().getNumScales(xdim);
37  double *sigmaFactors = new double[numScales+1];
38  for(int i=0;i<=numScales;i++){
39    if(i<=par.filter().maxFactor(1))
40      sigmaFactors[i] = par.filter().sigmaFactor(1,i);
41    else sigmaFactors[i] = sigmaFactors[i-1] / sqrt(2.);
42  }
43
44  float mean,sigma,originalSigma,originalMean,oldsigma,newsigma;
45  bool *isGood = new bool[xdim];
46  int goodSize=0;
47  for(int pos=0;pos<xdim;pos++) {
48    isGood[pos] = !par.isBlank(input[pos]);
49    if(isGood[pos]) goodSize++;
50  }
51
52  if(goodSize == 0){
53    // There are no good pixels -- everything is BLANK for some reason.
54    // Return the input array as the output.
55
56    for(int pos=0;pos<xdim; pos++) output[pos] = input[pos];
57
58  }
59  else{
60    // Otherwise, all is good, and we continue.
61
62
63    float *coeffs = new float[xdim];
64    float *wavelet = new float[xdim];
65
66    for(int pos=0;pos<xdim;pos++) output[pos]=0.;
67
68    int filterHW = par.filter().width()/2;
69    double *filter = new double[par.filter().width()];
70    for(int i=0;i<par.filter().width();i++) filter[i] = par.filter().coeff(i);
71
72
73    // No trimming done in 1D case.
74
75    int iteration=0;
76    newsigma = 1.e9;
77    do{
78      if(par.isVerbose()) {
79        std::cout << "Iteration #"<<++iteration<<":";
80        printSpace(13);
81      }
82      // first, get the value of oldsigma and set it to the previous
83      //   newsigma value
84      oldsigma = newsigma;
85      // all other times round, we are transforming the residual array
86      for(int i=0;i<xdim;i++)  coeffs[i] = input[i] - output[i];
87   
88      float *array = new float[xdim];
89      goodSize=0;
90      for(int i=0;i<xdim;i++) if(isGood[i]) array[goodSize++] = input[i];
91      findMedianStats(array,goodSize,originalMean,originalSigma);
92      originalSigma = madfmToSigma(originalSigma);
93      delete [] array;
94
95      int spacing = 1;
96      for(int scale = 1; scale<=numScales; scale++){
97
98        if(par.isVerbose()) {
99          printBackSpace(12);
100          std::cout << "Scale " << std::setw(2) << scale
101                    << " /"     << std::setw(2) << numScales <<std::flush;
102        }
103
104        for(int xpos = 0; xpos<xdim; xpos++){
105          // loops over each pixel in the image
106          int pos = xpos;
107
108          wavelet[pos] = coeffs[pos];
109       
110          if(!isGood[pos] )  wavelet[pos] = 0.;
111          else{
112
113            for(int xoffset=-filterHW; xoffset<=filterHW; xoffset++){
114              int x = xpos + spacing*xoffset;
115
116              while((x<0)||(x>=xdim)){
117                // boundary conditions are reflection.
118                if(x<0) x = 0 - x;
119                else if(x>=xdim) x = 2*(xdim-1) - x;
120              }
121
122              int filterpos = (xoffset+filterHW);
123              int oldpos = x;
124
125              if(isGood[oldpos])
126                wavelet[pos] -= filter[filterpos]*coeffs[oldpos];
127             
128            } //-> end of xoffset loop
129          } //-> end of else{ ( from if(!isGood[pos])  )
130           
131        } //-> end of xpos loop
132
133        // Need to do this after we've done *all* the convolving
134        for(int pos=0;pos<xdim;pos++) coeffs[pos] = coeffs[pos] - wavelet[pos];
135
136        // Have found wavelet coeffs for this scale -- now threshold
137        if(scale>=MIN_SCALE){
138          array = new float[xdim];
139          goodSize=0;
140          for(int pos=0;pos<xdim;pos++)
141            if(isGood[pos]) array[goodSize++] = wavelet[pos];
142          findMedianStats(array,goodSize,mean,sigma);
143          delete [] array;
144       
145          for(int pos=0;pos<xdim;pos++){
146            // preserve the Blank pixel values in the output.
147            if(!isGood[pos]) output[pos] = blankPixValue;
148            else if( fabs(wavelet[pos]) >
149                     (mean+SNR_THRESH*originalSigma*sigmaFactors[scale]) )
150              output[pos] += wavelet[pos];
151          }
152        }
153 
154        spacing *= 2;
155
156      } //-> end of scale loop
157
158      for(int pos=0;pos<xdim;pos++) if(isGood[pos]) output[pos] += coeffs[pos];
159
160      array = new float[xdim];
161      goodSize=0;
162      for(int i=0;i<xdim;i++)
163        if(isGood[i]) array[goodSize++] = input[i] - output[i];
164      findMedianStats(array,goodSize,mean,newsigma);
165      newsigma = madfmToSigma(newsigma);
166      delete [] array;
167
168      if(par.isVerbose()) printBackSpace(26);
169
170    } while( (iteration==1) ||
171             (fabs(oldsigma-newsigma)/newsigma > reconTolerance) );
172
173    if(par.isVerbose()) std::cout << "Completed "<<iteration<<" iterations. ";
174
175    delete [] filter;
176    delete [] coeffs;
177    delete [] wavelet;
178
179  }
180
181  delete [] isGood;
182  delete [] sigmaFactors;
183}
Note: See TracBrowser for help on using the repository browser.