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

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

Introduced some simple inline functions to duchamp.hh to make the printing of progress bars simpler and of a more unified fashion.

File size: 4.7 KB
Line 
1#include <iostream>
2#include <iomanip>
3#include <math.h>
4#include <duchamp.hh>
5#include <ATrous/atrous.hh>
6#include <Utils/utils.hh>
7
8using std::endl;
9using std::setw;
10
11void atrous1DReconstruct(long &xdim, float *&input,float *&output, Param &par)
12{
13  /**
14   *  atrous1DReconstruct(xdim, input, output, par)
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, although a Filter object has to be declared
20   *   elsewhere previously.
21   *  The input array is in "input", of length "xdim", and the reconstructed
22   *   array is in "output".
23   */
24
25
26  extern Filter reconFilter;
27  const float SNR_THRESH=par.getAtrousCut();
28  const int MIN_SCALE=par.getMinScale();
29
30  bool flagBlank=par.getFlagBlankPix();
31  float blankPixValue = par.getBlankPixVal();
32  int numScales = reconFilter.getNumScales(xdim);
33  double *sigmaFactors = new double[numScales+1];
34  for(int i=0;i<=numScales;i++){
35    if(i<=reconFilter.maxFactor(1))
36      sigmaFactors[i] = reconFilter.sigmaFactor(1,i);
37    else sigmaFactors[i] = sigmaFactors[i-1] / sqrt(2.);
38  }
39
40  float mean,sigma,originalSigma,originalMean,oldsigma,newsigma;
41  bool *isGood = new bool[xdim];
42  for(int pos=0;pos<xdim;pos++)
43    isGood[pos] = !par.isBlank(input[pos]);
44
45  float *coeffs = new float[xdim];
46  float *wavelet = new float[xdim];
47
48  for(int pos=0;pos<xdim;pos++) output[pos]=0.;
49
50  int filterHW = reconFilter.width()/2;
51  double *filter = new double[reconFilter.width()];
52  for(int i=0;i<reconFilter.width();i++) filter[i] = reconFilter.coeff(i);
53
54
55  // No trimming done in 1D case.
56
57  int iteration=0;
58  newsigma = 1.e9;
59  do{
60    if(par.isVerbose()) {
61      std::cout << "Iteration #"<<++iteration<<":";
62      printSpace(13);
63    }
64    // first, get the value of oldsigma and set it to the previous
65    //   newsigma value
66    oldsigma = newsigma;
67    // all other times round, we are transforming the residual array
68    for(int i=0;i<xdim;i++)  coeffs[i] = input[i] - output[i];
69   
70    float *array = new float[xdim];
71    int goodSize=0;
72    for(int i=0;i<xdim;i++) if(isGood[i]) array[goodSize++] = input[i];
73    findMedianStats(array,goodSize,originalMean,originalSigma);
74    originalSigma /= correctionFactor; // correct from MADFM to sigma estimator
75    delete [] array;
76
77    int spacing = 1;
78    for(int scale = 1; scale<=numScales; scale++){
79
80      if(par.isVerbose()) {
81        printBackSpace(12);
82        std::cout << "Scale " << setw(2) << scale
83                  << " /"     <<setw(2)  << numScales <<std::flush;
84      }
85
86      for(int xpos = 0; xpos<xdim; xpos++){
87            // loops over each pixel in the image
88        int pos = xpos;
89
90        wavelet[pos] = coeffs[pos];
91       
92        if(!isGood[pos] )  wavelet[pos] = 0.;
93        else{
94
95          for(int xoffset=-filterHW; xoffset<=filterHW; xoffset++){
96            int x = xpos + spacing*xoffset;
97
98            while((x<0)||(x>=xdim)){
99              if(x<0) x = 0 - x;                    // boundary conditions are
100              else if(x>=xdim) x = 2*(xdim-1) - x;  //    reflection.
101            }
102
103            int filterpos = (xoffset+filterHW);
104            int oldpos = x;
105
106            if(isGood[oldpos])
107              wavelet[pos] -= filter[filterpos]*coeffs[oldpos];
108             
109          } //-> end of xoffset loop
110        } //-> end of else{ ( from if(!isGood[pos])  )
111           
112      } //-> end of xpos loop
113
114      // Need to do this after we've done *all* the convolving
115      for(int pos=0;pos<xdim;pos++) coeffs[pos] = coeffs[pos] - wavelet[pos];
116
117      // Have found wavelet coeffs for this scale -- now threshold
118      if(scale>=MIN_SCALE){
119        array = new float[xdim];
120        goodSize=0;
121        for(int pos=0;pos<xdim;pos++)
122          if(isGood[pos]) array[goodSize++] = wavelet[pos];
123        findMedianStats(array,goodSize,mean,sigma);
124        delete [] array;
125       
126        for(int pos=0;pos<xdim;pos++){
127          // preserve the Blank pixel values in the output.
128          if(!isGood[pos]) output[pos] = blankPixValue;
129          else if( fabs(wavelet[pos]) >
130                   (mean+SNR_THRESH*originalSigma*sigmaFactors[scale]) )
131            output[pos] += wavelet[pos];
132        }
133      }
134 
135      spacing *= 2;
136
137    } //-> end of scale loop
138
139    for(int pos=0;pos<xdim;pos++) if(isGood[pos]) output[pos] += coeffs[pos];
140
141    array = new float[xdim];
142    goodSize=0;
143    for(int i=0;i<xdim;i++)
144      if(isGood[i]) array[goodSize++] = input[i] - output[i];
145    findMedianStats(array,goodSize,mean,newsigma);
146    newsigma /= correctionFactor; // correct from MADFM to sigma estimator.
147    delete [] array;
148
149    if(par.isVerbose()) printBackSpace(26);
150
151  } while( (iteration==1) ||
152           (fabs(oldsigma-newsigma)/newsigma > reconTolerance) );
153
154  if(par.isVerbose()) std::cout << "Completed "<<iteration<<" iterations. ";
155
156  delete [] coeffs;
157  delete [] wavelet;
158  delete [] isGood;
159  delete [] filter;
160  delete [] sigmaFactors;
161}
Note: See TracBrowser for help on using the repository browser.