source: branches/pixel-map-branch/src/ATrous/atrous_1d_reconstruct.cc @ 1441

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

Large raft of changes. Most are minor ones related to fixing up the use of std::string and std::vector (whether they are declared as using, or not...). Other changes include:

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