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