source: tags/release-1.6.1/src/Cubes/trimImage.cc @ 1441

Last change on this file since 1441 was 1396, checked in by MatthewWhiting, 10 years ago

Minor improvements to the trimming output.

File size: 14.8 KB
Line 
1// -----------------------------------------------------------------------
2// trimImage.cc: Trim a Cube of BLANKs around the spatial edge.
3// -----------------------------------------------------------------------
4// Copyright (C) 2006, Matthew Whiting, ATNF
5//
6// This program is free software; you can redistribute it and/or modify it
7// under the terms of the GNU General Public License as published by the
8// Free Software Foundation; either version 2 of the License, or (at your
9// option) any later version.
10//
11// Duchamp is distributed in the hope that it will be useful, but WITHOUT
12// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14// for more details.
15//
16// You should have received a copy of the GNU General Public License
17// along with Duchamp; if not, write to the Free Software Foundation,
18// Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
19//
20// Correspondence concerning Duchamp may be directed to:
21//    Internet email: Matthew.Whiting [at] atnf.csiro.au
22//    Postal address: Dr. Matthew Whiting
23//                    Australia Telescope National Facility, CSIRO
24//                    PO Box 76
25//                    Epping NSW 1710
26//                    AUSTRALIA
27// -----------------------------------------------------------------------
28#include <iostream>
29#include <duchamp/param.hh>
30#include <duchamp/Cubes/cubes.hh>
31#include <duchamp/PixelMap/Object3D.hh>
32#include <duchamp/Detection/finders.hh>
33#include <duchamp/Utils/feedback.hh>
34
35using namespace PixelInfo;
36
37namespace duchamp
38{
39
40    void Cube::trimCube()
41    {
42
43        if(this->par.getFlagTrim()) {
44
45            size_t xdim = this->axisDim[0];
46            size_t ydim = this->axisDim[1];
47            size_t zdim = this->axisDim[2];
48            size_t spatsize=xdim*ydim;
49           
50            size_t left=0,right=xdim-1,top=ydim-1,bottom=0;
51
52            ProgressBar bar;
53            if(this->par.isVerbose()){
54              std::cout << "\n  Determining blank pixel borders... "<<std::flush;
55              bar.init(zdim);
56            }
57            std::vector<bool> rowblank(xdim,false);
58            std::vector<bool> colblank(ydim,false);
59            for (size_t z=0;z<zdim;z++){
60              if(this->par.isVerbose()) bar.update(z+1);
61                std::vector<bool> currentBlank = this->par.makeBlankMask(this->array+z*spatsize,spatsize);
62                for(size_t x=0;x<xdim;x++){
63                  for(size_t y=0;y<ydim;y++){
64                    rowblank[x] = rowblank[x] || currentBlank[x+y*xdim];
65                    colblank[y] = colblank[y] || currentBlank[x+y*xdim];
66                  }
67                }
68            }
69
70            std::vector<Scan> rowscans = spectrumDetect(rowblank,xdim,1);
71            std::vector<Scan> colscans = spectrumDetect(colblank,ydim,1);
72
73            if(this->par.isVerbose()){
74              bar.remove();
75              std::cout << "Done."<<"\n";
76            }
77
78            if (rowscans.size()>0 && colscans.size()>0){
79
80                // if these sizes are zero then there are either a row or column of blanks, and we can't trim
81
82                left=rowscans.begin()->getX();
83                right=xdim-1-rowscans.rbegin()->getXmax();
84                bottom=colscans.begin()->getX();
85                top=ydim-1-colscans.rbegin()->getXmax();
86
87                if (left>0 || right>0 || bottom > 0 || top>0 ) {
88                    // only trim if we need to - are the borders right at the edges?
89                 
90                    // Set the flag indicating trimming has taken place only if it has.
91                    this->par.setFlagCubeTrimmed(true);
92                    this->par.setBorderLeft(left);
93                    this->par.setBorderRight(right);
94                    this->par.setBorderTop(top);
95                    this->par.setBorderBottom(bottom);
96
97                    // Reset the size of the cube
98                    this->axisDim[0] = xdim - left - right;
99                    this->axisDim[1] = ydim - bottom - top;
100                    this->axisDim[2] = zdim;
101                    this->numPixels = this->axisDim[0]*this->axisDim[1]*this->axisDim[2];
102
103                    size_t oldpos,newpos;
104
105                    if(this->par.isVerbose()){
106                      std::cout << "  Trimming data arrays... " << std::flush;
107                      bar.init(4);
108                    }
109                   
110                    if(this->par.isVerbose()) bar.update(1);
111                    // Trim the array of pixel values
112                    float *newarray  = new float[this->numPixels];
113                    for(size_t x = 0; x < axisDim[0]; x++){
114                        for(size_t y = 0; y < axisDim[1]; y++){
115                            for(size_t z = 0; z < axisDim[2]; z++){
116                                oldpos = (x+left) + (y+bottom)*xdim + z*xdim*ydim;
117                                newpos = x + y*this->axisDim[0] +
118                                    z*this->axisDim[0]*this->axisDim[1];
119                                newarray[newpos]  = this->array[oldpos];
120                            }
121                        }
122                    }
123                    delete [] this->array;
124                    this->array = newarray;
125
126                    if(this->par.isVerbose()) bar.update(2);
127                    // Trim the array of baseline values
128                    if(this->par.getFlagBaseline()){
129                        float *newarray  = new float[this->numPixels];
130                        for(size_t x = 0; x < axisDim[0]; x++){
131                            for(size_t y = 0; y < axisDim[1]; y++){
132                                for(size_t z = 0; z < axisDim[2]; z++){
133                                    oldpos = (x+left) + (y+bottom)*xdim + z*xdim*ydim;
134                                    newpos = x + y*this->axisDim[0] +
135                                        z*this->axisDim[0]*this->axisDim[1];
136                                    newarray[newpos]  = this->baseline[oldpos];
137                                }
138                            }
139                        }
140                        delete [] this->baseline;
141                        this->baseline = newarray;
142                    }
143
144                    if(this->par.isVerbose()) bar.update(3);
145                    // Trim the 2-D detection map
146                    short *newdetect = new short[this->axisDim[0]*this->axisDim[1]];
147                    for(size_t x = 0; x < axisDim[0]; x++){
148                        for(size_t y = 0; y < axisDim[1]; y++){
149                            oldpos = (x+left) + (y+bottom)*xdim;
150                            newpos = x + y*this->axisDim[0];
151                            newdetect[newpos] = this->detectMap[oldpos];
152                        }
153                    }
154                    delete [] this->detectMap;
155                    this->detectMap = newdetect;
156
157                    if(this->par.isVerbose()) bar.update(4);
158                    if(this->par.getFlagATrous() || this->par.getFlagSmooth()){
159                        // Trim the reconstructed array if we are going to do the
160                        // reconstruction or smooth the array
161                        float *newrecon  = new float[this->numPixels];
162                        for(size_t x = 0; x < axisDim[0]; x++){
163                            for(size_t y = 0; y < axisDim[1]; y++){
164                                for(size_t z = 0; z < axisDim[2]; z++){
165                                    oldpos = (x+left) + (y+bottom)*xdim + z*xdim*ydim;
166                                    newpos = x + y*this->axisDim[0] +
167                                        z*this->axisDim[0]*this->axisDim[1];
168                                    newrecon[newpos] = this->recon[oldpos];       
169                                }
170                            }
171                        }
172                        delete [] this->recon;
173                        this->recon = newrecon;
174                    }
175
176                    if(this->par.isVerbose()){
177                        bar.remove();
178                        std::cout << " Done.\n";
179                    }
180
181                }
182
183            }
184
185            if(!this->par.getFlagCubeTrimmed()){
186              if(this->par.isVerbose())
187                std::cout << "  No trimming necessary."<<"\n";
188            }
189
190        }
191
192    }
193
194
195
196  // void Cube::trimCubeOld()
197  // {
198  //   /// @details
199  //   ///  If the blankPix flag has been set, this routine trims excess blank
200  //   ///    pixels from the edges of the spatial image.
201  //   ///   It uses as its template the first channel, assuming that its non-BLANK
202  //   ///    size is representative of the rest of the channels.
203  //   ///   The edges are moved in until the first non-BLANK pixel is encountered.
204  //   ///   All other arrays are similarly edited, and the amount of trimming is
205  //   ///    recorded.
206
207  //   //   if(this->par.getFlagBlankPix()) {
208  //   if(this->par.getFlagTrim()) {
209
210  //     size_t xdim = this->axisDim[0];
211  //     size_t ydim = this->axisDim[1];
212  //     size_t zdim = this->axisDim[2];
213  //     const size_t ZCHAN = 0;
214
215  //     size_t left,right,top,bottom;
216
217  //     for(size_t z = 0; z < zdim; z++){
218
219  //    for(size_t row=0;row<ydim;row++){
220  //      left=0;
221  //      right=0;
222  //      while((left<xdim)&&
223  //            (this->par.isBlank(this->array[row*xdim+left+ZCHAN*xdim*ydim])) ) {
224  //        left++;
225  //      }
226  //      while((right<xdim)&&
227  //            (this->par.isBlank(this->array[row*xdim+(xdim-1-right)+ZCHAN*xdim*ydim]))){
228  //        right++;
229  //      }
230
231  //      if( ((z==0)&&(row==0)) || (left < this->par.getBorderLeft()) )
232  //        this->par.setBorderLeft(left);
233  //      if( ((z==0)&&(row==0)) || (right < this->par.getBorderRight()) )
234  //        this->par.setBorderRight(right);
235
236  //    }
237   
238  //    for(size_t col=0;col<xdim;col++){
239  //      bottom=0;
240  //      top=0;
241  //      while((bottom<ydim)&&
242  //            (this->par.isBlank(this->array[col+bottom*xdim+ZCHAN*xdim*ydim])) ) bottom++;
243
244  //      while((top<ydim)&&
245  //            (this->par.isBlank(this->array[col+(ydim-1-top)*xdim+ZCHAN*xdim*ydim])) ) top++;
246
247  //      if( ((z==0)&&(col==0)) || (bottom < this->par.getBorderBottom()) )
248  //        this->par.setBorderBottom(bottom);
249  //      if( ((z==0)&&(col==0)) || (top < this->par.getBorderTop()) )
250  //        this->par.setBorderTop(top);
251
252  //    }
253
254  //     }
255   
256  //     left = this->par.getBorderLeft();
257  //     right = this->par.getBorderRight();
258  //     top = this->par.getBorderTop();
259  //     bottom = this->par.getBorderBottom();
260
261
262  //     size_t oldpos,newpos;
263   
264  //     // Do the trimming, but only if we need to -- is there a border of Blanks?
265  //     if(((left>0)||(right>0)||(bottom>0)||(top>0)) && (right>left) && (top>bottom)) {
266
267  //      this->axisDim[0] = xdim - left - right;
268  //      this->axisDim[1] = ydim - bottom - top;
269  //      this->axisDim[2] = zdim;
270  //      this->numPixels = this->axisDim[0]*this->axisDim[1]*this->axisDim[2];
271
272  //    // Trim the array of pixel values
273  //    float *newarray  = new float[this->numPixels];
274  //    for(size_t x = 0; x < axisDim[0]; x++){
275  //      for(size_t y = 0; y < axisDim[1]; y++){
276  //        for(size_t z = 0; z < axisDim[2]; z++){
277  //          oldpos = (x+left) + (y+bottom)*xdim + z*xdim*ydim;
278  //          newpos = x + y*this->axisDim[0] +
279  //            z*this->axisDim[0]*this->axisDim[1];
280  //          newarray[newpos]  = this->array[oldpos];
281  //        }
282  //      }
283  //    }
284  //    delete [] this->array;
285  //    this->array = newarray;
286
287  //    // Trim the array of baseline values
288  //    if(this->par.getFlagBaseline()){
289  //      float *newarray  = new float[this->numPixels];
290  //      for(size_t x = 0; x < axisDim[0]; x++){
291  //        for(size_t y = 0; y < axisDim[1]; y++){
292  //          for(size_t z = 0; z < axisDim[2]; z++){
293  //            oldpos = (x+left) + (y+bottom)*xdim + z*xdim*ydim;
294  //            newpos = x + y*this->axisDim[0] +
295  //              z*this->axisDim[0]*this->axisDim[1];
296  //            newarray[newpos]  = this->baseline[oldpos];
297  //          }
298  //        }
299  //      }
300  //      delete [] this->baseline;
301  //      this->baseline = newarray;
302  //    }
303
304  //    // Trim the 2-D detection map
305  //    short *newdetect = new short[this->axisDim[0]*this->axisDim[1]];
306  //    for(size_t x = 0; x < axisDim[0]; x++){
307  //      for(size_t y = 0; y < axisDim[1]; y++){
308  //        oldpos = (x+left) + (y+bottom)*xdim;
309  //        newpos = x + y*this->axisDim[0];
310  //        newdetect[newpos] = this->detectMap[oldpos];
311  //      }
312  //    }
313  //    delete [] this->detectMap;
314  //    this->detectMap = newdetect;
315
316  //    if(this->par.getFlagATrous() || this->par.getFlagSmooth()){
317  //      // Trim the reconstructed array if we are going to do the
318  //      // reconstruction or smooth the array
319  //      float *newrecon  = new float[this->numPixels];
320  //      for(size_t x = 0; x < axisDim[0]; x++){
321  //        for(size_t y = 0; y < axisDim[1]; y++){
322  //          for(size_t z = 0; z < axisDim[2]; z++){
323  //            oldpos = (x+left) + (y+bottom)*xdim + z*xdim*ydim;
324  //            newpos = x + y*this->axisDim[0] +
325  //              z*this->axisDim[0]*this->axisDim[1];
326  //            newrecon[newpos] = this->recon[oldpos];   
327  //          }
328  //        }
329  //      }
330  //      delete [] this->recon;
331  //      this->recon = newrecon;
332  //    }
333
334  //    // Set the flag indicating trimming has taken place only if it has.
335  //    this->par.setFlagCubeTrimmed(true);
336
337  //     }
338
339  //   }
340
341  // }
342
343
344  void Cube::unTrimCube()
345  {
346    /// @details
347    ///  If the cube has been trimmed by trimCube(), this task adds back the
348    ///   BLANK pixels on the edges, so that it returns to its original size.
349    ///   All arrays are similarly edited.
350
351    if(this->par.getFlagCubeTrimmed()){
352
353      size_t left = this->par.getBorderLeft();
354      size_t right = this->par.getBorderRight();
355      size_t top = this->par.getBorderTop();
356      size_t bottom = this->par.getBorderBottom();
357
358      size_t smallXDim = this->axisDim[0];
359      size_t smallYDim = this->axisDim[1];
360      size_t smallZDim = this->axisDim[2];
361
362      // first correct the dimension sizes
363      this->axisDim[0] = smallXDim + left + right;
364      this->axisDim[1] = smallYDim + bottom + top;
365      this->axisDim[2] = smallZDim;
366      this->numPixels = this->axisDim[0]*this->axisDim[1]*this->axisDim[2];
367
368      size_t pos,smlpos;
369      bool isDud;
370
371      // Correct the array of pixel values
372      float *newarray  = new float[this->numPixels];
373      for(size_t x = 0; x < this->axisDim[0]; x++){
374        for(size_t y = 0; y < this->axisDim[1]; y++){
375          isDud = (x<left) || (x>=smallXDim+left) ||
376            (y<bottom) || (y>=smallYDim+bottom);
377       
378          for(size_t z = 0; z < this->axisDim[2]; z++){
379            pos = x + y*this->axisDim[0] + z*this->axisDim[0]*this->axisDim[1];
380            smlpos = (x-left) + (y-bottom)*smallXDim + z * smallXDim * smallYDim;
381            if(isDud) newarray[pos] = this->par.getBlankPixVal();
382            else      newarray[pos] = this->array[smlpos];
383          }
384        }
385      }
386      delete [] this->array;
387      this->array = newarray;
388
389      if(this->reconExists){
390        // Correct the reconstructed/smoothed array
391        float *newrecon   = new float[this->numPixels];
392        for(size_t x = 0; x < this->axisDim[0]; x++){
393          for(size_t y = 0; y < this->axisDim[1]; y++){
394            isDud = (x<left) || (x>=smallXDim+left) ||
395              (y<bottom) || (y>=smallYDim+bottom);
396         
397            for(size_t z = 0; z < this->axisDim[2]; z++){
398              pos = x + y*this->axisDim[0] + z*this->axisDim[0]*this->axisDim[1];
399              smlpos = (x-left) + (y-bottom)*smallXDim
400                + z * smallXDim * smallYDim;
401              if(isDud) newrecon[pos] = this->par.getBlankPixVal();
402              else      newrecon[pos] = this->recon[smlpos];
403            }
404          }
405        }
406        delete [] this->recon;
407        this->recon = newrecon;
408      }
409
410      // Correct the array of baseline values
411      if(this->par.getFlagBaseline()){
412        float *newbase  = new float[this->numPixels];
413        for(size_t x = 0; x < this->axisDim[0]; x++){
414          for(size_t y = 0; y < this->axisDim[1]; y++){
415            isDud = (x<left) || (x>=smallXDim+left) ||
416              (y<bottom) || (y>=smallYDim+bottom);
417       
418            for(size_t z = 0; z < this->axisDim[2]; z++){
419              pos = x + y*this->axisDim[0] + z*this->axisDim[0]*this->axisDim[1];
420              smlpos = (x-left) + (y-bottom)*smallXDim + z*smallXDim*smallYDim;
421              if(isDud) newbase[pos] = this->par.getBlankPixVal();
422              else      newbase[pos] = this->baseline[smlpos];
423            }
424          }
425        }
426        delete [] this->baseline;
427        this->baseline = newbase;
428      }
429
430      // Correct the 2-D detection map
431      short *newdetect = new short[this->axisDim[0]*this->axisDim[1]];
432      for(size_t x = 0; x < this->axisDim[0]; x++){
433        for(size_t y = 0; y < this->axisDim[1]; y++){
434          pos = x + y*this->axisDim[0];
435          smlpos = (x-left) + (y-bottom)*smallXDim;
436          isDud = (x<left) || (x>=smallXDim+left) ||
437            (y<bottom) || (y>=smallYDim+bottom);
438          if(isDud) newdetect[pos]=0;
439          else newdetect[pos] = this->detectMap[smlpos];
440        }
441      }
442      delete [] this->detectMap;
443      this->detectMap = newdetect;   
444
445 
446      // Now update the positions for all the detections
447 
448      std::vector<Detection>::iterator obj;
449      for(obj=this->objectList->begin();obj<this->objectList->end();obj++){
450        obj->addOffsets(left,bottom,0);
451      }
452
453    }
454
455  }
456
457}
Note: See TracBrowser for help on using the repository browser.