source: tags/release-1.2.2/src/Cubes/trimImage.cc

Last change on this file was 935, checked in by MatthewWhiting, 12 years ago

A bunch of int --> size_t conversions.

File size: 9.5 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
33using namespace PixelInfo;
34
35namespace duchamp
36{
37
38  void Cube::trimCube()
39  {
40    /// @details
41    ///  If the blankPix flag has been set, this routine trims excess blank
42    ///    pixels from the edges of the spatial image.
43    ///   It uses as its template the first channel, assuming that its non-BLANK
44    ///    size is representative of the rest of the channels.
45    ///   The edges are moved in until the first non-BLANK pixel is encountered.
46    ///   All other arrays are similarly edited, and the amount of trimming is
47    ///    recorded.
48
49    //   if(this->par.getFlagBlankPix()) {
50    if(this->par.getFlagTrim()) {
51
52      size_t xdim = this->axisDim[0];
53      size_t ydim = this->axisDim[1];
54      size_t zdim = this->axisDim[2];
55      const size_t ZCHAN = 0;
56
57      size_t left,right,top,bottom;
58
59      for(size_t z = 0; z < zdim; z++){
60
61        for(size_t row=0;row<ydim;row++){
62          left=0;
63          right=0;
64          while((left<xdim)&&
65                (this->par.isBlank(this->array[row*xdim+left+ZCHAN*xdim*ydim])) ) {
66            left++;
67          }
68          while((right<xdim)&&
69                (this->par.isBlank(this->array[row*xdim+(xdim-1-right)+ZCHAN*xdim*ydim]))){
70            right++;
71          }
72
73          if( ((z==0)&&(row==0)) || (left < this->par.getBorderLeft()) )
74            this->par.setBorderLeft(left);
75          if( ((z==0)&&(row==0)) || (right < this->par.getBorderRight()) )
76            this->par.setBorderRight(right);
77
78        }
79   
80        for(size_t col=0;col<xdim;col++){
81          bottom=0;
82          top=0;
83          while((bottom<ydim)&&
84                (this->par.isBlank(this->array[col+bottom*xdim+ZCHAN*xdim*ydim])) ) bottom++;
85
86          while((top<ydim)&&
87                (this->par.isBlank(this->array[col+(ydim-1-top)*xdim+ZCHAN*xdim*ydim])) ) top++;
88
89          if( ((z==0)&&(col==0)) || (bottom < this->par.getBorderBottom()) )
90            this->par.setBorderBottom(bottom);
91          if( ((z==0)&&(col==0)) || (top < this->par.getBorderTop()) )
92            this->par.setBorderTop(top);
93
94        }
95
96      }
97   
98      left = this->par.getBorderLeft();
99      right = this->par.getBorderRight();
100      top = this->par.getBorderTop();
101      bottom = this->par.getBorderBottom();
102
103      this->axisDim[0] = xdim - left - right;
104      this->axisDim[1] = ydim - bottom - top;
105      this->axisDim[2] = zdim;
106      this->numPixels = this->axisDim[0]*this->axisDim[1]*this->axisDim[2];
107
108      size_t oldpos,newpos;
109   
110      // Do the trimming, but only if we need to -- is there a border of Blanks?
111      if((left>0)||(right>0)||(bottom>0)||(top>0)) {
112
113        // Trim the array of pixel values
114        float *newarray  = new float[this->numPixels];
115        for(size_t x = 0; x < axisDim[0]; x++){
116          for(size_t y = 0; y < axisDim[1]; y++){
117            for(size_t z = 0; z < axisDim[2]; z++){
118              oldpos = (x+left) + (y+bottom)*xdim + z*xdim*ydim;
119              newpos = x + y*this->axisDim[0] +
120                z*this->axisDim[0]*this->axisDim[1];
121              newarray[newpos]  = this->array[oldpos];
122            }
123          }
124        }
125        delete [] this->array;
126        this->array = newarray;
127
128        // Trim the array of baseline values
129        if(this->par.getFlagBaseline()){
130          float *newarray  = new float[this->numPixels];
131          for(size_t x = 0; x < axisDim[0]; x++){
132            for(size_t y = 0; y < axisDim[1]; y++){
133              for(size_t z = 0; z < axisDim[2]; z++){
134                oldpos = (x+left) + (y+bottom)*xdim + z*xdim*ydim;
135                newpos = x + y*this->axisDim[0] +
136                  z*this->axisDim[0]*this->axisDim[1];
137                newarray[newpos]  = this->baseline[oldpos];
138              }
139            }
140          }
141          delete [] this->baseline;
142          this->baseline = newarray;
143        }
144
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.getFlagATrous() || this->par.getFlagSmooth()){
158          // Trim the reconstructed array if we are going to do the
159          // reconstruction or smooth the array
160          float *newrecon  = new float[this->numPixels];
161          for(size_t x = 0; x < axisDim[0]; x++){
162            for(size_t y = 0; y < axisDim[1]; y++){
163              for(size_t z = 0; z < axisDim[2]; z++){
164                oldpos = (x+left) + (y+bottom)*xdim + z*xdim*ydim;
165                newpos = x + y*this->axisDim[0] +
166                  z*this->axisDim[0]*this->axisDim[1];
167                newrecon[newpos] = this->recon[oldpos];   
168              }
169            }
170          }
171          delete [] this->recon;
172          this->recon = newrecon;
173        }
174
175        // Set the flag indicating trimming has taken place only if it has.
176        this->par.setFlagCubeTrimmed(true);
177
178      }
179
180    }
181
182  }
183
184
185  void Cube::unTrimCube()
186  {
187    /// @details
188    ///  If the cube has been trimmed by trimCube(), this task adds back the
189    ///   BLANK pixels on the edges, so that it returns to its original size.
190    ///   All arrays are similarly edited.
191
192    if(this->par.getFlagCubeTrimmed()){
193
194      size_t left = this->par.getBorderLeft();
195      size_t right = this->par.getBorderRight();
196      size_t top = this->par.getBorderTop();
197      size_t bottom = this->par.getBorderBottom();
198
199      size_t smallXDim = this->axisDim[0];
200      size_t smallYDim = this->axisDim[1];
201      size_t smallZDim = this->axisDim[2];
202
203      // first correct the dimension sizes
204      this->axisDim[0] = smallXDim + left + right;
205      this->axisDim[1] = smallYDim + bottom + top;
206      this->axisDim[2] = smallZDim;
207      this->numPixels = this->axisDim[0]*this->axisDim[1]*this->axisDim[2];
208
209      size_t pos,smlpos;
210      bool isDud;
211
212      // Correct the array of pixel values
213      float *newarray  = new float[this->numPixels];
214      for(size_t x = 0; x < this->axisDim[0]; x++){
215        for(size_t y = 0; y < this->axisDim[1]; y++){
216          isDud = (x<left) || (x>=smallXDim+left) ||
217            (y<bottom) || (y>=smallYDim+bottom);
218       
219          for(size_t z = 0; z < this->axisDim[2]; z++){
220            pos = x + y*this->axisDim[0] + z*this->axisDim[0]*this->axisDim[1];
221            smlpos = (x-left) + (y-bottom)*smallXDim + z * smallXDim * smallYDim;
222            if(isDud) newarray[pos] = this->par.getBlankPixVal();
223            else      newarray[pos] = this->array[smlpos];
224          }
225        }
226      }
227      delete [] this->array;
228      this->array = newarray;
229
230      if(this->reconExists){
231        // Correct the reconstructed/smoothed array
232        float *newrecon   = new float[this->numPixels];
233        for(size_t x = 0; x < this->axisDim[0]; x++){
234          for(size_t y = 0; y < this->axisDim[1]; y++){
235            isDud = (x<left) || (x>=smallXDim+left) ||
236              (y<bottom) || (y>=smallYDim+bottom);
237         
238            for(size_t z = 0; z < this->axisDim[2]; z++){
239              pos = x + y*this->axisDim[0] + z*this->axisDim[0]*this->axisDim[1];
240              smlpos = (x-left) + (y-bottom)*smallXDim
241                + z * smallXDim * smallYDim;
242              if(isDud) newrecon[pos] = this->par.getBlankPixVal();
243              else      newrecon[pos] = this->recon[smlpos];
244            }
245          }
246        }
247        delete [] this->recon;
248        this->recon = newrecon;
249      }
250
251      // Correct the array of baseline values
252      if(this->par.getFlagBaseline()){
253        float *newbase  = new float[this->numPixels];
254        for(size_t x = 0; x < this->axisDim[0]; x++){
255          for(size_t y = 0; y < this->axisDim[1]; y++){
256            isDud = (x<left) || (x>=smallXDim+left) ||
257              (y<bottom) || (y>=smallYDim+bottom);
258       
259            for(size_t z = 0; z < this->axisDim[2]; z++){
260              pos = x + y*this->axisDim[0] + z*this->axisDim[0]*this->axisDim[1];
261              smlpos = (x-left) + (y-bottom)*smallXDim + z*smallXDim*smallYDim;
262              if(isDud) newbase[pos] = this->par.getBlankPixVal();
263              else      newbase[pos] = this->baseline[smlpos];
264            }
265          }
266        }
267        delete [] this->baseline;
268        this->baseline = newbase;
269      }
270
271      // Correct the 2-D detection map
272      short *newdetect = new short[this->axisDim[0]*this->axisDim[1]];
273      for(size_t x = 0; x < this->axisDim[0]; x++){
274        for(size_t y = 0; y < this->axisDim[1]; y++){
275          pos = x + y*this->axisDim[0];
276          smlpos = (x-left) + (y-bottom)*smallXDim;
277          isDud = (x<left) || (x>=smallXDim+left) ||
278            (y<bottom) || (y>=smallYDim+bottom);
279          if(isDud) newdetect[pos]=0;
280          else newdetect[pos] = this->detectMap[smlpos];
281        }
282      }
283      delete [] this->detectMap;
284      this->detectMap = newdetect;   
285
286 
287      // Now update the positions for all the detections
288 
289      std::vector<Detection>::iterator obj;
290      for(obj=this->objectList->begin();obj<this->objectList->end();obj++){
291        obj->addOffsets(left,bottom,0);
292      }
293
294    }
295
296  }
297
298}
Note: See TracBrowser for help on using the repository browser.