source: tags/release-1.2/src/Detection/ObjectGrower.cc @ 1391

Last change on this file since 1391 was 984, checked in by MatthewWhiting, 12 years ago

Making sure the growing stage updates the detection map, so that the detection map shows all the grown pixels as well (it previously didn't!)

File size: 8.2 KB
Line 
1
2#include <iostream>
3#include <vector>
4#include <duchamp/duchamp.hh>
5#include <Detection/ObjectGrower.hh>
6#include <Detection/detection.hh>
7#include <Cubes/cubes.hh>
8#include <duchamp/Utils/Statistics.hh>
9#include <duchamp/PixelMap/Voxel.hh>
10
11
12namespace duchamp {
13
14  ObjectGrower::ObjectGrower() {
15  }
16
17  ObjectGrower::ObjectGrower(ObjectGrower &o)
18  {
19    this->operator=(o);
20  }
21
22  ObjectGrower& ObjectGrower::operator=(const ObjectGrower &o)
23  {
24    if(this == &o) return *this;
25    this->itsFlagArray = o.itsFlagArray;
26    this->itsArrayDim = o.itsArrayDim;
27    this->itsGrowthStats = o.itsGrowthStats;
28    this->itsSpatialThresh = o.itsSpatialThresh;
29    this->itsVelocityThresh = o.itsVelocityThresh;
30    this->itsFluxArray = o.itsFluxArray;
31    return *this;
32  }
33
34  void ObjectGrower::define( Cube *theCube )
35  {
36    /// @details This copies all necessary information from the Cube
37    /// and its parameters & statistics. It also defines the array of
38    /// pixel flags, which involves looking at each object to assign
39    /// them as detected, all blank & "milky-way" pixels to assign
40    /// them appropriately, and all others to "available". It is only
41    /// the latter that will be considered in the growing function.
42    /// @param theCube A pointer to a duchamp::Cube
43
44    this->itsGrowthStats = Statistics::StatsContainer<float>(theCube->stats());
45    if(theCube->pars().getFlagUserGrowthThreshold())
46      this->itsGrowthStats.setThreshold(theCube->pars().getGrowthThreshold());
47    else
48      this->itsGrowthStats.setThresholdSNR(theCube->pars().getGrowthCut());   
49    this->itsGrowthStats.setUseFDR(false);
50
51    if(theCube->isRecon()) this->itsFluxArray = theCube->getRecon();
52    else this->itsFluxArray = theCube->getArray();
53
54    this->itsArrayDim = std::vector<size_t>(3);
55    this->itsArrayDim[0]=theCube->getDimX();
56    this->itsArrayDim[1]=theCube->getDimY();
57    this->itsArrayDim[2]=theCube->getDimZ();
58    size_t spatsize=this->itsArrayDim[0]*this->itsArrayDim[1];
59    size_t fullsize=spatsize*this->itsArrayDim[2];
60
61    if(theCube->pars().getFlagAdjacent())
62      this->itsSpatialThresh = 1;
63    else
64      this->itsSpatialThresh = int(theCube->pars().getThreshS());
65    this->itsVelocityThresh = int(theCube->pars().getThreshV());
66
67    this->itsFlagArray = std::vector<STATE>(fullsize,AVAILABLE);
68
69    for(size_t o=0;o<theCube->getNumObj();o++){
70      std::vector<Voxel> voxlist = theCube->getObject(o).getPixelSet();
71      for(size_t i=0; i<voxlist.size(); i++){
72        size_t pos = voxlist[i].getX() + voxlist[i].getY()*this->itsArrayDim[0] + voxlist[i].getZ()*spatsize;
73        this->itsFlagArray[pos] = DETECTED;
74      }
75    }
76
77    if(theCube->pars().getFlagMW()){
78      int minz=std::max(0,theCube->pars().getMinMW());
79      int maxz=std::min(int(theCube->getDimZ())-1,theCube->pars().getMaxMW());
80      if(minz<maxz){
81        for(size_t i=minz*spatsize;i<(maxz+1)*spatsize;i++) this->itsFlagArray[i]=MW;
82      }
83    }
84
85    for(size_t i=0;i<fullsize;i++)
86      if(theCube->isBlank(i)) this->itsFlagArray[i]=BLANK;
87
88  }
89
90
91  void ObjectGrower::updateDetectMap(short *map)
92  {
93
94    int numNondegDim=0;
95    for(int i=0;i<3;i++) if(this->itsArrayDim[i]>1) numNondegDim++;
96
97    if(numNondegDim>1){
98      size_t spatsize=this->itsArrayDim[0]*this->itsArrayDim[1];
99      for(size_t xy=0;xy<spatsize;xy++){
100        short ct=0;
101        for(size_t z=0;z<this->itsArrayDim[2];z++){
102          if(this->itsFlagArray[xy+z*spatsize] == DETECTED) ct++;
103        }
104        map[xy]=ct;
105      }
106    }
107    else{
108      for(size_t z=0;z<this->itsArrayDim[2];z++){
109        map[z] = (this->itsFlagArray[z] == DETECTED) ? 1 : 0;
110      }
111    }
112
113  }
114
115
116  void ObjectGrower::grow(Detection *theObject)
117  {
118    /// @details This function grows the provided object out to the
119    /// secondary threshold provided in itsGrowthStats. For each pixel
120    /// in an object, all surrounding pixels are considered and, if
121    /// their flag is AVAILABLE, their flux is examined. If it's above
122    /// the threshold, that pixel is added to the list to be looked at
123    /// and their flag is changed to DETECTED.
124    /// @param theObject The duchamp::Detection object to be grown. It
125    /// is returned with new pixels in place. Only the basic
126    /// parameters that belong to PixelInfo::Object3D are
127    /// recalculated.
128
129    size_t spatsize=this->itsArrayDim[0]*this->itsArrayDim[1];
130    long zero = 0;
131    std::vector<Voxel> voxlist = theObject->getPixelSet();
132    size_t origSize = voxlist.size();
133    long xpt,ypt,zpt;
134    long xmin,xmax,ymin,ymax,zmin,zmax,x,y,z;
135    size_t pos;
136    for(size_t i=0; i<voxlist.size(); i++){
137     
138      // std::vector<Voxel> newvox = this->growFromPixel(voxlist[i]);
139      // for(size_t v=0;v<newvox.size();v++) voxlist.push_back(newvox[v]);
140
141      xpt=voxlist[i].getX();
142      ypt=voxlist[i].getY();
143      zpt=voxlist[i].getZ();
144     
145      xmin = size_t(std::max(xpt - this->itsSpatialThresh, zero));
146      xmax = size_t(std::min(xpt + this->itsSpatialThresh, long(this->itsArrayDim[0])-1));
147      ymin = size_t(std::max(ypt - this->itsSpatialThresh, zero));
148      ymax = size_t(std::min(ypt + this->itsSpatialThresh, long(this->itsArrayDim[1])-1));
149      zmin = size_t(std::max(zpt - this->itsVelocityThresh, zero));
150      zmax = size_t(std::min(zpt + this->itsVelocityThresh, long(this->itsArrayDim[2])-1));
151     
152      //loop over surrounding pixels.
153      for(x=xmin; x<=xmax; x++){
154        for(y=ymin; y<=ymax; y++){
155          for(z=zmin; z<=zmax; z++){
156
157            pos=x+y*this->itsArrayDim[0]+z*spatsize;
158            if( ((x!=xpt) || (y!=ypt) || (z!=zpt))
159                && this->itsFlagArray[pos]==AVAILABLE ) {
160
161              if(this->itsGrowthStats.isDetection(this->itsFluxArray[pos])){
162                this->itsFlagArray[pos]=DETECTED;
163                voxlist.push_back(Voxel(x,y,z));
164              }
165            }
166
167          } //end of z loop
168        } // end of y loop
169      } // end of x loop
170
171    } // end of i loop (voxels)
172
173    // Add in new pixels to the Detection
174    for(size_t i=origSize; i<voxlist.size(); i++){
175      theObject->addPixel(voxlist[i]);
176    }
177   
178
179  }
180
181
182  std::vector<Voxel> ObjectGrower::growFromPixel(Voxel &vox)
183  {
184
185    std::vector<Voxel> newVoxels;
186    // std::cerr << vox << "\n";
187    long xpt=vox.getX();
188    long ypt=vox.getY();
189    long zpt=vox.getZ();
190    size_t spatsize=this->itsArrayDim[0]*this->itsArrayDim[1];
191    long zero = 0;
192    // std::cerr << "--> " << xpt << " " << ypt << " " << zpt << "\n";
193
194    int xmin = std::max(xpt - this->itsSpatialThresh, zero);
195    int xmax = std::min(xpt + this->itsSpatialThresh, long(this->itsArrayDim[0])-1);
196    int ymin = std::max(ypt - this->itsSpatialThresh, zero);
197    int ymax = std::min(ypt + this->itsSpatialThresh, long(this->itsArrayDim[1])-1);
198    int zmin = std::max(zpt - this->itsVelocityThresh, zero);
199    int zmax = std::min(zpt + this->itsVelocityThresh, long(this->itsArrayDim[2])-1);
200     
201    // std::cerr << xmin << " " << xmax << "  " << ymin << " " << ymax << "  " << zmin << " " << zmax << "\n";
202    //loop over surrounding pixels.
203    size_t pos;
204    Voxel nvox;
205    std::vector<Voxel> morevox;
206    for(int x=xmin; x<=xmax; x++){
207      for(int y=ymin; y<=ymax; y++){
208        for(int z=zmin; z<=zmax; z++){
209
210          pos=x+y*this->itsArrayDim[0]+z*spatsize;
211          if( ((x!=xpt) || (y!=ypt) || (z!=zpt))
212              && this->itsFlagArray[pos]==AVAILABLE ) {
213
214            if(this->itsGrowthStats.isDetection(this->itsFluxArray[pos])){
215              this->itsFlagArray[pos]=DETECTED;
216              nvox.setXYZF(x,y,z,this->itsFluxArray[pos]);
217              newVoxels.push_back(nvox);
218              // std::cerr << x << " " << y << " " << z << " " << this->itsFluxArray[pos] << "  =  " << nvox << "\n";
219              // morevox = this->growFromPixel(nvox);
220              // if(morevox.size()>0)
221              //        for(size_t v=0;v<morevox.size();v++) newVoxels.push_back(morevox[v]);
222             
223            }
224          }
225
226        } //end of z loop
227      } // end of y loop
228    } // end of x loop
229
230    std::vector<Voxel>::iterator v,v2;
231    for(v=newVoxels.begin();v<newVoxels.end();v++) {
232      std::vector<Voxel> morevox = this->growFromPixel(*v);
233      for(v2=morevox.begin();v2<morevox.end();v2++)
234        newVoxels.push_back(*v2);
235    }
236
237    return newVoxels;
238
239  }
240
241  // void ObjectGrower::resetDetectionFlags()
242  // {
243  //   for(size_t i=0;i<itsFlagArray.size();i++)
244  //     if(itsFlagArray[i]==DETECTED) itsFlagArray[i] = AVAILABLE;
245  // }
246
247  // void ObjectGrower::growInwardsFromEdge()
248  // {
249   
250
251
252  // }
253
254}
Note: See TracBrowser for help on using the repository browser.