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

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

Mostly improvements to the Guide, with better formatting and descriptions of one of the changes below. The changes to the code are:

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