source: tags/release-1.0.7/src/ATrous/atrous_1d_reconstruct.cc

Last change on this file was 213, checked in by Matthew Whiting, 18 years ago

Summary:

  • Fixed the scale bar plotting for the spectral output, so that it can deal properly with very fine angular scales.
    • Improved the loop in Cube::drawScale
    • Included code in angularSeparation to deal with finely-separated positions.
  • Moved the ProgressBar? class to a new header file Utils/feedback.hh from duchamp.hh
    • Updated #include statements in many files
  • Fixed allocation bug in param copy constructor (related to offsets array).
File size: 4.7 KB
Line 
1#include <iostream>
2#include <iomanip>
3#include <math.h>
4#include <Utils/utils.hh>
5#include <Utils/feedback.hh>
6#include <ATrous/atrous.hh>
7#include <Utils/Statistics.hh>
8using Statistics::madfmToSigma;
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))
35      sigmaFactors[i] = reconFilter.sigmaFactor(1,i);
36    else sigmaFactors[i] = sigmaFactors[i-1] / sqrt(2.);
37  }
38
39  float mean,sigma,originalSigma,originalMean,oldsigma,newsigma;
40  bool *isGood = new bool[xdim];
41  for(int pos=0;pos<xdim;pos++)
42    isGood[pos] = !par.isBlank(input[pos]);
43
44  float *coeffs = new float[xdim];
45  float *wavelet = new float[xdim];
46
47  for(int pos=0;pos<xdim;pos++) output[pos]=0.;
48
49  int filterHW = reconFilter.width()/2;
50  double *filter = new double[reconFilter.width()];
51  for(int i=0;i<reconFilter.width();i++) filter[i] = reconFilter.coeff(i);
52
53
54  // No trimming done in 1D case.
55
56  int iteration=0;
57  newsigma = 1.e9;
58  do{
59    if(par.isVerbose()) {
60      std::cout << "Iteration #"<<++iteration<<":";
61      printSpace(13);
62    }
63    // first, get the value of oldsigma and set it to the previous
64    //   newsigma value
65    oldsigma = newsigma;
66    // all other times round, we are transforming the residual array
67    for(int i=0;i<xdim;i++)  coeffs[i] = input[i] - output[i];
68   
69    float *array = new float[xdim];
70    int goodSize=0;
71    for(int i=0;i<xdim;i++) if(isGood[i]) array[goodSize++] = input[i];
72    findMedianStats(array,goodSize,originalMean,originalSigma);
73    originalSigma = madfmToSigma(originalSigma);
74    delete [] array;
75
76    int spacing = 1;
77    for(int scale = 1; scale<=numScales; scale++){
78
79      if(par.isVerbose()) {
80        printBackSpace(12);
81        std::cout << "Scale " << std::setw(2) << scale
82                  << " /"     << std::setw(2) << numScales <<std::flush;
83      }
84
85      for(int xpos = 0; xpos<xdim; xpos++){
86            // loops over each pixel in the image
87        int pos = xpos;
88
89        wavelet[pos] = coeffs[pos];
90       
91        if(!isGood[pos] )  wavelet[pos] = 0.;
92        else{
93
94          for(int xoffset=-filterHW; xoffset<=filterHW; xoffset++){
95            int x = xpos + spacing*xoffset;
96
97            while((x<0)||(x>=xdim)){
98              if(x<0) x = 0 - x;                    // boundary conditions are
99              else if(x>=xdim) x = 2*(xdim-1) - x;  //    reflection.
100            }
101
102            int filterpos = (xoffset+filterHW);
103            int oldpos = x;
104
105            if(isGood[oldpos])
106              wavelet[pos] -= filter[filterpos]*coeffs[oldpos];
107             
108          } //-> end of xoffset loop
109        } //-> end of else{ ( from if(!isGood[pos])  )
110           
111      } //-> end of xpos loop
112
113      // Need to do this after we've done *all* the convolving
114      for(int pos=0;pos<xdim;pos++) coeffs[pos] = coeffs[pos] - wavelet[pos];
115
116      // Have found wavelet coeffs for this scale -- now threshold
117      if(scale>=MIN_SCALE){
118        array = new float[xdim];
119        goodSize=0;
120        for(int pos=0;pos<xdim;pos++)
121          if(isGood[pos]) array[goodSize++] = wavelet[pos];
122        findMedianStats(array,goodSize,mean,sigma);
123        delete [] array;
124       
125        for(int pos=0;pos<xdim;pos++){
126          // preserve the Blank pixel values in the output.
127          if(!isGood[pos]) output[pos] = blankPixValue;
128          else if( fabs(wavelet[pos]) >
129                   (mean+SNR_THRESH*originalSigma*sigmaFactors[scale]) )
130            output[pos] += wavelet[pos];
131        }
132      }
133 
134      spacing *= 2;
135
136    } //-> end of scale loop
137
138    for(int pos=0;pos<xdim;pos++) if(isGood[pos]) output[pos] += coeffs[pos];
139
140    array = new float[xdim];
141    goodSize=0;
142    for(int i=0;i<xdim;i++)
143      if(isGood[i]) array[goodSize++] = input[i] - output[i];
144    findMedianStats(array,goodSize,mean,newsigma);
145    newsigma = madfmToSigma(newsigma);
146    delete [] array;
147
148    if(par.isVerbose()) printBackSpace(26);
149
150  } while( (iteration==1) ||
151           (fabs(oldsigma-newsigma)/newsigma > reconTolerance) );
152
153  if(par.isVerbose()) std::cout << "Completed "<<iteration<<" iterations. ";
154
155  delete [] coeffs;
156  delete [] wavelet;
157  delete [] isGood;
158  delete [] filter;
159  delete [] sigmaFactors;
160}
Note: See TracBrowser for help on using the repository browser.