ITK  4.13.0
Insight Segmentation and Registration Toolkit
itkLabelSetUtils.h
Go to the documentation of this file.
1 /*=========================================================================
2  *
3  * Copyright Insight Software Consortium
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0.txt
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  *=========================================================================*/
18 #ifndef itkLabelSetUtils_h
19 #define itkLabelSetUtils_h
20 
21 #include <itkArray.h>
22 
23 #include "itkProgressReporter.h"
24 #include <vector>
25 namespace itk
26 {
27 namespace LabSet
28 {
29 template< class LineBufferType, class RealType >
30 void DoLineErodeFirstPass(LineBufferType & LineBuf, RealType leftend, RealType rightend,
31  const RealType magnitude, const RealType Sigma)
32 {
33  // This is the first pass algorithm. We can write down the values
34  // because we know the inputs are binary
35 
36  const long LineLength = LineBuf.size();
37 
38  for ( long pos = 0; pos < LineLength; pos++ )
39  {
40  // compute the height of the parabola starting at each end and
41  // keep the minimum
42  RealType left, right;
43  unsigned offset = LineLength - pos;
44  left = leftend - magnitude * ( pos + 1 ) * ( pos + 1 );
45  right = rightend - magnitude * offset * offset;
46  // note hard coded value here - could be a parameter
47 // LineBuf[pos] = std::min(std::min(left, right),
48 // itk::NumericTraits<RealType>::One);
49  LineBuf[pos] = std::min(std::min(left, right), Sigma);
50  }
51 }
52 
53 template< class LineBufferType, class LabLineBufferType, class RealType >
54 void DoLineDilateFirstPass(LineBufferType & LineBuf, LineBufferType & tmpLineBuf,
55  LabLineBufferType & LabBuf,
56  LabLineBufferType & NewLabBuf,
57  const RealType magnitude)
58 {
59  // need to propagate the labels here
60  const long LineLength = LineBuf.size();
61  long lastcontact = 0;
62  RealType lastval = LineBuf[0];
63 
64  for ( long pos = 0; pos < LineLength; pos++ )
65  {
66  // left pass
67  RealType krange = pos - lastcontact;
68  RealType thisval = lastval - magnitude * krange * krange;
69 
70  if ( LineBuf[pos] >= LineBuf[lastcontact] )
71  {
72  lastcontact = pos;
73  lastval = LineBuf[pos];
74  }
75  tmpLineBuf[pos] = std::max(LineBuf[pos], thisval);
76  if ( thisval > LineBuf[pos] )
77  {
78  NewLabBuf[pos] = LabBuf[lastcontact];
79  }
80  else
81  {
82  NewLabBuf[pos] = LabBuf[pos];
83  }
84  }
85 
86  lastcontact = LineLength - 1;
87  lastval = tmpLineBuf[lastcontact];
88  for ( long pos = LineLength - 1; pos >= 0; pos-- )
89  {
90  // right pass
91  RealType krange = lastcontact - pos;
92  RealType thisval = lastval - magnitude * krange * krange;
93 
94  if ( tmpLineBuf[pos] >= tmpLineBuf[lastcontact] )
95  {
96  lastcontact = pos;
97  lastval = tmpLineBuf[pos];
98  }
99  LineBuf[pos] = std::max(tmpLineBuf[pos], thisval);
100  if ( thisval > tmpLineBuf[pos] )
101  {
102  NewLabBuf[pos] = LabBuf[lastcontact];
103  }
104  // only need to do this bit on the first pass - it doubles as a
105  // way of initializing NewLabPos
106  // else
107  // {
108  // NewLabBuf[pos] = LabBuf[pos];
109  // }
110  }
111 }
112 
113 template< class LineBufferType, class RealType, bool doDilate >
114 void DoLine(LineBufferType & LineBuf, LineBufferType & tmpLineBuf,
115  const RealType magnitude, const RealType m_Extreme)
116 {
117  // contact point algorithm
118  long koffset = 0, newcontact = 0; // how far away the search starts.
119 
120  const long LineLength = LineBuf.size();
121 
122  // negative half of the parabola
123  for ( long pos = 0; pos < LineLength; pos++ )
124  {
125  RealType BaseVal = (RealType)m_Extreme; // the base value for
126  // comparison
127  for ( long krange = koffset; krange <= 0; krange++ )
128  {
129  // difference needs to be paramaterised
130  RealType T = LineBuf[pos + krange] - magnitude * krange * krange;
131  // switch on template parameter - hopefully gets optimized away.
132  if ( doDilate ? ( T >= BaseVal ) : ( T <= BaseVal ) )
133  {
134  BaseVal = T;
135  newcontact = krange;
136  }
137  }
138  tmpLineBuf[pos] = BaseVal;
139  koffset = newcontact - 1;
140  }
141  // positive half of parabola
142  koffset = newcontact = 0;
143  for ( long pos = LineLength - 1; pos >= 0; pos-- )
144  {
145  RealType BaseVal = (RealType)m_Extreme; // the base value for comparison
146  for ( long krange = koffset; krange >= 0; krange-- )
147  {
148  RealType T = tmpLineBuf[pos + krange] - magnitude * krange * krange;
149  if ( doDilate ? ( T >= BaseVal ) : ( T <= BaseVal ) )
150  {
151  BaseVal = T;
152  newcontact = krange;
153  }
154  }
155  LineBuf[pos] = BaseVal;
156  koffset = newcontact + 1;
157  }
158 }
159 
160 template< class LineBufferType, class LabBufferType, class RealType, bool doDilate >
161 void DoLineLabelProp(LineBufferType & LineBuf, LineBufferType & tmpLineBuf,
162  LabBufferType & LabelBuf, LabBufferType & tmpLabelBuf,
163  const RealType magnitude, const RealType m_Extreme)
164 {
165  // contact point algorithm
166  long koffset = 0, newcontact = 0; // how far away the search starts.
167 
168  typedef typename LabBufferType::ValueType LabelType;
169 
170  const long LineLength = LineBuf.size();
171  // negative half of the parabola
172  for ( long pos = 0; pos < LineLength; pos++ )
173  {
174  RealType BaseVal = (RealType)m_Extreme; // the base value for
175  // comparison
176  LabelType BaseLab = LabelBuf[pos];
177  for ( long krange = koffset; krange <= 0; krange++ )
178  {
179  // difference needs to be paramaterised
180  RealType T = LineBuf[pos + krange] - magnitude * krange * krange;
181  // switch on template parameter - hopefully gets optimized away.
182  if ( doDilate ? ( T >= BaseVal ) : ( T <= BaseVal ) )
183  {
184  BaseVal = T;
185  newcontact = krange;
186  BaseLab = LabelBuf[pos + krange];
187  }
188  }
189  tmpLineBuf[pos] = BaseVal;
190  tmpLabelBuf[pos] = BaseLab;
191  koffset = newcontact - 1;
192  }
193  // positive half of parabola
194  koffset = newcontact = 0;
195 #if 1
196  for ( long pos = LineLength - 1; pos >= 0; pos-- )
197  {
198  RealType BaseVal = (RealType)m_Extreme; // the base value for comparison
199  // initialize the label to the previously pro
200  LabelType BaseLab = tmpLabelBuf[pos];
201  for ( long krange = koffset; krange >= 0; krange-- )
202  {
203  RealType T = tmpLineBuf[pos + krange] - magnitude * krange * krange;
204  if ( doDilate ? ( T >= BaseVal ) : ( T <= BaseVal ) )
205  {
206  BaseVal = T;
207  newcontact = krange;
208  BaseLab = tmpLabelBuf[pos + krange];
209  }
210  }
211  LineBuf[pos] = BaseVal;
212  LabelBuf[pos] = BaseLab;
213  koffset = newcontact + 1;
214  }
215 #else
216  for ( long pos = LineLength - 1; pos >= 0; pos-- )
217  {
218  LineBuf[pos] = tmpLineBuf[pos];
219  LabelBuf[pos] = tmpLabelBuf[pos];
220  }
221 
222 #endif
223 }
224 
225 template< class TInIter, class TOutDistIter, class TOutLabIter, class RealType >
226 void doOneDimensionErodeFirstPass(TInIter & inputIterator, TOutDistIter & outputIterator,
227  TOutLabIter & outputLabIterator,
228  ProgressReporter & progress,
229  const unsigned LineLength,
230  const unsigned direction,
231  const int m_MagnitudeSign,
232  const bool m_UseImageSpacing,
233  const RealType m_Extreme,
234  const RealType image_scale,
235  const RealType Sigma,
236  const bool lastpass)
237 {
238  // specialised version for binary erosion during first pass. We can
239  // compute the results directly because the inputs are flat.
240  (void)m_Extreme; // avoid warning
241  typedef typename itk::Array< RealType > LineBufferType;
242  typedef typename itk::Array< typename TInIter::PixelType > LabelBufferType;
243  RealType iscale = 1.0;
244  if ( m_UseImageSpacing )
245  {
246  iscale = image_scale;
247  }
248  // restructure equation to reduce numerical error
249 // const RealType magnitude = (m_MagnitudeSign * iscale * iscale)/(2.0 *
250 // Sigma);
251  const RealType magnitude = ( m_MagnitudeSign * iscale * iscale ) / ( 2.0 );
252  LineBufferType LineBuf(LineLength);
253  LabelBufferType LabBuf(LineLength);
254 
255  inputIterator.SetDirection(direction);
256  outputIterator.SetDirection(direction);
257  outputLabIterator.SetDirection(direction);
258 
259  inputIterator.GoToBegin();
260  outputIterator.GoToBegin();
261  outputLabIterator.GoToBegin();
262 
263  while ( !inputIterator.IsAtEnd() && !outputIterator.IsAtEnd() )
264  {
265  // process this direction
266  // fetch the line into the buffer - this methodology is like
267  // the gaussian filters
268  unsigned int i = 0;
269 
270  // copy the scanline to a buffer
271  while ( !inputIterator.IsAtEndOfLine() )
272  {
273  LabBuf[i] = ( inputIterator.Get() );
274  if ( LabBuf[i] )
275  {
276  LineBuf[i] = 1.0;
277  }
278  ++i;
279  ++inputIterator;
280  }
281  // runlength encode the line buffer (could be integrated with extraction)
282 
283  typedef std::vector< unsigned > EndType;
284  EndType firsts;
285  EndType lasts;
286 
287  for ( unsigned idx = 0; idx < LineLength; idx++ )
288  {
289  RealType val = LabBuf[idx];
290  if ( val != 0 )
291  {
292  // found a run
293  firsts.push_back(idx);
294  unsigned idxend = idx;
295  for (; idxend < LineLength; idxend++ )
296  {
297  if ( val != LabBuf[idxend] )
298  {
299  break;
300  }
301  }
302  lasts.push_back(idxend - 1);
303  idx = idxend - 1;
304  }
305  }
306 
307  for ( unsigned R = 0; R < firsts.size(); R++ )
308  {
309  unsigned first = firsts[R];
310  unsigned last = lasts[R];
311  unsigned SLL = last - first + 1;
312  LineBufferType ShortLineBuf(SLL);
313  // if one end of the run touches the image edge, then we leave
314  // the value as 1
315  RealType leftend = 0, rightend = 0;
316  if ( first == 0 ) { leftend = Sigma; }
317  if ( last == LineLength - 1 ) { rightend = Sigma; }
318 
319  DoLineErodeFirstPass< LineBufferType, RealType >(ShortLineBuf, leftend, rightend, magnitude, Sigma);
320  // copy the segment back into the full line buffer
321  std::copy( ShortLineBuf.begin(), ShortLineBuf.end(), &( LineBuf[first] ) );
322  }
323  // copy the line buffer back to the image
324  unsigned j = 0;
325  while ( !outputIterator.IsAtEndOfLine() )
326  {
327  outputIterator.Set( static_cast< typename TOutDistIter::PixelType >( LineBuf[j++] ) );
328  ++outputIterator;
329  }
330 
331  if ( lastpass )
332  {
333  // copy to the output image - this would be a weird case of only
334  // using a one dimensional SE
335  unsigned j2 = 0;
336  while ( !outputLabIterator.IsAtEndOfLine() )
337  {
338  typename TInIter::PixelType val = 0;
339  if ( LineBuf[j2] == Sigma )
340  {
341  val = LabBuf[j2];
342  }
343  outputLabIterator.Set(val);
344  ++outputLabIterator;
345  ++j2;
346  }
347  outputLabIterator.NextLine();
348  }
349 
350  // now onto the next line
351  inputIterator.NextLine();
352  outputIterator.NextLine();
353  progress.CompletedPixel();
354  }
355 }
356 
357 template< class TInIter, class TOutDistIter, class TOutLabIter, class RealType >
358 void doOneDimensionDilateFirstPass(TInIter & inputIterator, TOutDistIter & outputIterator,
359  TOutLabIter & outputLabIterator,
360  ProgressReporter & progress,
361  const unsigned LineLength,
362  const unsigned direction,
363  const int m_MagnitudeSign,
364  const bool m_UseImageSpacing,
365  const RealType m_Extreme,
366  const RealType image_scale,
367  const RealType Sigma)
368 {
369  // specialised version for binary erosion during first pass. We can
370  // compute the results directly because the inputs are flat.
371  (void)m_Extreme; // stop warnings
372  typedef typename itk::Array< RealType > LineBufferType;
373  typedef typename itk::Array< typename TInIter::PixelType > LabelBufferType;
374  RealType iscale = 1.0;
375  if ( m_UseImageSpacing )
376  {
377  iscale = image_scale;
378  }
379  // restructure equation to reduce numerical error
380  //const RealType magnitude = (m_MagnitudeSign * iscale * iscale)/(2.0 *
381  // Sigma);
382  const RealType magnitude = ( m_MagnitudeSign * iscale * iscale ) / ( 2.0 );
383  LineBufferType LineBuf(LineLength);
384  LabelBufferType LabBuf(LineLength);
385  LineBufferType tmpLineBuf(LineLength);
386  LabelBufferType newLabBuf(LineLength);
387 
388  inputIterator.SetDirection(direction);
389  outputIterator.SetDirection(direction);
390  outputLabIterator.SetDirection(direction);
391 
392  inputIterator.GoToBegin();
393  outputIterator.GoToBegin();
394  outputLabIterator.GoToBegin();
395 
396  while ( !inputIterator.IsAtEnd() && !outputIterator.IsAtEnd() )
397  {
398  // process this direction
399  // fetch the line into the buffer - this methodology is like
400  // the gaussian filters
401  unsigned int i = 0;
402 
403  // copy the scanline to a buffer
404  while ( !inputIterator.IsAtEndOfLine() )
405  {
406  LabBuf[i] = ( inputIterator.Get() );
407  if ( LabBuf[i] )
408  {
409  LineBuf[i] = Sigma;
410  }
411  else
412  {
413  LineBuf[i] = 0;
414  }
415  ++i;
416  ++inputIterator;
417  }
418 
419  DoLineDilateFirstPass< LineBufferType, LabelBufferType, RealType >(LineBuf,
420  tmpLineBuf,
421  LabBuf,
422  newLabBuf,
423  magnitude);
424  // copy the line buffer back to the image
425  unsigned j = 0;
426  while ( !outputIterator.IsAtEndOfLine() )
427  {
428  outputIterator.Set( static_cast< typename TOutDistIter::PixelType >( LineBuf[j] ) );
429  outputLabIterator.Set(newLabBuf[j]);
430  ++outputLabIterator;
431  ++outputIterator;
432  ++j;
433  }
434 
435  // now onto the next line
436  inputIterator.NextLine();
437  outputIterator.NextLine();
438  outputLabIterator.NextLine();
439  progress.CompletedPixel();
440  }
441 }
442 
443 template< class TInIter, class TDistIter, class TOutLabIter, class TOutDistIter, class RealType >
444 void doOneDimensionErode(TInIter & inputIterator, TDistIter & inputDistIterator,
445  TOutDistIter & outputDistIterator, TOutLabIter & outputLabIterator,
446  ProgressReporter & progress,
447  const unsigned LineLength,
448  const unsigned direction,
449  const int m_MagnitudeSign,
450  const bool m_UseImageSpacing,
451  const RealType m_Extreme,
452  const RealType image_scale,
453  const RealType Sigma,
454  const RealType BaseSigma,
455  const bool lastpass)
456 {
457  // traditional erosion - can't optimise the same way as the first pass
458  typedef typename itk::Array< RealType > LineBufferType;
459  typedef typename itk::Array< typename TInIter::PixelType > LabelBufferType;
460  RealType iscale = 1.0;
461  if ( m_UseImageSpacing )
462  {
463  iscale = image_scale;
464  }
465  const RealType magnitude = ( m_MagnitudeSign * iscale * iscale ) / ( 2.0 * Sigma );
466  LineBufferType LineBuf(LineLength);
467  LabelBufferType LabBuf(LineLength);
468 
469  inputIterator.SetDirection(direction);
470  outputDistIterator.SetDirection(direction);
471  inputDistIterator.SetDirection(direction);
472  outputLabIterator.SetDirection(direction);
473 
474  inputIterator.GoToBegin();
475  outputDistIterator.GoToBegin();
476  inputDistIterator.GoToBegin();
477  outputLabIterator.GoToBegin();
478 
479  while ( !inputIterator.IsAtEnd() && !outputDistIterator.IsAtEnd() )
480  {
481  // process this direction
482  // fetch the line into the buffer - this methodology is like
483  // the gaussian filters
484  unsigned int i = 0;
485 
486  // copy the scanline to a buffer
487  while ( !inputIterator.IsAtEndOfLine() )
488  {
489  LineBuf[i] = static_cast< RealType >( inputDistIterator.Get() );
490  LabBuf[i] = inputIterator.Get();
491  ++i;
492  ++inputDistIterator;
493  ++inputIterator;
494  }
495  // runlength encode the line buffer (could be integrated with extraction)
496  typedef std::vector< unsigned > EndType;
497  EndType firsts;
498  EndType lasts;
499  for ( unsigned idx = 0; idx < LineLength; idx++ )
500  {
501  RealType val = LabBuf[idx];
502  if ( val != 0 )
503  {
504  // found a run
505  firsts.push_back(idx);
506  unsigned idxend = idx;
507  for (; idxend < LineLength; idxend++ )
508  {
509  if ( val != LabBuf[idxend] )
510  {
511  break;
512  }
513  }
514  lasts.push_back(idxend - 1);
515  idx = idxend - 1;
516  }
517  }
518 
519  for ( unsigned R = 0; R < firsts.size(); R++ )
520  {
521  unsigned first = firsts[R];
522  unsigned last = lasts[R];
523  unsigned SLL = last - first + 1;
524  LineBufferType ShortLineBuf(SLL + 2);
525  LineBufferType tmpShortLineBuf(SLL + 2);
526 
527  // if one end of the run touches the image edge, then we leave
528  // the value as 1
529  RealType leftend = 0, rightend = 0;
530  if ( first == 0 ) { leftend = BaseSigma; }
531  if ( last == LineLength - 1 ) { rightend = BaseSigma; }
532 
533  ShortLineBuf[0] = leftend;
534  ShortLineBuf[SLL + 1] = rightend;
535 
536  std::copy( &( LineBuf[first] ), &( LineBuf[last + 1] ), &( ShortLineBuf[1] ) );
537 
538  DoLine< LineBufferType, RealType, false >(ShortLineBuf, tmpShortLineBuf, magnitude, m_Extreme);
539  // copy the segment back into the full line buffer
540  std::copy( &( ShortLineBuf[1] ), &( ShortLineBuf[SLL + 1] ), &( LineBuf[first] ) );
541  }
542  // copy the line buffer back to the image - don't need to do it on
543  // the last pass - move when we are sure it is working
544  unsigned j = 0;
545  while ( !outputDistIterator.IsAtEndOfLine() )
546  {
547  outputDistIterator.Set( static_cast< typename TOutDistIter::PixelType >( LineBuf[j++] ) );
548  ++outputDistIterator;
549  }
550 
551  if ( lastpass )
552  {
553  unsigned j2 = 0;
554  while ( !outputLabIterator.IsAtEndOfLine() )
555  {
556  typename TInIter::PixelType val = 0;
557  if ( LineBuf[j2] == BaseSigma )
558  {
559  val = LabBuf[j2];
560  }
561  outputLabIterator.Set(val);
562  ++outputLabIterator;
563  ++j2;
564  }
565  outputLabIterator.NextLine();
566  }
567  // now onto the next line
568  inputIterator.NextLine();
569  inputDistIterator.NextLine();
570  outputDistIterator.NextLine();
571  progress.CompletedPixel();
572  }
573 }
574 
575 template< class TInIter, class TDistIter, class TOutLabIter, class TOutDistIter, class RealType >
576 void doOneDimensionDilate(TInIter & inputIterator, TDistIter & inputDistIterator,
577  TOutDistIter & outputDistIterator, TOutLabIter & outputLabIterator,
578  ProgressReporter & progress,
579  const unsigned LineLength,
580  const unsigned direction,
581  const int m_MagnitudeSign,
582  const bool m_UseImageSpacing,
583  const RealType m_Extreme,
584  const RealType image_scale,
585  const RealType Sigma
586  )
587 {
588  // specialised version for binary erosion during first pass. We can
589  // compute the results directly because the inputs are flat.
590  typedef typename itk::Array< RealType > LineBufferType;
591  typedef typename itk::Array< typename TInIter::PixelType > LabelBufferType;
592  RealType iscale = 1.0;
593  if ( m_UseImageSpacing )
594  {
595  iscale = image_scale;
596  }
597  // restructure equation to reduce numerical error
598  const RealType magnitude = ( m_MagnitudeSign * iscale * iscale ) / ( 2.0 * Sigma );
599 // const RealType magnitude = (m_MagnitudeSign * iscale * iscale)/(2.0 );
600  LineBufferType LineBuf(LineLength);
601  LabelBufferType LabBuf(LineLength);
602  LineBufferType tmpLineBuf(LineLength);
603  LabelBufferType newLabBuf(LineLength);
604  LabelBufferType tmpLabBuf(LineLength);
605 
606  inputIterator.SetDirection(direction);
607  inputDistIterator.SetDirection(direction);
608  outputDistIterator.SetDirection(direction);
609  outputLabIterator.SetDirection(direction);
610 
611  inputIterator.GoToBegin();
612  inputDistIterator.GoToBegin();
613  outputDistIterator.GoToBegin();
614  outputLabIterator.GoToBegin();
615 
616  while ( !inputDistIterator.IsAtEnd() && !outputLabIterator.IsAtEnd() )
617  {
618  // process this direction
619  // fetch the line into the buffer - this methodology is like
620  // the gaussian filters
621  unsigned int i = 0;
622 
623  // copy the scanline to a buffer
624  while ( !inputDistIterator.IsAtEndOfLine() )
625  {
626  LineBuf[i] = inputDistIterator.Get();
627  LabBuf[i] = inputIterator.Get();
628  ++i;
629  ++inputIterator;
630  ++inputDistIterator;
631  }
632 
633  DoLineLabelProp< LineBufferType, LabelBufferType, RealType, true >(LineBuf,
634  tmpLineBuf,
635  LabBuf,
636  tmpLabBuf,
637  magnitude,
638  m_Extreme);
639  // copy the line buffer back to the image
640  unsigned j = 0;
641  while ( !outputDistIterator.IsAtEndOfLine() )
642  {
643  outputDistIterator.Set( static_cast< typename TOutDistIter::PixelType >( LineBuf[j] ) );
644  outputLabIterator.Set(LabBuf[j]);
645  ++outputDistIterator;
646  ++outputLabIterator;
647  j++;
648  }
649 
650  // now onto the next line
651  inputIterator.NextLine();
652  outputLabIterator.NextLine();
653  inputDistIterator.NextLine();
654  outputDistIterator.NextLine();
655  progress.CompletedPixel();
656  }
657 }
658 }
659 }
660 #endif
void DoLineErodeFirstPass(LineBufferType &LineBuf, RealType leftend, RealType rightend, const RealType magnitude, const RealType Sigma)
void DoLine(LineBufferType &LineBuf, LineBufferType &tmpLineBuf, const RealType magnitude, const RealType m_Extreme)
void doOneDimensionErodeFirstPass(TInIter &inputIterator, TOutDistIter &outputIterator, TOutLabIter &outputLabIterator, ProgressReporter &progress, const unsigned LineLength, const unsigned direction, const int m_MagnitudeSign, const bool m_UseImageSpacing, const RealType m_Extreme, const RealType image_scale, const RealType Sigma, const bool lastpass)
void doOneDimensionErode(TInIter &inputIterator, TDistIter &inputDistIterator, TOutDistIter &outputDistIterator, TOutLabIter &outputLabIterator, ProgressReporter &progress, const unsigned LineLength, const unsigned direction, const int m_MagnitudeSign, const bool m_UseImageSpacing, const RealType m_Extreme, const RealType image_scale, const RealType Sigma, const RealType BaseSigma, const bool lastpass)
void doOneDimensionDilateFirstPass(TInIter &inputIterator, TOutDistIter &outputIterator, TOutLabIter &outputLabIterator, ProgressReporter &progress, const unsigned LineLength, const unsigned direction, const int m_MagnitudeSign, const bool m_UseImageSpacing, const RealType m_Extreme, const RealType image_scale, const RealType Sigma)
void DoLineDilateFirstPass(LineBufferType &LineBuf, LineBufferType &tmpLineBuf, LabLineBufferType &LabBuf, LabLineBufferType &NewLabBuf, const RealType magnitude)
void doOneDimensionDilate(TInIter &inputIterator, TDistIter &inputDistIterator, TOutDistIter &outputDistIterator, TOutLabIter &outputLabIterator, ProgressReporter &progress, const unsigned LineLength, const unsigned direction, const int m_MagnitudeSign, const bool m_UseImageSpacing, const RealType m_Extreme, const RealType image_scale, const RealType Sigma)
void DoLineLabelProp(LineBufferType &LineBuf, LineBufferType &tmpLineBuf, LabBufferType &LabelBuf, LabBufferType &tmpLabelBuf, const RealType magnitude, const RealType m_Extreme)
Implements progress tracking for a filter.