SMIL  0.9.1
DMorphoWatershedExtinction.hpp
1 /*
2  * Copyright (c) 2011, Matthieu FAESSEL and ARMINES
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are met:
7  *
8  * * Redistributions of source code must retain the above copyright
9  * notice, this list of conditions and the following disclaimer.
10  * * Redistributions in binary form must reproduce the above copyright
11  * notice, this list of conditions and the following disclaimer in the
12  * documentation and/or other materials provided with the distribution.
13  * * Neither the name of Matthieu FAESSEL, or ARMINES nor the
14  * names of its contributors may be used to endorse or promote products
15  * derived from this software without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY
18  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS AND CONTRIBUTORS BE LIABLE FOR ANY
21  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
24  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
26  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27  */
28 
29 #ifndef _D_MORPHO_WATERSHED_EXTINCTION_HPP
30 #define _D_MORPHO_WATERSHED_EXTINCTION_HPP
31 
32 #include "DMorphoWatershed.hpp"
33 #include "DMorphoGraph.hpp"
34 
35 #include <set>
36 
37 namespace smil
38 {
39 
47  #ifndef SWIG
48  template <class T>
50  {
51  CrossVectorComp(const vector<T> &vec)
52  : compVec(vec)
53  {
54  }
55  const vector<T> &compVec;
56  inline bool operator() (const T &i, const T &j)
57  {
58  return ( compVec[i] > compVec[j] );
59  }
60  };
61  #endif // SWIG
62 
70  template <class T, class labelT, class extValType=UINT, class HQ_Type=HierarchicalQueue<T> >
72 #ifndef SWIG
73  : public BaseFlooding<T, labelT, HQ_Type>
74 #endif // SWIG
75  {
76  public:
77  virtual ~ExtinctionFlooding() {}
78 
79  UINT labelNbr, basinNbr;
80  T currentLevel;
81  vector<labelT> equivalentLabels;
82  vector<extValType> extinctionValues;
83  size_t lastOffset;
84 
85  std::vector< std::pair<labelT,labelT> > pendingMerges;
86  std::vector<T> mergeLevels;
87 
89 
90  virtual void createBasins(const UINT &nbr)
91  {
92  equivalentLabels.resize(nbr);
93  extinctionValues.resize(nbr, 0);
94 
95  for (UINT i=0;i<nbr;i++)
96  equivalentLabels[i] = i;
97 
98  basinNbr = nbr;
99  }
100  virtual void deleteBasins()
101  {
102  equivalentLabels.clear();
103  extinctionValues.clear();
104 
105  basinNbr = 0;
106  }
107 
108  inline virtual void insertPixel(const size_t &/*offset*/, const labelT &/*lbl*/) {}
109  inline virtual void raiseLevel(const labelT &/*lbl*/) {}
110  inline virtual labelT mergeBasins(const labelT &/*lbl1*/, const labelT &/*lbl2*/) { return 0; }
111  inline virtual void finalize(const labelT &/*lbl*/) {}
112 
113  virtual void updateEquTable(const labelT &lbl1, const labelT &lbl2)
114  {
115  for (size_t i=1;i<labelNbr+1;i++)
116  if (equivalentLabels[i]==lbl1)
117  equivalentLabels[i] = lbl2;
118  }
119 
120  virtual RES_T flood(const Image<T> &imIn, const Image<labelT> &imMarkers, Image<labelT> &imBasinsOut, const StrElt &se=DEFAULT_SE)
121  {
122  return BaseFlooding<T, labelT, HQ_Type>::flood(imIn, imMarkers, imBasinsOut, se);
123  }
124 
125  virtual RES_T flood(const Image<T> &imIn, const Image<labelT> &imMarkers, Image<labelT> &imBasinsOut, Graph<labelT, extValType> &_graph, const StrElt &se=DEFAULT_SE)
126  {
127  ASSERT_ALLOCATED(&imIn, &imMarkers, &imBasinsOut);
128  ASSERT_SAME_SIZE(&imIn, &imMarkers, &imBasinsOut);
129 
130  ImageFreezer freeze(imBasinsOut);
131 
132  copy(imMarkers, imBasinsOut);
133 
134  initialize(imIn, imBasinsOut, se);
135  this->graph = &_graph;
136  graph->clear();
137  processImage(imIn, imBasinsOut, se);
138 
139  return RES_OK;
140  }
141 
142  template <class outT>
143  RES_T floodWithExtValues(const Image<T> &imIn, const Image<labelT> &imMarkers, Image<outT> &imExtValOut, Image<labelT> &imBasinsOut, const StrElt & se=DEFAULT_SE)
144  {
145  ASSERT_ALLOCATED (&imExtValOut);
146  ASSERT_SAME_SIZE (&imIn, &imExtValOut);
147 
148  ASSERT(this->flood(imIn, imMarkers, imBasinsOut, se)==RES_OK);
149 
150  ImageFreezer freezer (imExtValOut);
151 
152  typename ImDtTypes < outT >::lineType pixOut = imExtValOut.getPixels ();
153  typename ImDtTypes < labelT >::lineType pixMarkers = imMarkers.getPixels ();
154 
155  fill(imExtValOut, outT(0));
156 
157  for (size_t i=0; i<imIn.getPixelCount (); i++, pixMarkers++, pixOut++)
158  {
159  if(*pixMarkers != labelT(0))
160  *pixOut = extinctionValues[*pixMarkers] ;
161  }
162 
163  return RES_OK;
164  }
165  template <class outT>
166  RES_T floodWithExtValues(const Image<T> &imIn, const Image<labelT> &imMarkers, Image<outT> &imExtValOut, const StrElt & se=DEFAULT_SE)
167  {
168  Image<labelT> imBasinsOut(imMarkers);
169  return floodWithExtValues(imIn, imMarkers, imExtValOut, imBasinsOut, se);
170  }
171 
172  template <class outT>
173  RES_T floodWithExtRank(const Image<T> &imIn, const Image<labelT> &imMarkers, Image<outT> &imExtRankOut, Image<labelT> &imBasinsOut, const StrElt & se=DEFAULT_SE)
174  {
175  ASSERT_ALLOCATED (&imExtRankOut);
176  ASSERT_SAME_SIZE (&imIn, &imExtRankOut);
177 
178  ASSERT(this->flood(imIn, imMarkers, imBasinsOut, se)==RES_OK);
179 
180  typename ImDtTypes < outT >::lineType pixOut = imExtRankOut.getPixels ();
181  typename ImDtTypes < labelT >::lineType pixMarkers = imMarkers.getPixels ();
182 
183  ImageFreezer freezer (imExtRankOut);
184 
185  // Sort by extinctionValues
186  vector<outT> rank(labelNbr);
187  for (UINT i=0;i<labelNbr;i++)
188  rank[i] = i+1;
189 
190  CrossVectorComp<extValType> comp(this->extinctionValues);
191  sort(rank.begin(), rank.end(), comp);
192  for (UINT i=0;i<labelNbr;i++)
193  extinctionValues[rank[i]] = i+1;
194 
195  fill(imExtRankOut, outT(0));
196 
197  for (size_t i=0; i<imIn.getPixelCount (); i++, pixMarkers++, pixOut++)
198  {
199  if(*pixMarkers != labelT(0))
200  *pixOut = extinctionValues[*pixMarkers] ;
201  }
202 
203  return RES_OK;
204  }
205  template <class outT>
206  RES_T floodWithExtRank(const Image<T> &imIn, const Image<labelT> &imMarkers, Image<outT> &imExtRankOut, const StrElt & se=DEFAULT_SE)
207  {
208  Image<labelT> imBasinsOut(imMarkers);
209  return floodWithExtRank(imIn, imMarkers, imExtRankOut, imBasinsOut, se);
210  }
211 
212  protected:
213  virtual RES_T initialize(const Image<T> &imIn, Image<labelT> &imLbl, const StrElt &se)
214  {
216 
217  labelNbr = maxVal(imLbl);
218  createBasins(labelNbr+1);
219  currentLevel = ImDtTypes<T>::min();
220 
221  graph = NULL;
222 
223  return RES_OK;
224  }
225 
226  virtual RES_T processImage(const Image<T> &imIn, Image<labelT> &imLbl, const StrElt &se)
227  {
229 
230  processMerges();
231 
232  // Update last level of flooding.
233  labelT l2 = this->lblPixels[lastOffset];
234  finalize(equivalentLabels[l2]);
235 
236  return RES_OK;
237  }
238 
239  virtual void processMerges(void)
240  {
241  if (pendingMerges.size()==0)
242  return;
243 
244  typename std::vector< std::pair<labelT,labelT> >::iterator mIt = pendingMerges.begin();
245  // typename std::vector<T>::iterator lIt = mergeLevels.begin();
246 
247  while(mIt!=pendingMerges.end())
248  {
249 // if (*lIt<=this->currentLevel)
250  {
251 
252  labelT l1_orig = mIt->first, l1 = equivalentLabels[l1_orig];
253  labelT l2_orig = mIt->second, l2 = equivalentLabels[l2_orig];
254 
255  if (l1 != l2)
256  {
257  // merge basins
258  labelT eater = mergeBasins(l1, l2), eaten;
259  labelT eater_orig, eaten_orig;
260 
261  if (eater==l1)
262  {
263  eater_orig = l1_orig;
264  eaten = l2;
265  eaten_orig = l2_orig;
266  }
267  else
268  {
269  eater_orig = l2_orig;
270  eaten = l1;
271  eaten_orig = l1_orig;
272  }
273 
274  if (graph)
275  graph->addEdge(eater_orig, eaten_orig, this->extinctionValues[eaten]);
276 
277  updateEquTable(eaten, eater);
278  }
279  mIt = pendingMerges.erase(mIt);
280 // mergeLevels.erase(lIt);
281  }
282 // else
283 // {
284 // mIt++;
285 // lIt++;
286 // }
287  }
288  }
289 
290  inline virtual void processPixel(const size_t &curOffset)
291  {
292  if (this->inPixels[curOffset] > currentLevel)
293  {
294  processMerges();
295 
296  currentLevel = this->inPixels[curOffset];
297  for (labelT i = 1; i < labelNbr + 1 ; ++i)
298  if (equivalentLabels[i]==i)
299  raiseLevel(i);
300  }
301 
303 
304  labelT l1 = this->lblPixels[curOffset];
305 
306  insertPixel(curOffset, equivalentLabels[l1]);
307 
308  lastOffset = curOffset;
309  }
310 
311  inline virtual void processNeighbor(const size_t &curOffset, const size_t &nbOffset)
312  {
313  labelT nbLbl = this->lblPixels[nbOffset];
314  labelT curLbl = this->lblPixels[curOffset];//==this->STAT_QUEUED ? 0 : this->lblPixels[curOffset];
315 
316  if (nbLbl==0) // Add it to the tmp offsets queue
317  {
318  this->hq.push(this->inPixels[nbOffset], nbOffset);
319  this->lblPixels[nbOffset] = curLbl;
320 
321  }
322  else
323  {
324  if (equivalentLabels[nbLbl]!=equivalentLabels[curLbl])
325  pendingMerges.push_back( make_pair(min(curLbl,nbLbl), max(curLbl,nbLbl)) );
326  }
327 
328  }
329 
330 
331  };
332 
333 
334  template <class T, class labelT, class extValType=UINT, class HQ_Type=HierarchicalQueue<T> >
335  class AreaExtinctionFlooding : public ExtinctionFlooding<T, labelT, extValType, HQ_Type>
336  {
337  public:
338  vector<UINT> areas;
339  vector<T> minValues;
340 
341  virtual void createBasins(const UINT &nbr)
342  {
343  areas.resize(nbr, 0);
344  minValues.resize(nbr, ImDtTypes<T>::max());
345 
347  }
348 
349  virtual void deleteBasins()
350  {
351  areas.clear();
352  minValues.clear();
353 
355  }
356 
357  inline virtual void insertPixel(const size_t &offset, const labelT &lbl)
358  {
359  if (this->inPixels[offset] < minValues[lbl])
360  minValues[lbl] = this->inPixels[offset];
361 
362  areas[lbl]++;
363  }
364  virtual labelT mergeBasins(const labelT &lbl1, const labelT &lbl2)
365  {
366  labelT eater, eaten;
367 
368  if (areas[lbl1] > areas[lbl2] || (areas[lbl1] == areas[lbl2] && minValues[lbl1] < minValues[lbl2]))
369  {
370  eater = lbl1;
371  eaten = lbl2;
372  }
373  else
374  {
375  eater = lbl2;
376  eaten = lbl1;
377  }
378 
379  this->extinctionValues[eaten] = areas[eaten];
380  areas[eater] += areas[eaten];
381 
382  return eater;
383  }
384  virtual void finalize(const labelT &lbl)
385  {
386  this->extinctionValues[lbl] += areas[lbl];
387  }
388  };
389 
390  template <class T, class labelT, class extValType=UINT, class HQ_Type=HierarchicalQueue<T> >
391  class VolumeExtinctionFlooding : public ExtinctionFlooding<T, labelT, extValType, HQ_Type>
392  {
393  vector<UINT> areas, volumes;
394  vector<T> floodLevels;
395 
396  virtual void createBasins(const UINT &nbr)
397  {
398  areas.resize(nbr, 0);
399  volumes.resize(nbr, 0);
400  floodLevels.resize(nbr, 0);
401 
403  }
404 
405  virtual void deleteBasins()
406  {
407  areas.clear();
408  volumes.clear();
409  floodLevels.clear();
410 
412  }
413 
414 
415  virtual void insertPixel(const size_t &offset, const labelT &lbl)
416  {
417  floodLevels[lbl] = max(this->currentLevel, floodLevels[lbl]);
418  volumes[lbl] += this->currentLevel-this->inPixels[offset]; // If currentLevel > pixel value (ex. non-minima markers)
419  areas[lbl]++;
420  }
421  virtual void raiseLevel(const labelT &lbl)
422  {
423  if (floodLevels[lbl] < this->currentLevel)
424  {
425  volumes[lbl] += areas[lbl] * (this->currentLevel - floodLevels[lbl]);
426  floodLevels[lbl] = this->currentLevel;
427  }
428  }
429  virtual labelT mergeBasins(const labelT &lbl1, const labelT &lbl2)
430  {
431  labelT eater, eaten;
432 
433  if (volumes[lbl1] > volumes[lbl2] || (volumes[lbl1] == volumes[lbl2] && floodLevels[lbl1] < floodLevels[lbl2]))
434  {
435  eater = lbl1;
436  eaten = lbl2;
437  }
438  else
439  {
440  eater = lbl2;
441  eaten = lbl1;
442  }
443 
444  this->extinctionValues[eaten] = volumes[eaten];
445  volumes[eater] += volumes[eaten];
446  areas[eater] += areas[eaten];
447 
448  return eater;
449  }
450  virtual void finalize(const labelT &lbl)
451  {
452  volumes[lbl] += areas[lbl];
453  this->extinctionValues[lbl] += volumes[lbl];
454  }
455 
456  };
457 
458  template <class T, class labelT, class extValType=UINT, class HQ_Type=HierarchicalQueue<T> >
459  class DynamicExtinctionFlooding : public AreaExtinctionFlooding<T, labelT, extValType, HQ_Type>
460  {
461  virtual labelT mergeBasins(const labelT &lbl1, const labelT &lbl2)
462  {
463  labelT eater, eaten;
464 
465  if (this->minValues[lbl1] < this->minValues[lbl2] || (this->minValues[lbl1] == this->minValues[lbl2] && this->areas[lbl1] > this->areas[lbl2]))
466  {
467  eater = lbl1;
468  eaten = lbl2;
469  }
470  else
471  {
472  eater = lbl2;
473  eaten = lbl1;
474  }
475 
476  this->extinctionValues[eaten] = this->currentLevel - this->minValues[eaten];
477  this->areas[eater] += this->areas[eaten];
478 
479  return eater;
480  }
481  virtual void finalize(const labelT &lbl)
482  {
483  this->extinctionValues[lbl] = this->currentLevel - this->minValues[lbl];
484  }
485  };
486 
487 
488 
489  //*******************************************
490  //******** GENERAL EXPORTED FUNCTIONS
491  //*******************************************
492 
493 
494  template < class T, class labelT, class outT >
495  RES_T watershedExtinction (const Image<T> &imIn,
496  const Image<labelT> &imMarkers,
497  Image<outT> &imOut,
498  Image<labelT> &imBasinsOut,
499  const char * extinctionType="v",
500  const StrElt &se = DEFAULT_SE,
501  bool rankOutput=true)
502  {
503  RES_T res = RES_ERR;
504 
505  if (rankOutput)
506  {
507  ExtinctionFlooding<T, labelT, UINT> *flooding = NULL; // outT type may be smaller than the required flooding type
508 
509  if(strcmp(extinctionType, "v")==0)
511  else if(strcmp(extinctionType, "a")==0)
513  else if(strcmp(extinctionType, "d")==0)
515 
516  if (flooding)
517  {
518  flooding->floodWithExtRank(imIn, imMarkers, imOut, imBasinsOut, se);
519  delete flooding;
520  }
521  }
522 
523  else
524  {
525  ExtinctionFlooding<T, labelT, outT> *flooding = NULL; // outT type may be smaller than the required flooding type
526 
527  if(strcmp(extinctionType, "v")==0)
529  else if(strcmp(extinctionType, "a")==0)
531  else if(strcmp(extinctionType, "d")==0)
533 
534  if (flooding)
535  {
536  flooding->floodWithExtValues(imIn, imMarkers, imOut, imBasinsOut, se);
537  delete flooding;
538  }
539  }
540 
541  return res;
542  }
543 
544  template < class T, class labelT, class outT >
545  RES_T watershedExtinction (const Image < T > &imIn,
546  Image < labelT > &imMarkers,
547  Image < outT > &imOut,
548  const char * extinctionType="v",
549  const StrElt & se = DEFAULT_SE,
550  bool rankOutput=true)
551  {
552  ASSERT_ALLOCATED (&imIn, &imMarkers, &imOut);
553  ASSERT_SAME_SIZE (&imIn, &imMarkers, &imOut);
554  Image < labelT > imBasinsOut (imMarkers);
555  return watershedExtinction (imIn, imMarkers, imOut, imBasinsOut, extinctionType, se, rankOutput);
556  }
557 
558  template < class T, class outT >
559  RES_T watershedExtinction (const Image < T > &imIn,
560  Image < outT > &imOut,
561  const char * extinctionType="v",
562  const StrElt & se = DEFAULT_SE,
563  bool rankOutput=true)
564  {
565  ASSERT_ALLOCATED (&imIn, &imOut);
566  ASSERT_SAME_SIZE (&imIn, &imOut);
567  Image < T > imMin (imIn);
568  minima (imIn, imMin, se);
569  Image < UINT > imLbl (imIn);
570  label (imMin, imLbl, se);
571  return watershedExtinction (imIn, imLbl, imOut,extinctionType, se, rankOutput);
572  }
573 
579  template < class T, class labelT, class outT >
581  const Image < labelT > &imMarkers,
582  Image < labelT > &imBasinsOut,
583  Graph < labelT, outT > &graph,
584  const char * extinctionType="v",
585  const StrElt & se = DEFAULT_SE)
586  {
587 
588  ExtinctionFlooding<T, labelT, outT> *flooding = NULL; // outT type may be smaller than the required flooding type
589 
590  if(strcmp(extinctionType, "v")==0)
592  else if(strcmp(extinctionType, "a")==0)
594  else if(strcmp(extinctionType, "d")==0)
596  else return RES_ERR;
597 
598  RES_T res = flooding->flood(imIn, imMarkers, imBasinsOut, graph, se);
599 
600  delete flooding;
601 
602  return res;
603 
604  }
605  template < class T, class labelT, class outT >
606  RES_T watershedExtinctionGraph (const Image < T > &imIn,
607  Image < labelT > &imBasinsOut,
608  Graph < labelT, outT > &graph,
609  const char * extinctionType="v",
610  const StrElt & se = DEFAULT_SE)
611  {
612  ASSERT_ALLOCATED (&imIn, &imBasinsOut);
613  ASSERT_SAME_SIZE (&imIn, &imBasinsOut);
614 
615  Image<T> imMin (imIn);
616  minima(imIn, imMin, se);
617  Image<labelT> imLbl(imBasinsOut);
618  label(imMin, imLbl, se);
619 
620  return watershedExtinctionGraph(imIn, imLbl, imBasinsOut, graph, extinctionType, se);
621  }
622 
626  template < class T, class labelT>
628  const Image < labelT > &imMarkers,
629  Image < labelT > &imBasinsOut,
630  const char * extinctionType="v",
631  const StrElt & se = DEFAULT_SE)
632  {
633  Graph<labelT,UINT> graph;
634  Graph<labelT,labelT> rankGraph;
635  ASSERT(watershedExtinctionGraph(imIn, imMarkers, imBasinsOut, graph, extinctionType, se)==RES_OK, rankGraph);
636 
637  // Sort edges by extinctionValues
638  graph.sortEdges();
639 
640 
641  typedef typename Graph<labelT,UINT>::EdgeType EdgeType;
642  const vector<EdgeType> &edges = graph.getEdges();
643  UINT edgesNbr = edges.size();
644 
645  for (UINT i=0;i<edgesNbr;i++)
646  rankGraph.addEdge(edges[i].source, edges[i].target, i+1, false);
647 
648  return rankGraph;
649  }
650  template < class T, class labelT>
652  Image < labelT > &imBasinsOut,
653  const char * extinctionType="v",
654  const StrElt & se = DEFAULT_SE)
655  {
656  Graph<labelT,UINT> graph;
657  Graph<labelT,labelT> rankGraph;
658  ASSERT(watershedExtinctionGraph(imIn, imBasinsOut, graph, extinctionType, se)==RES_OK, rankGraph);
659 
660  // Sort edges by extinctionValues
661  graph.sortEdges();
662 
663 
664  typedef typename Graph<labelT,UINT>::EdgeType EdgeType;
665  const vector<EdgeType> &edges = graph.getEdges();
666  UINT edgesNbr = edges.size();
667 
668  for (UINT i=0;i<edgesNbr;i++)
669  rankGraph.addEdge(edges[i].source, edges[i].target, i+1, false);
670 
671  return rankGraph;
672  }
673 } // namespace smil
674 
675 
676 #endif // _D_MORPHO_WATERSHED_EXTINCTION_HPP
RES_T minima(const Image< T > &imIn, Image< T > &imOut, const StrElt &se=DEFAULT_SE)
Minima.
Definition: DMorphoExtrema.hpp:51
Author Vincent Morard Date : 7 march 2011 See : Morard V. and Dokladal P. and Decenciere E...
Definition: DApplyThreshold.hpp:36
RES_T copy(const Image< T1 > &imIn, size_t startX, size_t startY, size_t startZ, size_t sizeX, size_t sizeY, size_t sizeZ, Image< T2 > &imOut, size_t outStartX=0, size_t outStartY=0, size_t outStartZ=0)
Copy image.
Definition: DImageArith.hpp:114
Definition: DBaseImage.h:235
Non-oriented edge.
Definition: DGraph.hpp:52
RES_T fill(Image< T > &imOut, const T &value)
Fill an image with a given value.
Definition: DImageArith.hpp:62
Definition: DMorphoWatershedExtinction.hpp:391
Base structuring element.
Definition: DStructuringElement.h:51
void clear()
Clear graph content.
Definition: DGraph.hpp:198
size_t label(const Image< T1 > &imIn, Image< T2 > &imOut, const StrElt &se=DEFAULT_SE)
Image labelization.
Definition: DMorphoLabel.hpp:503
size_t getPixelCount() const
Get the number of pixels.
Definition: DBaseImage.h:150
Generic extinction flooding process.
Definition: DMorphoWatershedExtinction.hpp:71
Definition: DTypes.hpp:80
Main Image class.
Definition: DQVtkViewer.hpp:42
Definition: DMorphoWatershedExtinction.hpp:459
RES_T extinctionValues(const Image< T1 > &imIn, Image< T2 > &imOut, const StrElt &se=DEFAULT_SE)
Extinction values.
Definition: DSkeleton.hpp:101
Definition: DMorphoWatershed.hpp:50
lineType getPixels() const
Get the pixels as a 1D array.
Definition: DImage.hpp:110
Definition: DMorphoWatershedExtinction.hpp:49
void addEdge(const EdgeType &e, bool checkIfExists=true)
Add an edge to the graph.
Definition: DGraph.hpp:237
T maxVal(const Image< T > &imIn, bool onlyNonZero=false)
Max value of an image.
Definition: Base/include/private/DMeasures.hpp:260
RES_T watershedExtinctionGraph(const Image< T > &imIn, const Image< labelT > &imMarkers, Image< labelT > &imBasinsOut, Graph< labelT, outT > &graph, const char *extinctionType="v", const StrElt &se=DEFAULT_SE)
Calculation of the minimum spanning tree, simultaneously to the image flooding, with edges weighted a...
Definition: DMorphoWatershedExtinction.hpp:580
Definition: DMorphoWatershedExtinction.hpp:335
RES_T rank(const Image< T > &imIn, Image< T > &imOut, double percentile, const StrElt &se=DEFAULT_SE)
Rank filter.
Definition: DMorphoFilter.hpp:208