source: trunk/src/Cubes/trimImage.cc @ 1392

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

Trying to fix problem with trimming where we can trim off everything.

File size: 9.6 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
104      size_t oldpos,newpos;
105   
106      // Do the trimming, but only if we need to -- is there a border of Blanks?
107      if(((left>0)||(right>0)||(bottom>0)||(top>0)) && (right>left) && (top>bottom)) {
108
109          this->axisDim[0] = xdim - left - right;
110          this->axisDim[1] = ydim - bottom - top;
111          this->axisDim[2] = zdim;
112          this->numPixels = this->axisDim[0]*this->axisDim[1]*this->axisDim[2];
113
114        // Trim the array of pixel values
115        float *newarray  = new float[this->numPixels];
116        for(size_t x = 0; x < axisDim[0]; x++){
117          for(size_t y = 0; y < axisDim[1]; y++){
118            for(size_t z = 0; z < axisDim[2]; z++){
119              oldpos = (x+left) + (y+bottom)*xdim + z*xdim*ydim;
120              newpos = x + y*this->axisDim[0] +
121                z*this->axisDim[0]*this->axisDim[1];
122              newarray[newpos]  = this->array[oldpos];
123            }
124          }
125        }
126        delete [] this->array;
127        this->array = newarray;
128
129        // Trim the array of baseline values
130        if(this->par.getFlagBaseline()){
131          float *newarray  = new float[this->numPixels];
132          for(size_t x = 0; x < axisDim[0]; x++){
133            for(size_t y = 0; y < axisDim[1]; y++){
134              for(size_t z = 0; z < axisDim[2]; z++){
135                oldpos = (x+left) + (y+bottom)*xdim + z*xdim*ydim;
136                newpos = x + y*this->axisDim[0] +
137                  z*this->axisDim[0]*this->axisDim[1];
138                newarray[newpos]  = this->baseline[oldpos];
139              }
140            }
141          }
142          delete [] this->baseline;
143          this->baseline = newarray;
144        }
145
146        // Trim the 2-D detection map
147        short *newdetect = new short[this->axisDim[0]*this->axisDim[1]];
148        for(size_t x = 0; x < axisDim[0]; x++){
149          for(size_t y = 0; y < axisDim[1]; y++){
150            oldpos = (x+left) + (y+bottom)*xdim;
151            newpos = x + y*this->axisDim[0];
152            newdetect[newpos] = this->detectMap[oldpos];
153          }
154        }
155        delete [] this->detectMap;
156        this->detectMap = newdetect;
157
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        // Set the flag indicating trimming has taken place only if it has.
177        this->par.setFlagCubeTrimmed(true);
178
179      }
180
181    }
182
183  }
184
185
186  void Cube::unTrimCube()
187  {
188    /// @details
189    ///  If the cube has been trimmed by trimCube(), this task adds back the
190    ///   BLANK pixels on the edges, so that it returns to its original size.
191    ///   All arrays are similarly edited.
192
193    if(this->par.getFlagCubeTrimmed()){
194
195      size_t left = this->par.getBorderLeft();
196      size_t right = this->par.getBorderRight();
197      size_t top = this->par.getBorderTop();
198      size_t bottom = this->par.getBorderBottom();
199
200      size_t smallXDim = this->axisDim[0];
201      size_t smallYDim = this->axisDim[1];
202      size_t smallZDim = this->axisDim[2];
203
204      // first correct the dimension sizes
205      this->axisDim[0] = smallXDim + left + right;
206      this->axisDim[1] = smallYDim + bottom + top;
207      this->axisDim[2] = smallZDim;
208      this->numPixels = this->axisDim[0]*this->axisDim[1]*this->axisDim[2];
209
210      size_t pos,smlpos;
211      bool isDud;
212
213      // Correct the array of pixel values
214      float *newarray  = new float[this->numPixels];
215      for(size_t x = 0; x < this->axisDim[0]; x++){
216        for(size_t y = 0; y < this->axisDim[1]; y++){
217          isDud = (x<left) || (x>=smallXDim+left) ||
218            (y<bottom) || (y>=smallYDim+bottom);
219       
220          for(size_t z = 0; z < this->axisDim[2]; z++){
221            pos = x + y*this->axisDim[0] + z*this->axisDim[0]*this->axisDim[1];
222            smlpos = (x-left) + (y-bottom)*smallXDim + z * smallXDim * smallYDim;
223            if(isDud) newarray[pos] = this->par.getBlankPixVal();
224            else      newarray[pos] = this->array[smlpos];
225          }
226        }
227      }
228      delete [] this->array;
229      this->array = newarray;
230
231      if(this->reconExists){
232        // Correct the reconstructed/smoothed array
233        float *newrecon   = new float[this->numPixels];
234        for(size_t x = 0; x < this->axisDim[0]; x++){
235          for(size_t y = 0; y < this->axisDim[1]; y++){
236            isDud = (x<left) || (x>=smallXDim+left) ||
237              (y<bottom) || (y>=smallYDim+bottom);
238         
239            for(size_t z = 0; z < this->axisDim[2]; z++){
240              pos = x + y*this->axisDim[0] + z*this->axisDim[0]*this->axisDim[1];
241              smlpos = (x-left) + (y-bottom)*smallXDim
242                + z * smallXDim * smallYDim;
243              if(isDud) newrecon[pos] = this->par.getBlankPixVal();
244              else      newrecon[pos] = this->recon[smlpos];
245            }
246          }
247        }
248        delete [] this->recon;
249        this->recon = newrecon;
250      }
251
252      // Correct the array of baseline values
253      if(this->par.getFlagBaseline()){
254        float *newbase  = new float[this->numPixels];
255        for(size_t x = 0; x < this->axisDim[0]; x++){
256          for(size_t y = 0; y < this->axisDim[1]; y++){
257            isDud = (x<left) || (x>=smallXDim+left) ||
258              (y<bottom) || (y>=smallYDim+bottom);
259       
260            for(size_t z = 0; z < this->axisDim[2]; z++){
261              pos = x + y*this->axisDim[0] + z*this->axisDim[0]*this->axisDim[1];
262              smlpos = (x-left) + (y-bottom)*smallXDim + z*smallXDim*smallYDim;
263              if(isDud) newbase[pos] = this->par.getBlankPixVal();
264              else      newbase[pos] = this->baseline[smlpos];
265            }
266          }
267        }
268        delete [] this->baseline;
269        this->baseline = newbase;
270      }
271
272      // Correct the 2-D detection map
273      short *newdetect = new short[this->axisDim[0]*this->axisDim[1]];
274      for(size_t x = 0; x < this->axisDim[0]; x++){
275        for(size_t y = 0; y < this->axisDim[1]; y++){
276          pos = x + y*this->axisDim[0];
277          smlpos = (x-left) + (y-bottom)*smallXDim;
278          isDud = (x<left) || (x>=smallXDim+left) ||
279            (y<bottom) || (y>=smallYDim+bottom);
280          if(isDud) newdetect[pos]=0;
281          else newdetect[pos] = this->detectMap[smlpos];
282        }
283      }
284      delete [] this->detectMap;
285      this->detectMap = newdetect;   
286
287 
288      // Now update the positions for all the detections
289 
290      std::vector<Detection>::iterator obj;
291      for(obj=this->objectList->begin();obj<this->objectList->end();obj++){
292        obj->addOffsets(left,bottom,0);
293      }
294
295    }
296
297  }
298
299}
Note: See TracBrowser for help on using the repository browser.