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  // Propagate label on plateaus
320  if (this->inPixels[nbOffset]==this->inPixels[curOffset] && curLbl!=0)
321  this->lblPixels[nbOffset] = curLbl;
322  else
323  this->lblPixels[nbOffset] = this->STAT_QUEUED;
324  }
325  else if (nbLbl<this->STAT_QUEUED)
326  {
327  labelT curLbl = this->lblPixels[curOffset];
328  if (curLbl==0 || curLbl==this->STAT_QUEUED)
329  this->lblPixels[curOffset] = this->lblPixels[nbOffset];
330  else if (equivalentLabels[nbLbl]!=equivalentLabels[curLbl])
331  pendingMerges.push_back( make_pair(min(curLbl,nbLbl), max(curLbl,nbLbl)) );
332  }
333 
334  }
335 
336 
337  };
338 
339 
340  template <class T, class labelT, class extValType=UINT, class HQ_Type=HierarchicalQueue<T> >
341  class AreaExtinctionFlooding : public ExtinctionFlooding<T, labelT, extValType, HQ_Type>
342  {
343  public:
344  vector<UINT> areas;
345  vector<T> minValues;
346 
347  virtual void createBasins(const UINT &nbr)
348  {
349  areas.resize(nbr, 0);
350  minValues.resize(nbr, ImDtTypes<T>::max());
351 
353  }
354 
355  virtual void deleteBasins()
356  {
357  areas.clear();
358  minValues.clear();
359 
361  }
362 
363  inline virtual void insertPixel(const size_t &offset, const labelT &lbl)
364  {
365  if (this->inPixels[offset] < minValues[lbl])
366  minValues[lbl] = this->inPixels[offset];
367 
368  areas[lbl]++;
369  }
370  virtual labelT mergeBasins(const labelT &lbl1, const labelT &lbl2)
371  {
372  labelT eater, eaten;
373 
374  if (areas[lbl1] > areas[lbl2] || (areas[lbl1] == areas[lbl2] && minValues[lbl1] < minValues[lbl2]))
375  {
376  eater = lbl1;
377  eaten = lbl2;
378  }
379  else
380  {
381  eater = lbl2;
382  eaten = lbl1;
383  }
384 
385  this->extinctionValues[eaten] = areas[eaten];
386  areas[eater] += areas[eaten];
387 
388  return eater;
389  }
390  virtual void finalize(const labelT &lbl)
391  {
392  this->extinctionValues[lbl] += areas[lbl];
393  }
394  };
395 
396  template <class T, class labelT, class extValType=UINT, class HQ_Type=HierarchicalQueue<T> >
397  class VolumeExtinctionFlooding : public ExtinctionFlooding<T, labelT, extValType, HQ_Type>
398  {
399  vector<UINT> areas, volumes;
400  vector<T> floodLevels;
401 
402  virtual void createBasins(const UINT &nbr)
403  {
404  areas.resize(nbr, 0);
405  volumes.resize(nbr, 0);
406  floodLevels.resize(nbr, 0);
407 
409  }
410 
411  virtual void deleteBasins()
412  {
413  areas.clear();
414  volumes.clear();
415  floodLevels.clear();
416 
418  }
419 
420 
421  virtual void insertPixel(const size_t &offset, const labelT &lbl)
422  {
423  floodLevels[lbl] = max(this->currentLevel, floodLevels[lbl]);
424  volumes[lbl] += this->currentLevel-this->inPixels[offset]; // If currentLevel > pixel value (ex. non-minima markers)
425  areas[lbl]++;
426  }
427  virtual void raiseLevel(const labelT &lbl)
428  {
429  if (floodLevels[lbl] < this->currentLevel)
430  {
431  volumes[lbl] += areas[lbl] * (this->currentLevel - floodLevels[lbl]);
432  floodLevels[lbl] = this->currentLevel;
433  }
434  }
435  virtual labelT mergeBasins(const labelT &lbl1, const labelT &lbl2)
436  {
437  labelT eater, eaten;
438 
439  if (volumes[lbl1] > volumes[lbl2] || (volumes[lbl1] == volumes[lbl2] && floodLevels[lbl1] < floodLevels[lbl2]))
440  {
441  eater = lbl1;
442  eaten = lbl2;
443  }
444  else
445  {
446  eater = lbl2;
447  eaten = lbl1;
448  }
449 
450  this->extinctionValues[eaten] = volumes[eaten];
451  volumes[eater] += volumes[eaten];
452  areas[eater] += areas[eaten];
453 
454  return eater;
455  }
456  virtual void finalize(const labelT &lbl)
457  {
458  volumes[lbl] += areas[lbl];
459  this->extinctionValues[lbl] += volumes[lbl];
460  }
461 
462  };
463 
464  template <class T, class labelT, class extValType=UINT, class HQ_Type=HierarchicalQueue<T> >
465  class DynamicExtinctionFlooding : public AreaExtinctionFlooding<T, labelT, extValType, HQ_Type>
466  {
467  virtual labelT mergeBasins(const labelT &lbl1, const labelT &lbl2)
468  {
469  labelT eater, eaten;
470 
471  if (this->minValues[lbl1] < this->minValues[lbl2] || (this->minValues[lbl1] == this->minValues[lbl2] && this->areas[lbl1] > this->areas[lbl2]))
472  {
473  eater = lbl1;
474  eaten = lbl2;
475  }
476  else
477  {
478  eater = lbl2;
479  eaten = lbl1;
480  }
481 
482  this->extinctionValues[eaten] = this->currentLevel - this->minValues[eaten];
483  this->areas[eater] += this->areas[eaten];
484 
485  return eater;
486  }
487  virtual void finalize(const labelT &lbl)
488  {
489  this->extinctionValues[lbl] = this->currentLevel - this->minValues[lbl];
490  }
491  };
492 
493 
494 
495  //*******************************************
496  //******** GENERAL EXPORTED FUNCTIONS
497  //*******************************************
498 
499 
500  template < class T, class labelT, class outT >
501  RES_T watershedExtinction (const Image<T> &imIn,
502  const Image<labelT> &imMarkers,
503  Image<outT> &imOut,
504  Image<labelT> &imBasinsOut,
505  const char * extinctionType="v",
506  const StrElt &se = DEFAULT_SE,
507  bool rankOutput=true)
508  {
509  RES_T res = RES_ERR;
510 
511  if (rankOutput)
512  {
513  ExtinctionFlooding<T, labelT, UINT> *flooding = NULL; // outT type may be smaller than the required flooding type
514 
515  if(strcmp(extinctionType, "v")==0)
517  else if(strcmp(extinctionType, "a")==0)
519  else if(strcmp(extinctionType, "d")==0)
521 
522  if (flooding)
523  {
524  flooding->floodWithExtRank(imIn, imMarkers, imOut, imBasinsOut, se);
525  delete flooding;
526  }
527  }
528 
529  else
530  {
531  ExtinctionFlooding<T, labelT, outT> *flooding = NULL; // outT type may be smaller than the required flooding type
532 
533  if(strcmp(extinctionType, "v")==0)
535  else if(strcmp(extinctionType, "a")==0)
537  else if(strcmp(extinctionType, "d")==0)
539 
540  if (flooding)
541  {
542  flooding->floodWithExtValues(imIn, imMarkers, imOut, imBasinsOut, se);
543  delete flooding;
544  }
545  }
546 
547  return res;
548  }
549 
550  template < class T, class labelT, class outT >
551  RES_T watershedExtinction (const Image < T > &imIn,
552  Image < labelT > &imMarkers,
553  Image < outT > &imOut,
554  const char * extinctionType="v",
555  const StrElt & se = DEFAULT_SE,
556  bool rankOutput=true)
557  {
558  ASSERT_ALLOCATED (&imIn, &imMarkers, &imOut);
559  ASSERT_SAME_SIZE (&imIn, &imMarkers, &imOut);
560  Image < labelT > imBasinsOut (imMarkers);
561  return watershedExtinction (imIn, imMarkers, imOut, imBasinsOut, extinctionType, se, rankOutput);
562  }
563 
564  template < class T, class outT >
565  RES_T watershedExtinction (const Image < T > &imIn,
566  Image < outT > &imOut,
567  const char * extinctionType="v",
568  const StrElt & se = DEFAULT_SE,
569  bool rankOutput=true)
570  {
571  ASSERT_ALLOCATED (&imIn, &imOut);
572  ASSERT_SAME_SIZE (&imIn, &imOut);
573  Image < T > imMin (imIn);
574  minima (imIn, imMin, se);
575  Image < UINT > imLbl (imIn);
576  label (imMin, imLbl, se);
577  return watershedExtinction (imIn, imLbl, imOut,extinctionType, se, rankOutput);
578  }
579 
585  template < class T, class labelT, class outT >
587  const Image < labelT > &imMarkers,
588  Image < labelT > &imBasinsOut,
589  Graph < labelT, outT > &graph,
590  const char * extinctionType="v",
591  const StrElt & se = DEFAULT_SE)
592  {
593 
594  ExtinctionFlooding<T, labelT, outT> *flooding = NULL; // outT type may be smaller than the required flooding type
595 
596  if(strcmp(extinctionType, "v")==0)
598  else if(strcmp(extinctionType, "a")==0)
600  else if(strcmp(extinctionType, "d")==0)
602  else return RES_ERR;
603 
604  RES_T res = flooding->flood(imIn, imMarkers, imBasinsOut, graph, se);
605 
606  delete flooding;
607 
608  return res;
609 
610  }
611  template < class T, class labelT, class outT >
612  RES_T watershedExtinctionGraph (const Image < T > &imIn,
613  Image < labelT > &imBasinsOut,
614  Graph < labelT, outT > &graph,
615  const char * extinctionType="v",
616  const StrElt & se = DEFAULT_SE)
617  {
618  ASSERT_ALLOCATED (&imIn, &imBasinsOut);
619  ASSERT_SAME_SIZE (&imIn, &imBasinsOut);
620 
621  Image<T> imMin (imIn);
622  minima(imIn, imMin, se);
623  Image<labelT> imLbl(imBasinsOut);
624  label(imMin, imLbl, se);
625 
626  return watershedExtinctionGraph(imIn, imLbl, imBasinsOut, graph, extinctionType, se);
627  }
628 
632  template < class T, class labelT>
634  const Image < labelT > &imMarkers,
635  Image < labelT > &imBasinsOut,
636  const char * extinctionType="v",
637  const StrElt & se = DEFAULT_SE)
638  {
639  Graph<labelT,UINT> graph;
640  Graph<labelT,labelT> rankGraph;
641  ASSERT(watershedExtinctionGraph(imIn, imMarkers, imBasinsOut, graph, extinctionType, se)==RES_OK, rankGraph);
642 
643  // Sort edges by extinctionValues
644  graph.sortEdges();
645 
646 
647  typedef typename Graph<labelT,UINT>::EdgeType EdgeType;
648  const vector<EdgeType> &edges = graph.getEdges();
649  UINT edgesNbr = edges.size();
650 
651  for (UINT i=0;i<edgesNbr;i++)
652  rankGraph.addEdge(edges[i].source, edges[i].target, i+1, false);
653 
654  return rankGraph;
655  }
656  template < class T, class labelT>
658  Image < labelT > &imBasinsOut,
659  const char * extinctionType="v",
660  const StrElt & se = DEFAULT_SE)
661  {
662  Graph<labelT,UINT> graph;
663  Graph<labelT,labelT> rankGraph;
664  ASSERT(watershedExtinctionGraph(imIn, imBasinsOut, graph, extinctionType, se)==RES_OK, rankGraph);
665 
666  // Sort edges by extinctionValues
667  graph.sortEdges();
668 
669 
670  typedef typename Graph<labelT,UINT>::EdgeType EdgeType;
671  const vector<EdgeType> &edges = graph.getEdges();
672  UINT edgesNbr = edges.size();
673 
674  for (UINT i=0;i<edgesNbr;i++)
675  rankGraph.addEdge(edges[i].source, edges[i].target, i+1, false);
676 
677  return rankGraph;
678  }
679 } // namespace smil
680 
681 
682 #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
Definition: DColorConvert.h:38
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
lineType getPixels() const
Get the pixels as a 1D array.
Definition: DImage.hpp:110
RES_T fill(Image< T > &imOut, const T &value)
Fill an image with a given value.
Definition: DImageArith.hpp:62
Definition: DMorphoWatershedExtinction.hpp:397
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:78
Main Image class.
Definition: DQVtkViewer.hpp:44
Definition: DMorphoWatershedExtinction.hpp:465
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
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: 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:586
Definition: DMorphoWatershedExtinction.hpp:341
RES_T rank(const Image< T > &imIn, Image< T > &imOut, double percentile, const StrElt &se=DEFAULT_SE)
Rank filter.
Definition: DMorphoFilter.hpp:208