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

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

Changed all instances of fabsf to fabs so that compilation on venice works.

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