A.I.M.S algorithms


greyLevelBlob.h
Go to the documentation of this file.
1 /* This software and supporting documentation are distributed by
2  * Institut Federatif de Recherche 49
3  * CEA/NeuroSpin, Batiment 145,
4  * 91191 Gif-sur-Yvette cedex
5  * France
6  *
7  * This software is governed by the CeCILL-B license under
8  * French law and abiding by the rules of distribution of free software.
9  * You can use, modify and/or redistribute the software under the
10  * terms of the CeCILL-B license as circulated by CEA, CNRS
11  * and INRIA at the following URL "http://www.cecill.info".
12  *
13  * As a counterpart to the access to the source code and rights to copy,
14  * modify and redistribute granted by the license, users are provided only
15  * with a limited warranty and the software's author, the holder of the
16  * economic rights, and the successive licensors have only limited
17  * liability.
18  *
19  * In this respect, the user's attention is drawn to the risks associated
20  * with loading, using, modifying and/or developing or reproducing the
21  * software by the user in light of its specific status of free software,
22  * that may mean that it is complicated to manipulate, and that also
23  * therefore means that it is reserved for developers and experienced
24  * professionals having in-depth computer knowledge. Users are therefore
25  * encouraged to load and test the software's suitability as regards their
26  * requirements in conditions enabling the security of their systems and/or
27  * data to be ensured and, more generally, to use and operate it in the
28  * same conditions as regards security.
29  *
30  * The fact that you are presently reading this means that you have had
31  * knowledge of the CeCILL-B license and that you accept its terms.
32  */
33 
34 #ifndef AIMS_PRIMALSKETCH_GREYLEVELBLOB_H
35 #define AIMS_PRIMALSKETCH_GREYLEVELBLOB_H
36 
37 #include <cstdlib>
39 #include <iostream>
40 #include <set>
41 #include <map>
42 #include <list>
43 #include <vector>
44 
45 namespace aims {
46  const int BACKGROUND = 0;
47 
48  template<typename T> struct ltstr_p3d { // comparaison de Sites pour conteneurs tri�s (set, map)
49  bool operator()(const T p1, const T p2) { return false;}
50  };
51 
52  template <> struct ltstr_p3d<Point3d> {
53  bool operator ()( const Point3d p1, const Point3d p2 ) {
54  if ( p1[2] < p2[2] )
55  return true;
56  else if ( p1[2] > p2[2] )
57  return false;
58  else {
59  if ( p1[1] < p2[1] )
60  return true;
61  else if ( p1[1] > p2[1] )
62  return false;
63  else
64  {
65  if ( p1[0] < p2[0] )
66  return true;
67  else return false;
68  }
69  }
70  }
71  };
72 
73  template <> struct ltstr_p3d<std::pair<Point3df, uint> > {
74  bool operator () ( const std::pair<Point3df, uint> p1,
75  const std::pair<Point3df, uint> p2 ) {
76  if ( p1.second < p2.second )
77  return true;
78  else
79  return false;
80  }
81  };
82 
83  template<class T> class MaximumPoint;
84  template<class T> class SaddlePoint;
85  template<class T> class GreyLevelBlob;
86 
88 
89  public:
92  BlobMeasurements(float maxInt, float meanInt, float maxCont, float meanCont, float a, float tv=0.0, float tvalue=0.0):
93  maxIntensity(maxInt), meanIntensity(meanInt), maxContrast(maxCont), meanContrast(meanCont), area(a), t(tv), tValue(tvalue) {}
94 
95  float maxIntensity;
97  float maxContrast;
98  float meanContrast;
99  float area;
100  float t;
101  float tValue;
102 
104  };
105 
106  // Class for grey-level blobs
107  // Templated with respect to the type of points:
108  // TypeSite<AimsData<T> >::type for images
109  // TypeSite<AimsSurface<D, Void> >::type for textures.
110 
111  template<class T> class GreyLevelBlob {
112 
113  protected:
114 
115  int _label;
116  std::set<T,ltstr_p3d<T> > listePoints;
119  float scale;
120  bool grow;
121 
122  public:
123 
124  GreyLevelBlob ( MaximumPoint<T> *node, int label ) {
125  saddle = 0;
126  maximum = node;
127  node->blob = this;
128  grow = true;
129  _label = label;
130  AddPoint (maximum->_node);
131  }
133  saddle = 0;
134  maximum = 0;
135  grow = true;
136  _label = BACKGROUND;
137  }
138 
140 
141  void AddPoint( T node ) { listePoints.insert(node); }
142  void StopGrowth() { grow = false; }
143  bool CanGrow() { return grow; }
144  int Label() { return _label; }
145 
146  std::set<T, ltstr_p3d<T> > & GetListePoints () { return listePoints; }
147 
148  void SetSaddle (SaddlePoint<T> *node) {
149  saddle = node;
150  node->AddBlob (this);
151  StopGrowth();
152  }
153 
156  float GetScale () { return scale; }
157  void SetScale (float t) { scale = t; }
158 
159  GreyLevelBlob<T> & operator = ( const GreyLevelBlob<T> & other );
160 
161  };
162 
163  // class for saddle points
164 
165  template<class T> class SaddlePoint {
166 
167  public:
168  T _node;
169  std::list<GreyLevelBlob<T>* > blobList;
170 
171  SaddlePoint () { }
172  SaddlePoint (T node) : _node(node) { }
174 
175  void AddBlob(GreyLevelBlob<T> *blob) { blobList.push_back(blob); }
176  std::list<GreyLevelBlob<T>*> & GetBlobList() { return blobList; }
177 
178  SaddlePoint<T> & operator = ( const SaddlePoint<T>& other );
179 
180  };
181 
182  // class for maxima
183 
184  template<class T> class MaximumPoint {
185 
186  public:
187  T _node;
190 
191  MaximumPoint () : blob(0) { }
192  MaximumPoint ( T node ) : _node(node), blob(0) { }
193  MaximumPoint<T> & operator = ( const MaximumPoint<T>& other );
194 
195  };
196 
197  // Class that define grey-level blobs algorithm extraction
198 
199  template<typename Geom, typename Text> class ExtractGreyLevelBlobs {
200 
201  private :
202 
203  typedef typename SiteType<Geom>::type Site;
204  typedef typename TexType<Text>::type Val;
205 
206  TexturedData<Geom,Text> *_texdata;
207  TexturedData<Geom,Text> *_rawtexdata;
208  TexturedData<Geom, Text> *_mask; // For convenience, data and mask are same type.
209  // This is the only simple solution to keep type genericity
210  // Mask is 0 outside, >0 inside
211  std::map<int, GreyLevelBlob<Site>* > blobMap; // map label -> blob
212  std::list<SaddlePoint<Site> *> saddleList;
213  std::list<MaximumPoint<Site> *> maximumList;
214  TexturedData<Geom, Text> labelsImage; // mapping site->label (blob, background...)
215 
216  char *_stats; // File name for blob statistics
217 
218  void DoMasking(); // if required, use a mask to remove some blobs
219  void CheckMask(); // basic check : is the geometry of the mask the same than the data ?
220 
221  public :
222 
224  : _texdata(texdata), _rawtexdata(rawtexdata), _mask(mask), _stats(0){ labelsImage=TexturedData<Geom, Text>(*_texdata); CheckMask();}
226  : _texdata(texdata), _rawtexdata(rawtexdata), _mask(mask), _stats(stats) { labelsImage=TexturedData<Geom, Text>(*_texdata); CheckMask();}
227 
228 
230  : _texdata(texdata), _rawtexdata(NULL), _mask(0), _stats(0) { labelsImage=TexturedData<Geom, Text>(*_texdata);}
232  : _texdata(texdata), _rawtexdata(NULL), _mask(mask), _stats(0) { labelsImage=TexturedData<Geom, Text>(*_texdata); CheckMask();}
234  : _texdata(texdata), _rawtexdata(NULL), _mask(mask), _stats(stats) { labelsImage=TexturedData<Geom, Text>(*_texdata); CheckMask();}
235  void Run(); // possibility of masking to exclude an area
236 
238  void SetOriginalTexture ( TexturedData<Geom,Text> *rawtexdata ) { _rawtexdata = rawtexdata; }
239  TexturedData<Geom,Text> *GetOriginalTexture ( ) { return _rawtexdata; }
240  // doit renvoyer une liste de GLB, de maximums et de saddle points
241  std::list<SaddlePoint<Site> *> GetSaddleList() { return saddleList; }
242  std::list<MaximumPoint<Site> *> GetMaxList() { return maximumList; }
243  std::map<int, GreyLevelBlob<Site> *> GetBlobs() { return blobMap; }
244  TexturedData<Geom, Text> GetBlobImage() { return labelsImage; }
245  int nbBlobs() { return blobMap.size(); }
246 
247  };
248 
249 
250  // class that provide some tools for blob management
251 
252  template<typename T> class GreyLevelBlobTools {
253 
254  private :
255  GreyLevelBlob<T> *_blob;
256 
257  public :
258 
259  GreyLevelBlobTools(GreyLevelBlob<T> *blob) : _blob(blob) {}
260  std::vector<float> Boundingbox();
261  std::vector<float> Barycenter();
262 
263  };
264 
265  //---------------------------------------------------------------------------
266  //
267  // Methods
268  //
269  //---------------------------------------------------------------------------
270 
271  inline
273  {
276  maxContrast=other.maxContrast;
278  area=other.area;
279  t=other.t;
280  tValue=other.tValue;
281 
282  return *this;
283  }
284 
285  //----------------------------------------------------------------------------------------------------------
286 
287  template<class T>
288  inline
290  {
291  _node=other.node;
292  return *this;
293  }
294 
295  //----------------------------------------------------------------------------------------------------------
296 
297  template<class T>
298  inline
300  {
301  _node=other.node;
302  blob=other.blob;
303  return *this;
304  }
305 
306  //----------------------------------------------------------------------------------------------------------
307 
308  template<class T>
309  inline
311  {
312  _label=other._label;
313  listePoints=other.listePoints;
314  scale=other.scale;
315  saddle=other.saddle;
316  maximum=other.maximum;
317 
318  return *this;
319  }
320 
321  //----------------------------------------------------------------------------------------------------------
322 
323  template<typename Geom, typename Text> void ExtractGreyLevelBlobs<Geom, Text>::Run()
324  {
325  int currentLabel=0, labelBlob;
326  MaximumPoint<Site> *maximum;
327  SaddlePoint<Site> *saddle;
328  GreyLevelBlob<Site> *greyLevelBlob;
329 
330  // multimap<intensity, data.site> for intensity based sorting of sites/voxels
331  std::multimap<const Val, Site> sortedSites;
332  SiteIterator<Geom> ptSite=(*_texdata).siteBegin();
333 
334  for ( ; ptSite != (*_texdata).siteEnd(); ++ptSite)
335  sortedSites.insert(std::pair<Val, Site>((*_texdata).intensity(*ptSite), (*ptSite)));
336 
337 
338 
339  // TexturedData that will contains the label associated with each site,
340  // that is: BACKGROUND, or grey-level blob number.
341  // This TexturedData also gives acess to the neighbours of each site
342 
343  // Rem: labels should be (int) but will be same type than Text to handle both surfaces
344  // and images. Not elegant but that's all I found so far.
345 
346  for (ptSite=labelsImage.siteBegin(); ptSite != labelsImage.siteEnd(); ++ptSite)
347  labelsImage.intensity(*ptSite)=BACKGROUND;
348  // GL Blob extraction
349  // This is the core algorithm
350  typename std::multimap<Val, Site>::reverse_iterator ptSortedSites;
351 
352  //std::cout << "DEBUG: extractor has started detection" << std::endl;
353  for ( ptSortedSites=sortedSites.rbegin(); ptSortedSites != sortedSites.rend(); ++ptSortedSites) {
354  Val intensity=(*_texdata).intensity((*ptSortedSites).second);
355 
356  int nbAbove;
357  int nbAboveLabels;
358 
359  // How many neighbours with higher intensity ?
360 
361  std::vector<Site> neighb=(*_texdata).neighbours((*ptSortedSites).second); //neighbours
362 
363  std::vector<Site> above; //neighbours with higher intensity
364  std::set<int> aboveLabels; // labels of (above)
365  typename std::vector<Site>::iterator ptNeigh=neighb.begin();
366 
367  for ( ; ptNeigh != neighb.end(); ++ptNeigh){
368 
369  if ((*_texdata).intensity(*ptNeigh) > intensity){
370 
371  above.push_back(*ptNeigh);
372  aboveLabels.insert(int(labelsImage.intensity(*ptNeigh)));
373  }
374  }
375 
376  nbAbove=above.size();
377  nbAboveLabels=aboveLabels.size();
378 
379  if (nbAbove==0){ // Case 1: local max, new blob
380  currentLabel++;
381  maximum=new MaximumPoint<Site>((*ptSortedSites).second);
382  greyLevelBlob=new GreyLevelBlob<Site>(maximum, currentLabel);
383  labelsImage.intensity((*ptSortedSites).second)=(Val) currentLabel;
384  maximumList.push_back(maximum);
385  blobMap[currentLabel]=(greyLevelBlob);
386 
387  }
388  else if ( (nbAbove==1) && ((labelsImage.intensity(*(above.begin())))==BACKGROUND) ){
389  // Case 2: point in background
390  labelsImage.intensity((*ptSortedSites).second)=BACKGROUND;
391 
392  }
393 
394  else if ((nbAbove>1) && (nbAboveLabels>1)){
395  // Case 3: one or several blobs to stop -> Saddle point
396 
397  int flagS=0;
398  labelsImage.intensity((*ptSortedSites).second)=BACKGROUND;
399  std::set<int>::iterator ptLabels=aboveLabels.begin();
400  for (; ptLabels != aboveLabels.end(); ++ptLabels)
401  if (*ptLabels!=BACKGROUND)
402  if (blobMap[*ptLabels]->CanGrow())
403  {
404  if (flagS==0)
405  {
406  saddle=new SaddlePoint<Site>((*ptSortedSites).second);
407  saddleList.push_back(saddle);
408  blobMap[*ptLabels]->SetSaddle(saddle);
409  flagS=1;
410  }
411  else
412  blobMap[*ptLabels]->SetSaddle(saddle);
413  }
414  }
415  else // Case 4: point belong to a growing blob
416  {
417  labelBlob=int(labelsImage.intensity(*(above.begin())));
418  if ((labelBlob != BACKGROUND) && (blobMap[labelBlob]->CanGrow() ))
419  {
420  labelsImage.intensity((*ptSortedSites).second)=(Val) labelBlob;
421  blobMap[labelBlob]->AddPoint((*ptSortedSites).second);
422  }
423  else
424  {
425  labelsImage.intensity((*ptSortedSites).second)=BACKGROUND;
426  }
427  }
428  }
429  //std::cout << "DEBUG: found " << blobMap.size() << " blobs" << std::endl;
430  //std::cout << "DEBUG: extractor about to enter masking" << std::endl;
431  if (_mask!=0) { DoMasking();
432  std::cout<<"MASKING" << std::endl;
433  }
434  //std::cout << "DEBUG: masking done, extractor about to enter measurements" << std::endl;
435  ComputeBlobMeasurements();
436  //std::cout << "DEBUG: done" << std::endl;
437  }
438 
439  //----------------------------------------------------------------------------------------------------------
440 
441  template<typename Geom, typename Text> void ExtractGreyLevelBlobs<Geom, Text>::DoMasking() {
442  typename std::list<MaximumPoint<Site> *>::iterator itMax=maximumList.begin(), itPrevious=itMax;
443  SaddlePoint<Site> *saddle;
444  double EPSILON = 0.00001;
445  int del = 0;
446 
447  std::cout << "DEBUG: found " << blobMap.size() << " blobs" << std::endl;
448  std::cout << "DEBUG: saddle list size : " << saddleList.size() << std::endl;
449 
450  for ( ; itMax != maximumList.end() ; ++itMax ) {
451  if ( del == 1 ) {
452  maximumList.erase(itPrevious);
453  }
454  del = 0;
455  if ( fabs ( _mask->intensity((*itMax)->_node)) < EPSILON ) { // this is to test float=0.0
456  blobMap.erase ( (*itMax)->blob->Label() ); // remove the blob from the list.
457 
458  saddle = (*itMax)->blob->GetSaddle(); // check the saddle
459  if ( saddle != 0 ) { // some blobs can have no saddle if they are on the image border
460  if ( saddle->blobList.size() > 1 ) {
461  saddle->blobList.remove( (*itMax)->blob );
462  }
463  else {
464  saddle->blobList.remove((*itMax)->blob);
465  saddleList.remove(saddle);
466  delete saddle;
467  }
468  }
469  delete (*itMax)->blob; // delete the blob
470  del = 1; // maximum has to be deleted
471  }
472  itPrevious=itMax;
473  }
474  if ( del == 1 )
475  maximumList.erase(itPrevious);
476  std::cout << "DEBUG: found " << blobMap.size() << " blobs" << std::endl;
477  }
478 
479  //----------------------------------------------------------------------------------------------------------
480 
481  template<typename Geom, typename Text> void ExtractGreyLevelBlobs<Geom, Text>::CheckMask()
482  {
483  if (_mask != 0)
484  if (_mask->NbSites() != _texdata->NbSites())
485  {
486  std::cerr << "ExtractGreyLevelBlobs : mask and data do not have the same number of sites !!!" << std::endl;
487  exit(EXIT_FAILURE);
488  }
489  }
490 
491  //----------------------------------------------------------------------------------------------------------
492 
493  template<typename Geom, typename Text>
494  void
496  typename std::map<int, GreyLevelBlob<Site>* >::iterator blobIt;
497  GreyLevelBlob<Site> *blob;
498  SaddlePoint<Site> *saddle;
499  MaximumPoint<Site> *maxi;
500  Val saddleInt, maxInt, intensity;
501  float maxIntensity, meanIntensity, maxContrast, meanContrast, area;
502  int nbPoint;
503  FILE *fileStat = 0;
504 
505  if ( _stats != 0 ) {
506  fileStat = fopen ( _stats, "w" );
507  fprintf ( fileStat, "Blob_label max_int mean_int max_cont mean_cont area\n" );
508  }
509 
510  //std::cout << "DEBUG: going through blob list" << std::endl;
511  //std::cout << "DEBUG: Size of list : " << blobMap.size() << std::endl;
512  //std::cout << "DEBUG: saddle list size : " << saddleList.size() << std::endl;
513  for ( blobIt = blobMap.begin() ; blobIt != blobMap.end() ; ++blobIt ) {
514  //std::cout << ((*blobIt).second)->Label(); fflulongsh(stdout);
515  //std::cout << "DEBUG : blob " << (*blobIt).first << std::endl;
516  maxIntensity = 0.0;
517  meanIntensity = 0.0;
518  maxContrast = 0.0;
519  meanContrast = 0.0;
520  nbPoint = 0;
521  area = 0.0; // pour l'instant il s'agit du nombre de points
522  // donc tres mauvais pour les surfaces
523  blob = (*blobIt).second;
524  //std::cout << "DEBUG : getting saddle" << std::endl;
525  saddle = blob->GetSaddle();
526  //std::cout << "DEBUG : getting maxi" << std::endl;
527  maxi=blob->GetMaximum();
528  //std::cout << "DEBUG : sites : " << (*_texdata).NbSites() << std::endl;
529  //std::cout << "DEBUG : getting max intensity" << std::endl;
530  maxInt=(*_texdata).intensity(maxi->_node);
531  //std::cout << "DEBUG : getting saddle intensity" << std::endl;
532  if (saddle != 0) {
533  //std::cout << "DEBUG : saddle : " << (saddle) << std::endl;
534  saddleInt=(*_texdata).intensity(saddle->_node);
535  }
536  else {
537  //std::cout << "DEBUG : blob " << blob->Label() << " has no saddle " << std::endl;
538  //std::cout << " ! " << std::flush;
539  saddleInt=0;
540  }
541  maxContrast=float(maxInt-saddleInt);
542  maxIntensity=float(maxInt);
543 
544  std::set<Site,ltstr_p3d<Site> > listePoints=blob->GetListePoints();
545  typename std::set<Site,ltstr_p3d<Site> >::iterator
546  itPoints=listePoints.begin();
547  Site point;
548 
549  //std::cout << "DEBUG : going through points" << std::endl;
550  for (; itPoints!=listePoints.end(); ++itPoints) {
551  point=(*itPoints);
552  intensity=(*_texdata).intensity(point);
553  nbPoint++;
554  area=area+1.0;
555  meanContrast+=float(intensity - saddleInt);
556  meanIntensity+=float(intensity);
557  }
558  meanContrast/=float(nbPoint);
559  meanIntensity/=float(nbPoint);
560 
561  //std::cout << " + " << std::flush;
562  blob->measurements.maxIntensity=maxIntensity;
563  blob->measurements.meanIntensity=meanIntensity;
564  blob->measurements.maxContrast=maxContrast;
565  blob->measurements.meanContrast=meanContrast;
566  blob->measurements.area=area;
567 
568 
569  if ( GetOriginalTexture() != NULL ) {
570  std::set<Site,ltstr_p3d<Site> > pixels;
571  pixels = blob->GetListePoints();
572 
573  typename std::set<Site, ltstr_p3d<Site> >::iterator itPix;
574  float tvmax = -100.0;
575  for ( itPix = pixels.begin() ; itPix != pixels.end() ; itPix++ ) {
576  if ( float ( GetOriginalTexture()->intensity(*itPix) ) > tvmax )
577  tvmax = float ( GetOriginalTexture()->intensity(*itPix) );
578  }
579  blob->measurements.t = tvmax;
580  }
581  else {
582  std::cout << "BLOBMEASUREMENT = 0.0" << std::endl;
583  blob->measurements.t = 0.0;
584  }
585 
586 
587  //std::cout << " - " << std::flush;
588  if ( fileStat != 0 )
589  fprintf ( fileStat, "%i %.4f %.4f %.4f %.4f %.4f\n", blob->Label(),
590  maxIntensity, meanIntensity, maxContrast, meanContrast, area);
591  //std::cout << " | " << std::flush;
592  }
593  if ( fileStat != 0 )
594  fclose(fileStat);
595  }
596 
597  //----------------------------------------------------------------------------------------
598 
599  // Image specialisation
600 
601  template <>
602  std::vector<float>
604  {
605 
606  std::set<Point3d,ltstr_p3d<Point3d> > listeP=_blob->GetListePoints();
607  std::set<Point3d,ltstr_p3d<Point3d> >::iterator pointIt=listeP.begin();
608 
609  float x1,x2,y1,y2,z1,z2;
610 
611  x1=10000.0; y1=10000.0; z1=10000.0;
612  x2=-10000.0; y2=-10000.0; z2=-10000.0;
613  std::vector<float> vectF(6);
614 
615  for (; pointIt != listeP.end(); ++pointIt)
616  {
617  float x=(float) (*pointIt)[0];
618  float y=(float) (*pointIt)[1];
619  float z=(float) (*pointIt)[2];
620  if (x<x1) x1=x;
621  if (x>x2) x2=x;
622  if (y<y1) y1=y;
623  if (y>y2) y2=y;
624  if (z<z1) z1=z;
625  if (z>z2) z2=z;
626  }
627 
628  vectF[0]=x1; vectF[1]=y1; vectF[2]=z1;
629  vectF[3]=x2; vectF[4]=y2; vectF[5]=z2;
630 
631  return vectF;
632  }
633 
634  template <>
635  std::vector<float>
637  {
638  Point3d max= _blob->GetMaximum()->_node;
639  std::vector<float> triplet;
640  triplet.push_back(max[0]);
641  triplet.push_back(max[1]);
642  triplet.push_back(max[2]);
643  return triplet;
644 
645  }
646 
647  // Surface specialisation
648 
649  template <>
650  std::vector<float>
652  {
653  std::set<std::pair<Point3df,uint> ,ltstr_p3d<std::pair<Point3df,uint> > > listeP=_blob->GetListePoints();
654  std::set<std::pair<Point3df,uint> ,ltstr_p3d<std::pair<Point3df,uint> > >::iterator pointIt=listeP.begin();
655 
656  float x1,x2,y1,y2,z1,z2;
657 
658  x1=10000.0; y1=10000.0; z1=10000.0;
659  x2=-10000.0; y2=-10000.0; z2=-10000.0;
660 
661  std::vector<float> vectF(6);
662 
663  for (; pointIt != listeP.end(); ++pointIt)
664  {
665  float x=(float) (*pointIt).first[0];
666  float y=(float) (*pointIt).first[1];
667  float z=(float) (*pointIt).first[2];
668  if (x<x1) x1=x;
669  if (x>x2) x2=x;
670  if (y<y1) y1=y;
671  if (y>y2) y2=y;
672  if (z<z1) z1=z;
673  if (z>z2) z2=z;
674  }
675 
676  vectF[0]=x1; vectF[1]=y1; vectF[2]=z1;
677  vectF[3]=x2; vectF[4]=y2; vectF[5]=z2;
678 
679  return vectF;
680  }
681 
682 
683 
684 template <>
685  std::vector<float>
687 {
688  Point3df max= _blob->GetMaximum()->_node.first;
689  std::vector<float> triplet;
690  triplet.push_back(max[0]);
691  triplet.push_back(max[1]);
692  triplet.push_back(max[2]);
693  return triplet;
694 
695 }
696 }
697 #endif
ExtractGreyLevelBlobs(TexturedData< Geom, Text > *texdata, TexturedData< Geom, Text > *mask, char *stats)
BlobMeasurements & operator=(const BlobMeasurements &other)
TexturedData< Geom, Text > * GetOriginalTexture()
GreyLevelBlobTools(GreyLevelBlob< T > *blob)
float max(float x, float y)
Definition: thickness.h:97
BucketMap< Void > * mask(const BucketMap< Void > &src, const BucketMap< Void > &m, bool intersect=true)
bool operator()(const T p1, const T p2)
Definition: greyLevelBlob.h:49
std::set< T, ltstr_p3d< T > > & GetListePoints()
BlobMeasurements(const BlobMeasurements &other)
Definition: greyLevelBlob.h:91
void SetScale(float t)
GreyLevelBlob< T > * blob
ExtractGreyLevelBlobs(TexturedData< Geom, Text > *texdata, TexturedData< Geom, Text > *rawtexdata, TexturedData< Geom, Text > *mask, char *stats)
BlobMeasurements measurements
void SetOriginalTexture(TexturedData< Geom, Text > *rawtexdata)
void AddBlob(GreyLevelBlob< T > *blob)
MaximumPoint< T > * GetMaximum()
std::set< T, ltstr_p3d< T > > listePoints
SaddlePoint< T > & operator=(const SaddlePoint< T > &other)
std::vector< float > Barycenter()
GreyLevelBlob< T > & operator=(const GreyLevelBlob< T > &other)
void AddPoint(T node)
MaximumPoint< T > & operator=(const MaximumPoint< T > &other)
ExtractGreyLevelBlobs(TexturedData< Geom, Text > *texdata, TexturedData< Geom, Text > *rawtexdata, TexturedData< Geom, Text > *mask)
std::list< GreyLevelBlob< T > * > & GetBlobList()
MaximumPoint< T > * maximum
SaddlePoint< T > * GetSaddle()
#define EPSILON
ExtractGreyLevelBlobs(TexturedData< Geom, Text > *texdata, TexturedData< Geom, Text > *mask)
BlobMeasurements(float maxInt, float meanInt, float maxCont, float meanCont, float a, float tv=0.0, float tvalue=0.0)
Definition: greyLevelBlob.h:92
std::list< MaximumPoint< Site > * > GetMaxList()
std::map< int, GreyLevelBlob< Site > * > GetBlobs()
GreyLevelBlob(MaximumPoint< T > *node, int label)
std::list< GreyLevelBlob< T > * > blobList
void SetSaddle(SaddlePoint< T > *node)
SaddlePoint< T > * saddle
std::list< SaddlePoint< Site > * > GetSaddleList()
std::vector< float > Boundingbox()
ExtractGreyLevelBlobs(TexturedData< Geom, Text > *texdata)
TexturedData< Geom, Text > GetBlobImage()