18 #ifndef itkLabelSetUtils_h
19 #define itkLabelSetUtils_h
29 template<
class LineBufferType,
class RealType >
31 const RealType magnitude,
const RealType Sigma)
36 const long LineLength = LineBuf.size();
38 for (
long pos = 0; pos < LineLength; pos++ )
43 unsigned offset = LineLength - pos;
44 left = leftend - magnitude * ( pos + 1 ) * ( pos + 1 );
45 right = rightend - magnitude * offset * offset;
49 LineBuf[pos] = std::min(std::min(left, right), Sigma);
53 template<
class LineBufferType,
class LabLineBufferType,
class RealType >
55 LabLineBufferType & LabBuf,
56 LabLineBufferType & NewLabBuf,
57 const RealType magnitude)
60 const long LineLength = LineBuf.size();
62 RealType lastval = LineBuf[0];
64 for (
long pos = 0; pos < LineLength; pos++ )
67 RealType krange = pos - lastcontact;
68 RealType thisval = lastval - magnitude * krange * krange;
70 if ( LineBuf[pos] >= LineBuf[lastcontact] )
73 lastval = LineBuf[pos];
75 tmpLineBuf[pos] = std::max(LineBuf[pos], thisval);
76 if ( thisval > LineBuf[pos] )
78 NewLabBuf[pos] = LabBuf[lastcontact];
82 NewLabBuf[pos] = LabBuf[pos];
86 lastcontact = LineLength - 1;
87 lastval = tmpLineBuf[lastcontact];
88 for (
long pos = LineLength - 1; pos >= 0; pos-- )
91 RealType krange = lastcontact - pos;
92 RealType thisval = lastval - magnitude * krange * krange;
94 if ( tmpLineBuf[pos] >= tmpLineBuf[lastcontact] )
97 lastval = tmpLineBuf[pos];
99 LineBuf[pos] = std::max(tmpLineBuf[pos], thisval);
100 if ( thisval > tmpLineBuf[pos] )
102 NewLabBuf[pos] = LabBuf[lastcontact];
113 template<
class LineBufferType,
class RealType,
bool doDilate >
114 void DoLine(LineBufferType & LineBuf, LineBufferType & tmpLineBuf,
115 const RealType magnitude,
const RealType m_Extreme)
118 long koffset = 0, newcontact = 0;
120 const long LineLength = LineBuf.size();
123 for (
long pos = 0; pos < LineLength; pos++ )
125 RealType BaseVal = (RealType)m_Extreme;
127 for (
long krange = koffset; krange <= 0; krange++ )
130 RealType T = LineBuf[pos + krange] - magnitude * krange * krange;
132 if ( doDilate ? ( T >= BaseVal ) : ( T <= BaseVal ) )
138 tmpLineBuf[pos] = BaseVal;
139 koffset = newcontact - 1;
142 koffset = newcontact = 0;
143 for (
long pos = LineLength - 1; pos >= 0; pos-- )
145 RealType BaseVal = (RealType)m_Extreme;
146 for (
long krange = koffset; krange >= 0; krange-- )
148 RealType T = tmpLineBuf[pos + krange] - magnitude * krange * krange;
149 if ( doDilate ? ( T >= BaseVal ) : ( T <= BaseVal ) )
155 LineBuf[pos] = BaseVal;
156 koffset = newcontact + 1;
160 template<
class LineBufferType,
class LabBufferType,
class RealType,
bool doDilate >
162 LabBufferType & LabelBuf, LabBufferType & tmpLabelBuf,
163 const RealType magnitude,
const RealType m_Extreme)
166 long koffset = 0, newcontact = 0;
168 typedef typename LabBufferType::ValueType LabelType;
170 const long LineLength = LineBuf.size();
172 for (
long pos = 0; pos < LineLength; pos++ )
174 RealType BaseVal = (RealType)m_Extreme;
176 LabelType BaseLab = LabelBuf[pos];
177 for (
long krange = koffset; krange <= 0; krange++ )
180 RealType T = LineBuf[pos + krange] - magnitude * krange * krange;
182 if ( doDilate ? ( T >= BaseVal ) : ( T <= BaseVal ) )
186 BaseLab = LabelBuf[pos + krange];
189 tmpLineBuf[pos] = BaseVal;
190 tmpLabelBuf[pos] = BaseLab;
191 koffset = newcontact - 1;
194 koffset = newcontact = 0;
196 for (
long pos = LineLength - 1; pos >= 0; pos-- )
198 RealType BaseVal = (RealType)m_Extreme;
200 LabelType BaseLab = tmpLabelBuf[pos];
201 for (
long krange = koffset; krange >= 0; krange-- )
203 RealType T = tmpLineBuf[pos + krange] - magnitude * krange * krange;
204 if ( doDilate ? ( T >= BaseVal ) : ( T <= BaseVal ) )
208 BaseLab = tmpLabelBuf[pos + krange];
211 LineBuf[pos] = BaseVal;
212 LabelBuf[pos] = BaseLab;
213 koffset = newcontact + 1;
216 for (
long pos = LineLength - 1; pos >= 0; pos-- )
218 LineBuf[pos] = tmpLineBuf[pos];
219 LabelBuf[pos] = tmpLabelBuf[pos];
225 template<
class TInIter,
class TOutDistIter,
class TOutLabIter,
class RealType >
227 TOutLabIter & outputLabIterator,
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,
243 RealType iscale = 1.0;
244 if ( m_UseImageSpacing )
246 iscale = image_scale;
251 const RealType magnitude = ( m_MagnitudeSign * iscale * iscale ) / ( 2.0 );
252 LineBufferType LineBuf(LineLength);
253 LabelBufferType LabBuf(LineLength);
255 inputIterator.SetDirection(direction);
256 outputIterator.SetDirection(direction);
257 outputLabIterator.SetDirection(direction);
259 inputIterator.GoToBegin();
260 outputIterator.GoToBegin();
261 outputLabIterator.GoToBegin();
263 while ( !inputIterator.IsAtEnd() && !outputIterator.IsAtEnd() )
271 while ( !inputIterator.IsAtEndOfLine() )
273 LabBuf[i] = ( inputIterator.Get() );
283 typedef std::vector< unsigned > EndType;
287 for (
unsigned idx = 0; idx < LineLength; idx++ )
289 RealType val = LabBuf[idx];
293 firsts.push_back(idx);
294 unsigned idxend = idx;
295 for (; idxend < LineLength; idxend++ )
297 if ( val != LabBuf[idxend] )
302 lasts.push_back(idxend - 1);
307 for (
unsigned R = 0; R < firsts.size(); R++ )
309 unsigned first = firsts[R];
310 unsigned last = lasts[R];
311 unsigned SLL = last - first + 1;
312 LineBufferType ShortLineBuf(SLL);
315 RealType leftend = 0, rightend = 0;
316 if ( first == 0 ) { leftend = Sigma; }
317 if ( last == LineLength - 1 ) { rightend = Sigma; }
319 DoLineErodeFirstPass< LineBufferType, RealType >(ShortLineBuf, leftend, rightend, magnitude, Sigma);
321 std::copy( ShortLineBuf.begin(), ShortLineBuf.end(), &( LineBuf[first] ) );
325 while ( !outputIterator.IsAtEndOfLine() )
327 outputIterator.Set( static_cast< typename TOutDistIter::PixelType >( LineBuf[j++] ) );
336 while ( !outputLabIterator.IsAtEndOfLine() )
338 typename TInIter::PixelType val = 0;
339 if ( LineBuf[j2] == Sigma )
343 outputLabIterator.Set(val);
347 outputLabIterator.NextLine();
351 inputIterator.NextLine();
352 outputIterator.NextLine();
357 template<
class TInIter,
class TOutDistIter,
class TOutLabIter,
class RealType >
359 TOutLabIter & outputLabIterator,
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)
374 RealType iscale = 1.0;
375 if ( m_UseImageSpacing )
377 iscale = image_scale;
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);
388 inputIterator.SetDirection(direction);
389 outputIterator.SetDirection(direction);
390 outputLabIterator.SetDirection(direction);
392 inputIterator.GoToBegin();
393 outputIterator.GoToBegin();
394 outputLabIterator.GoToBegin();
396 while ( !inputIterator.IsAtEnd() && !outputIterator.IsAtEnd() )
404 while ( !inputIterator.IsAtEndOfLine() )
406 LabBuf[i] = ( inputIterator.Get() );
419 DoLineDilateFirstPass< LineBufferType, LabelBufferType, RealType >(LineBuf,
426 while ( !outputIterator.IsAtEndOfLine() )
428 outputIterator.Set( static_cast< typename TOutDistIter::PixelType >( LineBuf[j] ) );
429 outputLabIterator.Set(newLabBuf[j]);
436 inputIterator.NextLine();
437 outputIterator.NextLine();
438 outputLabIterator.NextLine();
443 template<
class TInIter,
class TDistIter,
class TOutLabIter,
class TOutDistIter,
class RealType >
445 TOutDistIter & outputDistIterator, TOutLabIter & outputLabIterator,
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,
460 RealType iscale = 1.0;
461 if ( m_UseImageSpacing )
463 iscale = image_scale;
465 const RealType magnitude = ( m_MagnitudeSign * iscale * iscale ) / ( 2.0 * Sigma );
466 LineBufferType LineBuf(LineLength);
467 LabelBufferType LabBuf(LineLength);
469 inputIterator.SetDirection(direction);
470 outputDistIterator.SetDirection(direction);
471 inputDistIterator.SetDirection(direction);
472 outputLabIterator.SetDirection(direction);
474 inputIterator.GoToBegin();
475 outputDistIterator.GoToBegin();
476 inputDistIterator.GoToBegin();
477 outputLabIterator.GoToBegin();
479 while ( !inputIterator.IsAtEnd() && !outputDistIterator.IsAtEnd() )
487 while ( !inputIterator.IsAtEndOfLine() )
489 LineBuf[i] =
static_cast< RealType
>( inputDistIterator.Get() );
490 LabBuf[i] = inputIterator.Get();
496 typedef std::vector< unsigned > EndType;
499 for (
unsigned idx = 0; idx < LineLength; idx++ )
501 RealType val = LabBuf[idx];
505 firsts.push_back(idx);
506 unsigned idxend = idx;
507 for (; idxend < LineLength; idxend++ )
509 if ( val != LabBuf[idxend] )
514 lasts.push_back(idxend - 1);
519 for (
unsigned R = 0; R < firsts.size(); R++ )
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);
529 RealType leftend = 0, rightend = 0;
530 if ( first == 0 ) { leftend = BaseSigma; }
531 if ( last == LineLength - 1 ) { rightend = BaseSigma; }
533 ShortLineBuf[0] = leftend;
534 ShortLineBuf[SLL + 1] = rightend;
536 std::copy( &( LineBuf[first] ), &( LineBuf[last + 1] ), &( ShortLineBuf[1] ) );
538 DoLine< LineBufferType, RealType, false >(ShortLineBuf, tmpShortLineBuf, magnitude, m_Extreme);
540 std::copy( &( ShortLineBuf[1] ), &( ShortLineBuf[SLL + 1] ), &( LineBuf[first] ) );
545 while ( !outputDistIterator.IsAtEndOfLine() )
547 outputDistIterator.Set( static_cast< typename TOutDistIter::PixelType >( LineBuf[j++] ) );
548 ++outputDistIterator;
554 while ( !outputLabIterator.IsAtEndOfLine() )
556 typename TInIter::PixelType val = 0;
557 if ( LineBuf[j2] == BaseSigma )
561 outputLabIterator.Set(val);
565 outputLabIterator.NextLine();
568 inputIterator.NextLine();
569 inputDistIterator.NextLine();
570 outputDistIterator.NextLine();
575 template<
class TInIter,
class TDistIter,
class TOutLabIter,
class TOutDistIter,
class RealType >
577 TOutDistIter & outputDistIterator, TOutLabIter & outputLabIterator,
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,
592 RealType iscale = 1.0;
593 if ( m_UseImageSpacing )
595 iscale = image_scale;
598 const RealType magnitude = ( m_MagnitudeSign * iscale * iscale ) / ( 2.0 * Sigma );
600 LineBufferType LineBuf(LineLength);
601 LabelBufferType LabBuf(LineLength);
602 LineBufferType tmpLineBuf(LineLength);
603 LabelBufferType newLabBuf(LineLength);
604 LabelBufferType tmpLabBuf(LineLength);
606 inputIterator.SetDirection(direction);
607 inputDistIterator.SetDirection(direction);
608 outputDistIterator.SetDirection(direction);
609 outputLabIterator.SetDirection(direction);
611 inputIterator.GoToBegin();
612 inputDistIterator.GoToBegin();
613 outputDistIterator.GoToBegin();
614 outputLabIterator.GoToBegin();
616 while ( !inputDistIterator.IsAtEnd() && !outputLabIterator.IsAtEnd() )
624 while ( !inputDistIterator.IsAtEndOfLine() )
626 LineBuf[i] = inputDistIterator.Get();
627 LabBuf[i] = inputIterator.Get();
633 DoLineLabelProp< LineBufferType, LabelBufferType, RealType, true >(LineBuf,
641 while ( !outputDistIterator.IsAtEndOfLine() )
643 outputDistIterator.Set( static_cast< typename TOutDistIter::PixelType >( LineBuf[j] ) );
644 outputLabIterator.Set(LabBuf[j]);
645 ++outputDistIterator;
651 inputIterator.NextLine();
652 outputLabIterator.NextLine();
653 inputDistIterator.NextLine();
654 outputDistIterator.NextLine();
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.