source: tags/release-0.9/ATrous/atrous_3d_reconstruct.cc

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

This is the first full import of all working code to
the Duchamp repository.
Made three directories at top level:

branches/ tags/ trunk/

and trunk/ has the full set of code:
ATrous/ Cubes/ Detection/ InputComplete? InputExample? README Utils/ docs/ mainDuchamp.cc param.cc param.hh

File size: 9.1 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 atrous3DReconstruct(long &xdim, long &ydim, long &zdim, float *&input,float *&output, Param &par)
11{
12  extern Filter reconFilter;
13  long size = xdim * ydim * zdim;
14  long mindim = xdim;
15  if (ydim<mindim) mindim = ydim;
16  if (zdim<mindim) mindim = zdim;
17  int numScales = reconFilter.getNumScales(mindim);
18  /*
19  if(numScales>maxNumScales3D){
20    std::cerr<<"Error in atrous3DReconstruct:: numScales ("<<numScales<<") > "<<maxNumScales3D<<"\n";
21    std::cerr<<"Don't have correction factors for this many scales...\n";
22    std::cerr<<"Exiting...\n";
23    exit(1);
24  }
25  */
26  double *sigmaFactors = new double[numScales+1];
27//   for(int i=0;i<=numScales;i++){
28//     if(i<=maxNumScales3D) sigmaFactors[i] = sigmaFactors3D[i];
29//     else sigmaFactors[i] = sigmaFactors[i-1] / sqrt(8.);
30//   }
31  for(int i=0;i<=numScales;i++){
32    if(i<=reconFilter.maxFactor(3)) sigmaFactors[i] = reconFilter.sigmaFactor(3,i);
33    else sigmaFactors[i] = sigmaFactors[i-1] / sqrt(8.);
34  }
35
36  float mean,sigma,originalSigma,originalMean,oldsigma,newsigma;
37  bool *isGood = new bool[size];
38  bool flagBlank = par.getFlagBlankPix();
39  float blankPixValue = par.getBlankPixVal();
40  for(int pos=0;pos<size;pos++) //isGood[pos] = (!flagBlank) || (input[pos]!=blankPixValue);
41    isGood[pos] = !par.isBlank(input[pos]);
42 
43  float *array = new float[size];
44  int goodSize=0;
45  for(int i=0;i<size;i++) if(isGood[i]) array[goodSize++] = input[i];
46  findMedianStats(array,goodSize,originalMean,originalSigma);
47  originalSigma /= correctionFactor; // correct from MADFM to sigma estimator.
48  delete [] array;
49
50  float *coeffs = new float[size];
51  float *wavelet = new float[size];
52
53  for(int pos=0;pos<size;pos++) output[pos]=0.;
54
55/***********************************************************************/
56/////  3-DIMENSIONAL TRANSFORM
57
58//   int filterHW = filterwidth/2;
59//   int fsize = filterwidth*filterwidth*filterwidth;
60//   double *filter = new double[fsize];
61//   for(int i=0;i<filterwidth;i++){
62//     for(int j=0;j<filterwidth;j++){
63//       for(int k=0;k<filterwidth;k++){
64//       filter[i +j*filterwidth + k*filterwidth*filterwidth] =
65//      filter1D[i] * filter1D[j] * filter1D[k];
66//       }
67//     }
68//   }
69  int filterwidth = reconFilter.width();
70  int filterHW = filterwidth/2;
71  int fsize = filterwidth*filterwidth*filterwidth;
72  double *filter = new double[fsize];
73  for(int i=0;i<filterwidth;i++){
74    for(int j=0;j<filterwidth;j++){
75      for(int k=0;k<filterwidth;k++){
76      filter[i +j*filterwidth + k*filterwidth*filterwidth] =
77        reconFilter.coeff(i) * reconFilter.coeff(j) * reconFilter.coeff(k);
78      }
79    }
80  }
81
82
83  // locating the borders of the image -- ignoring BLANK pixels
84  // HAVE NOT DONE THIS FOR Z --> ASSUMING NO TRIMMING IN SPECTRAL DIRECTION
85//   int xLim1 = 0, yLim1 = 0, xLim2 = xdim-1, yLim2 = ydim-1;
86//   for(int col=0;col<xdim;col++){
87//     while((yLim1<yLim2)&&(input[col+xdim*yLim1]==blankPixValue) ) yLim1++;
88//     while((yLim2>yLim1)&&(input[col+xdim*yLim1]==blankPixValue) ) yLim2--;
89//   }
90//   for(int row=0;row<ydim;row++){
91//     while((xLim1<xLim2)&&(input[row*xdim+xLim1]==blankPixValue) ) xLim1++;
92//     while((xLim2>xLim1)&&(input[row*xdim+xLim1]==blankPixValue) ) xLim2--;
93//   }
94  int *xLim1 = new int[ydim];
95  int *yLim1 = new int[xdim];
96  int *xLim2 = new int[ydim];
97  int *yLim2 = new int[xdim];
98  float avGapX = 0, avGapY = 0;
99  for(int row=0;row<ydim;row++){
100    int ct1 = 0;
101    int ct2 = xdim - 1;
102    while((ct1<ct2)&&(input[row*xdim+ct1]==blankPixValue) ) ct1++;
103    while((ct2>ct1)&&(input[row*xdim+ct2]==blankPixValue) ) ct2--;
104    xLim1[row] = ct1;
105    xLim2[row] = ct2;
106    avGapX += ct2 - ct1;
107  }
108  avGapX /= float(ydim);
109
110  for(int col=0;col<xdim;col++){
111    int ct1=0;
112    int ct2=ydim-1;
113    while((ct1<ct2)&&(input[col+xdim*ct1]==blankPixValue) ) ct1++;
114    while((ct2>ct1)&&(input[col+xdim*ct2]==blankPixValue) ) ct2--;
115    yLim1[col] = ct1;
116    yLim2[col] = ct2;
117    avGapY += ct2 - ct1;
118  }
119  avGapY /= float(ydim);
120 
121  mindim = int(avGapX);
122  if(avGapY < avGapX) mindim = int(avGapY);
123  numScales = reconFilter.getNumScales(mindim);
124
125  float threshold;
126  int iteration=0;
127  newsigma = 1.e9;
128  for(int i=0;i<size;i++) output[i] = 0;
129  do{
130    if(par.isVerbose())  std::cout << "Iteration #"<<setw(2)<<++iteration<<": ";
131    // first, get the value of oldsigma, set it to the previous newsigma value
132    oldsigma = newsigma;
133    // we are transforming the residual array (input array first time around)
134    for(int i=0;i<size;i++)  coeffs[i] = input[i] - output[i];
135
136    int spacing = 1;
137    for(int scale = 1; scale<=numScales; scale++){
138
139      if(par.isVerbose()){
140        std::cout << "Scale ";
141        std::cout << setw(2)<<scale<<" / "<<setw(2)<<numScales
142                  << "\b\b\b\b\b\b\b\b\b\b\b\b\b"<<std::flush;
143      }
144
145      for(int zpos = 0; zpos<zdim; zpos++){
146//      std::cout << setw(4)<<zpos<<"\b\b\b\b";
147        for(int ypos = 0; ypos<ydim; ypos++){
148          for(int xpos = 0; xpos<xdim; xpos++){
149            // loops over each pixel in the image
150            int pos = zpos*xdim*ydim + ypos*xdim + xpos;
151
152            wavelet[pos] = coeffs[pos];
153           
154            if(!isGood[pos] )  wavelet[pos] = 0.;
155            else{
156
157              for(int zoffset=-filterHW; zoffset<=filterHW; zoffset++){
158                int z = zpos + spacing*zoffset;
159                if(z<0) z = -z;                 // boundary conditions are
160                if(z>=zdim) z = 2*(zdim-1) - z; //    reflection.
161         
162                for(int yoffset=-filterHW; yoffset<=filterHW; yoffset++){
163                  int y = ypos + spacing*yoffset;
164                  //if(y<0) y = -y;                 // boundary conditions are
165                  //if(y>=ydim) y = 2*(ydim-1) - y; //    reflection.
166//                if(y<yLim1) y = 2*yLim1 - y;      // boundary conditions are
167//                if(y>yLim2) y = 2*yLim2 - y;      //    reflection.
168         
169                  for(int xoffset=-filterHW; xoffset<=filterHW; xoffset++){
170                    int x = xpos + spacing*xoffset;
171                    //if(x<0) x = -x;                 // boundary conditions are
172                    //if(x>=xdim) x = 2*(xdim-1) - x; //    reflection.
173//                  if(x<xLim1) x = 2*xLim1 - x;      // boundary conditions are
174//                  if(x>xLim2) x = 2*xLim2 - x;      //    reflection.
175
176                    // boundary conditions are reflection.
177//                  if(y<yLim1[xpos]) newy = 2*yLim1[xpos] - y;     
178//                  else if(y>yLim2[xpos]) newy = 2*yLim2[xpos] - y;     
179//                  else newy = y;
180
181                    if(yLim1[xpos]!=yLim2[xpos]){
182                      // if these are equal we will get into an infinite loop here
183                      while((y<yLim1[xpos])||(y>yLim2[xpos])){
184                        if(y<yLim1[xpos]) y = 2*yLim1[xpos] - y;     
185                        else if(y>yLim2[xpos]) y = 2*yLim2[xpos] - y;     
186                      }
187                    }
188
189//                  if(x<xLim1[ypos]) newx = 2*xLim1[ypos] - x;
190//                  else if(x>xLim2[ypos]) newx = 2*xLim2[ypos] - x;     
191//                  else newx=x;     
192
193                    if(xLim1[ypos]!=xLim2[ypos]){
194                      // if these are equal we will get into an infinite loop here
195                      while((x<xLim1[ypos])||(x>xLim2[ypos])){
196                        if(x<xLim1[ypos]) x = 2*xLim1[ypos] - x;     
197                        else if(x>xLim2[ypos]) x = 2*xLim2[ypos] - x;     
198                      }
199                    }
200
201//                  x = newx;
202//                  y = newy;
203
204                    int filterpos = (zoffset+filterHW)*filterwidth*filterwidth +
205                      (yoffset+filterHW)*filterwidth + (xoffset+filterHW);
206                    int oldpos = z*xdim*ydim + y*xdim + x;
207                    if(oldpos>=size)
208                      std::cerr<<"oldpos ("<<oldpos<<") exceeds array size("<<size<<")!\n"
209                          <<"x="<<x<<", y="<<y<<", z="<<z<<endl
210                          <<"xpos="<<xpos<<", ypos="<<ypos<<", zpos="<<zpos<<endl
211                          <<"cf. xdim="<<xdim<<", ydim="<<ydim<<", zdim="<<zdim<<endl;
212                   
213                    if(isGood[oldpos])
214                      wavelet[pos] -= filter[filterpos]*coeffs[oldpos];
215                     
216                  } //-> end of xoffset loop
217                } //-> end of yoffset loop
218              } //-> end of zoffset loop
219            } //-> end of else{ ( from if(!isGood[pos])  )
220           
221          } //-> end of xpos loop
222        } //-> end of ypos loop
223      } //-> end of zpos loop
224
225      // Need to do this after we've done *all* the convolving
226      for(int pos=0;pos<size;pos++) coeffs[pos] = coeffs[pos] - wavelet[pos];
227
228      // Have found wavelet coeffs for this scale -- now threshold
229      if(scale>=par.getMinScale()){
230        array = new float[size];
231        goodSize=0;
232        for(int pos=0;pos<size;pos++) if(isGood[pos]) array[goodSize++] = wavelet[pos];
233        findMedianStats(array,goodSize,mean,sigma);
234        delete [] array;
235       
236        threshold = mean + par.getAtrousCut() * originalSigma * sigmaFactors[scale];
237        for(int pos=0;pos<size;pos++){
238          if(!isGood[pos]) output[pos] = blankPixValue; // preserve the Blank pixel values in the output.
239          else if( fabs(wavelet[pos]) > threshold ) output[pos] += wavelet[pos];
240        }
241      }
242 
243      spacing *= 2;
244
245    } //-> end of scale loop
246
247    for(int pos=0;pos<size;pos++) if(isGood[pos]) output[pos] += coeffs[pos];
248
249    array = new float[size];
250    goodSize=0;
251    for(int i=0;i<size;i++) if(isGood[i]) array[goodSize++] = input[i] - output[i];
252    findNormalStats(array,goodSize,mean,newsigma);
253    delete [] array;
254
255    if(par.isVerbose()) std::cout << "\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b";
256
257  } while( (iteration==1) ||
258           (fabsf(oldsigma-newsigma)/newsigma > reconTolerance) );
259
260  if(par.isVerbose()) std::cout << "Completed "<<iteration<<" iterations. ";
261
262  delete [] coeffs;
263  delete [] wavelet;
264  delete [] isGood;
265  delete [] filter;
266  delete [] sigmaFactors;
267}
Note: See TracBrowser for help on using the repository browser.