18 #ifndef itkLabelSetUtils_h
19 #define itkLabelSetUtils_h
28 template<
class LineBufferType,
class RealType >
30 const RealType magnitude,
const RealType Sigma)
35 const long LineLength = LineBuf.size();
37 for (
long pos = 0; pos < LineLength; pos++ )
42 unsigned offset = LineLength - pos;
43 left = leftend - magnitude * ( pos + 1 ) * ( pos + 1 );
44 right = rightend - magnitude * offset * offset;
48 LineBuf[pos] = std::min(std::min(left, right), Sigma);
52 template<
class LineBufferType,
class LabLineBufferType,
class RealType >
54 LabLineBufferType & LabBuf,
55 LabLineBufferType & NewLabBuf,
56 const RealType magnitude)
59 const long LineLength = LineBuf.size();
61 RealType lastval = LineBuf[0];
63 for (
long pos = 0; pos < LineLength; pos++ )
66 RealType krange = pos - lastcontact;
67 RealType thisval = lastval - magnitude * krange * krange;
69 if ( LineBuf[pos] >= LineBuf[lastcontact] )
72 lastval = LineBuf[pos];
74 tmpLineBuf[pos] = std::max(LineBuf[pos], thisval);
75 if ( thisval > LineBuf[pos] )
77 NewLabBuf[pos] = LabBuf[lastcontact];
81 NewLabBuf[pos] = LabBuf[pos];
85 lastcontact = LineLength - 1;
86 lastval = tmpLineBuf[lastcontact];
87 for (
long pos = LineLength - 1; pos >= 0; pos-- )
90 RealType krange = lastcontact - pos;
91 RealType thisval = lastval - magnitude * krange * krange;
93 if ( tmpLineBuf[pos] >= tmpLineBuf[lastcontact] )
96 lastval = tmpLineBuf[pos];
98 LineBuf[pos] = std::max(tmpLineBuf[pos], thisval);
99 if ( thisval > tmpLineBuf[pos] )
101 NewLabBuf[pos] = LabBuf[lastcontact];
112 template<
class LineBufferType,
class RealType,
bool doDilate >
113 void DoLine(LineBufferType & LineBuf, LineBufferType & tmpLineBuf,
114 const RealType magnitude,
const RealType m_Extreme)
117 long koffset = 0, newcontact = 0;
119 const long LineLength = LineBuf.size();
122 for (
long pos = 0; pos < LineLength; pos++ )
124 auto BaseVal = (RealType)m_Extreme;
126 for (
long krange = koffset; krange <= 0; krange++ )
129 RealType T = LineBuf[pos + krange] - magnitude * krange * krange;
131 if ( doDilate ? ( T >= BaseVal ) : ( T <= BaseVal ) )
137 tmpLineBuf[pos] = BaseVal;
138 koffset = newcontact - 1;
141 koffset = newcontact = 0;
142 for (
long pos = LineLength - 1; pos >= 0; pos-- )
144 auto BaseVal = (RealType)m_Extreme;
145 for (
long krange = koffset; krange >= 0; krange-- )
147 RealType T = tmpLineBuf[pos + krange] - magnitude * krange * krange;
148 if ( doDilate ? ( T >= BaseVal ) : ( T <= BaseVal ) )
154 LineBuf[pos] = BaseVal;
155 koffset = newcontact + 1;
159 template<
class LineBufferType,
class LabBufferType,
class RealType,
bool doDilate >
161 LabBufferType & LabelBuf, LabBufferType & tmpLabelBuf,
162 const RealType magnitude,
const RealType m_Extreme)
165 long koffset = 0, newcontact = 0;
167 using LabelType =
typename LabBufferType::ValueType;
169 const long LineLength = LineBuf.size();
171 for (
long pos = 0; pos < LineLength; pos++ )
173 auto BaseVal = (RealType)m_Extreme;
175 LabelType BaseLab = LabelBuf[pos];
176 for (
long krange = koffset; krange <= 0; krange++ )
179 RealType T = LineBuf[pos + krange] - magnitude * krange * krange;
181 if ( doDilate ? ( T >= BaseVal ) : ( T <= BaseVal ) )
185 BaseLab = LabelBuf[pos + krange];
188 tmpLineBuf[pos] = BaseVal;
189 tmpLabelBuf[pos] = BaseLab;
190 koffset = newcontact - 1;
193 koffset = newcontact = 0;
195 for (
long pos = LineLength - 1; pos >= 0; pos-- )
197 auto BaseVal = (RealType)m_Extreme;
199 LabelType BaseLab = tmpLabelBuf[pos];
200 for (
long krange = koffset; krange >= 0; krange-- )
202 RealType T = tmpLineBuf[pos + krange] - magnitude * krange * krange;
203 if ( doDilate ? ( T >= BaseVal ) : ( T <= BaseVal ) )
207 BaseLab = tmpLabelBuf[pos + krange];
210 LineBuf[pos] = BaseVal;
211 LabelBuf[pos] = BaseLab;
212 koffset = newcontact + 1;
215 for (
long pos = LineLength - 1; pos >= 0; pos-- )
217 LineBuf[pos] = tmpLineBuf[pos];
218 LabelBuf[pos] = tmpLabelBuf[pos];
224 template<
class TInIter,
class TOutDistIter,
class TOutLabIter,
class RealType >
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,
239 RealType iscale = 1.0;
240 if ( m_UseImageSpacing )
242 iscale = image_scale;
247 const RealType magnitude = ( m_MagnitudeSign * iscale * iscale ) / ( 2.0 );
248 LineBufferType LineBuf(LineLength);
249 LabelBufferType LabBuf(LineLength);
251 inputIterator.SetDirection(direction);
252 outputIterator.SetDirection(direction);
253 outputLabIterator.SetDirection(direction);
255 inputIterator.GoToBegin();
256 outputIterator.GoToBegin();
257 outputLabIterator.GoToBegin();
259 while ( !inputIterator.IsAtEnd() && !outputIterator.IsAtEnd() )
267 while ( !inputIterator.IsAtEndOfLine() )
269 LabBuf[i] = ( inputIterator.Get() );
279 using EndType = std::vector< unsigned >;
283 for (
unsigned idx = 0; idx < LineLength; idx++ )
285 RealType val = LabBuf[idx];
289 firsts.push_back(idx);
290 unsigned idxend = idx;
291 for (; idxend < LineLength; idxend++ )
293 if ( val != LabBuf[idxend] )
298 lasts.push_back(idxend - 1);
303 for (
unsigned R = 0; R < firsts.size(); R++ )
305 unsigned first = firsts[R];
306 unsigned last = lasts[R];
307 unsigned SLL = last - first + 1;
308 LineBufferType ShortLineBuf(SLL);
311 RealType leftend = 0, rightend = 0;
312 if ( first == 0 ) { leftend = Sigma; }
313 if ( last == LineLength - 1 ) { rightend = Sigma; }
315 DoLineErodeFirstPass< LineBufferType, RealType >(ShortLineBuf, leftend, rightend, magnitude, Sigma);
317 std::copy( ShortLineBuf.begin(), ShortLineBuf.end(), &( LineBuf[first] ) );
321 while ( !outputIterator.IsAtEndOfLine() )
323 outputIterator.Set( static_cast< typename TOutDistIter::PixelType >( LineBuf[j++] ) );
332 while ( !outputLabIterator.IsAtEndOfLine() )
334 typename TInIter::PixelType val = 0;
335 if ( LineBuf[j2] == Sigma )
339 outputLabIterator.Set(val);
343 outputLabIterator.NextLine();
347 inputIterator.NextLine();
348 outputIterator.NextLine();
352 template<
class TInIter,
class TOutDistIter,
class TOutLabIter,
class RealType >
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)
366 RealType iscale = 1.0;
367 if ( m_UseImageSpacing )
369 iscale = image_scale;
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);
380 inputIterator.SetDirection(direction);
381 outputIterator.SetDirection(direction);
382 outputLabIterator.SetDirection(direction);
384 inputIterator.GoToBegin();
385 outputIterator.GoToBegin();
386 outputLabIterator.GoToBegin();
388 while ( !inputIterator.IsAtEnd() && !outputIterator.IsAtEnd() )
396 while ( !inputIterator.IsAtEndOfLine() )
398 LabBuf[i] = ( inputIterator.Get() );
411 DoLineDilateFirstPass< LineBufferType, LabelBufferType, RealType >(LineBuf,
418 while ( !outputIterator.IsAtEndOfLine() )
420 outputIterator.Set( static_cast< typename TOutDistIter::PixelType >( LineBuf[j] ) );
421 outputLabIterator.Set(newLabBuf[j]);
428 inputIterator.NextLine();
429 outputIterator.NextLine();
430 outputLabIterator.NextLine();
434 template<
class TInIter,
class TDistIter,
class TOutLabIter,
class TOutDistIter,
class RealType >
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,
450 RealType iscale = 1.0;
451 if ( m_UseImageSpacing )
453 iscale = image_scale;
455 const RealType magnitude = ( m_MagnitudeSign * iscale * iscale ) / ( 2.0 * Sigma );
456 LineBufferType LineBuf(LineLength);
457 LabelBufferType LabBuf(LineLength);
459 inputIterator.SetDirection(direction);
460 outputDistIterator.SetDirection(direction);
461 inputDistIterator.SetDirection(direction);
462 outputLabIterator.SetDirection(direction);
464 inputIterator.GoToBegin();
465 outputDistIterator.GoToBegin();
466 inputDistIterator.GoToBegin();
467 outputLabIterator.GoToBegin();
469 while ( !inputIterator.IsAtEnd() && !outputDistIterator.IsAtEnd() )
477 while ( !inputIterator.IsAtEndOfLine() )
479 LineBuf[i] =
static_cast< RealType
>( inputDistIterator.Get() );
480 LabBuf[i] = inputIterator.Get();
486 using EndType = std::vector< unsigned >;
489 for (
unsigned idx = 0; idx < LineLength; idx++ )
491 RealType val = LabBuf[idx];
495 firsts.push_back(idx);
496 unsigned idxend = idx;
497 for (; idxend < LineLength; idxend++ )
499 if ( val != LabBuf[idxend] )
504 lasts.push_back(idxend - 1);
509 for (
unsigned R = 0; R < firsts.size(); R++ )
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);
519 RealType leftend = 0, rightend = 0;
520 if ( first == 0 ) { leftend = BaseSigma; }
521 if ( last == LineLength - 1 ) { rightend = BaseSigma; }
523 ShortLineBuf[0] = leftend;
524 ShortLineBuf[SLL + 1] = rightend;
526 std::copy( &( LineBuf[first] ), &( LineBuf[last + 1] ), &( ShortLineBuf[1] ) );
528 DoLine< LineBufferType, RealType, false >(ShortLineBuf, tmpShortLineBuf, magnitude, m_Extreme);
530 std::copy( &( ShortLineBuf[1] ), &( ShortLineBuf[SLL + 1] ), &( LineBuf[first] ) );
535 while ( !outputDistIterator.IsAtEndOfLine() )
537 outputDistIterator.Set( static_cast< typename TOutDistIter::PixelType >( LineBuf[j++] ) );
538 ++outputDistIterator;
544 while ( !outputLabIterator.IsAtEndOfLine() )
546 typename TInIter::PixelType val = 0;
547 if ( LineBuf[j2] == BaseSigma )
551 outputLabIterator.Set(val);
555 outputLabIterator.NextLine();
558 inputIterator.NextLine();
559 inputDistIterator.NextLine();
560 outputDistIterator.NextLine();
564 template<
class TInIter,
class TDistIter,
class TOutLabIter,
class TOutDistIter,
class RealType >
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,
580 RealType iscale = 1.0;
581 if ( m_UseImageSpacing )
583 iscale = image_scale;
586 const RealType magnitude = ( m_MagnitudeSign * iscale * iscale ) / ( 2.0 * Sigma );
588 LineBufferType LineBuf(LineLength);
589 LabelBufferType LabBuf(LineLength);
590 LineBufferType tmpLineBuf(LineLength);
591 LabelBufferType newLabBuf(LineLength);
592 LabelBufferType tmpLabBuf(LineLength);
594 inputIterator.SetDirection(direction);
595 inputDistIterator.SetDirection(direction);
596 outputDistIterator.SetDirection(direction);
597 outputLabIterator.SetDirection(direction);
599 inputIterator.GoToBegin();
600 inputDistIterator.GoToBegin();
601 outputDistIterator.GoToBegin();
602 outputLabIterator.GoToBegin();
604 while ( !inputDistIterator.IsAtEnd() && !outputLabIterator.IsAtEnd() )
612 while ( !inputDistIterator.IsAtEndOfLine() )
614 LineBuf[i] = inputDistIterator.Get();
615 LabBuf[i] = inputIterator.Get();
621 DoLineLabelProp< LineBufferType, LabelBufferType, RealType, true >(LineBuf,
629 while ( !outputDistIterator.IsAtEndOfLine() )
631 outputDistIterator.Set( static_cast< typename TOutDistIter::PixelType >( LineBuf[j] ) );
632 outputLabIterator.Set(LabBuf[j]);
633 ++outputDistIterator;
639 inputIterator.NextLine();
640 outputLabIterator.NextLine();
641 inputDistIterator.NextLine();
642 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, 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)