17 #ifndef __itkWatershedSegmentTreeGenerator_txx
18 #define __itkWatershedSegmentTreeGenerator_txx
28 template <
class TScalarType>
31 m_ConsumeInput(false), m_HighestCalculatedFloodLevel(0.0)
35 this->SetNumberOfRequiredOutputs(1);
37 m_MergedSegmentsTable = OneWayEquivalencyTableType::New();
40 template <
class TScalarType>
45 return static_cast<DataObject*
>(SegmentTreeType::New().GetPointer());
48 template <
class TScalarType>
53 if (val > 1.0) { m_FloodLevel = 1.0; }
54 else if (val < 0.0) { m_FloodLevel = 0.0; }
55 else { m_FloodLevel = val; }
60 if ( m_HighestCalculatedFloodLevel < m_FloodLevel )
66 template <
class TScalarType>
72 m_MergedSegmentsTable->Clear();
73 this->GetOutputSegmentTree()->Clear();
78 if (m_ConsumeInput ==
true)
81 input->SortEdgeLists();
83 if (m_Merge ==
true) { this->MergeEquivalencies(); }
85 this->CompileMergeList(input, mergeList);
86 this->ExtractMergeHierarchy(input, mergeList);
92 if (m_Merge ==
true) { this->MergeEquivalencies(); }
93 this->CompileMergeList(seg, mergeList);
94 this->ExtractMergeHierarchy(seg, mergeList);
96 this->UpdateProgress(1.0);
99 if (m_FloodLevel > m_HighestCalculatedFloodLevel)
101 m_HighestCalculatedFloodLevel = m_FloodLevel;
105 template <
class TScalarType>
111 this->GetInputEquivalencyTable();
116 unsigned long counter =0;
118 segTable->PruneEdgeLists(threshold);
120 for (it = eqTable->Begin(); it != eqTable->End(); ++it)
122 MergeSegments(segTable, m_MergedSegmentsTable,
123 (*it).first, (*it).second);
125 if ( (counter % 10000) == 0 )
127 segTable->PruneEdgeLists(threshold);
128 m_MergedSegmentsTable->Flatten();
136 template <
class TScalarType>
148 unsigned long labelFROM;
149 unsigned long labelTO;
151 m_MergedSegmentsTable->Flatten();
153 segments->PruneEdgeLists(threshold);
155 for (segment_ptr = segments->Begin(); segment_ptr != segments->End();
158 labelFROM = (*segment_ptr).first;
163 = m_MergedSegmentsTable->RecursiveLookup((*segment_ptr).second.edge_list.front().label);
164 while (labelTO == labelFROM)
166 (*segment_ptr).second.edge_list.pop_front();
168 = m_MergedSegmentsTable->RecursiveLookup((*segment_ptr).second.edge_list.front().label);
173 tempMerge.
from = labelFROM;
174 tempMerge.
to = labelTO;
175 tempMerge.
saliency = (*segment_ptr).second.edge_list.front().height
176 - (*segment_ptr).second.min;
179 mergeList->PushBack(tempMerge);
185 std::make_heap(mergeList->Begin(), mergeList->End(), MergeComparison() );
188 template <
class TScalarType>
204 unsigned long toSegLabel, fromSegLabel;
206 if (heap->Empty())
return;
207 double initHeapSize =
static_cast<double>(heap->Size());
212 while( (! heap->Empty()) && (topMerge.saliency <= threshold) )
215 if ((counter == 10000))
218 segments->PruneEdgeLists(threshold);
221 if ((counter % 10000) == 0)
223 m_MergedSegmentsTable->Flatten();
226 if ((counter % 1000) == 0)
228 this->UpdateProgress(1.0 - ((static_cast<double>(heap->Size())) /
232 std::pop_heap(heap->Begin(), heap->End(), MergeComparison() );
238 fromSegLabel = m_MergedSegmentsTable->RecursiveLookup(topMerge.from);
239 toSegLabel = m_MergedSegmentsTable->RecursiveLookup(topMerge.to);
244 if ( fromSegLabel == topMerge.from && fromSegLabel != toSegLabel )
246 toSeg = segments->Lookup( toSegLabel );
248 topMerge.from = fromSegLabel;
249 topMerge.to = toSegLabel;
250 list->PushBack(topMerge);
253 Self::MergeSegments(segments, m_MergedSegmentsTable,
254 fromSegLabel, toSegLabel);
262 if (! toSeg->edge_list.empty() )
264 tempMerge.from = toSegLabel;
265 tempMerge.to = m_MergedSegmentsTable->RecursiveLookup(
266 toSeg->edge_list.front().label );
267 while (tempMerge.to == tempMerge.from)
269 toSeg->edge_list.pop_front();
270 tempMerge.to = m_MergedSegmentsTable->RecursiveLookup(
271 toSeg->edge_list.front().label );
274 (toSeg->edge_list.front().height) - toSeg->min;
276 heap->PushBack(tempMerge);
277 std::push_heap(heap->Begin(), heap->End(), MergeComparison() );
280 if( ! heap->Empty() )
282 topMerge = heap->Front();
288 template <
class TScalarType>
292 const unsigned long FROM,
const unsigned long TO,
295 typename SegmentTableType::edge_list_t::iterator edgeTOi, edgeFROMi,
299 unsigned long labelTO, labelFROM;
305 if (from_seg == 0 || to_seg == 0)
307 itkGenericExceptionMacro ( <<
"PruneMergeSegments:: An unexpected and fatal error has occurred.");
311 if ((from_seg->
min) < (to_seg->
min)) (to_seg->
min) = (from_seg->
min);
327 while ( edgeTOi != to_seg->
edge_list.end() &&
331 labelTO = eqT->RecursiveLookup(edgeTOi->label);
332 labelFROM = eqT->RecursiveLookup(edgeFROMi->label);
338 if ( seen_table.
find(labelTO) != seen_table.
end() ||
347 if ( seen_table.
find(labelFROM) != seen_table.
end() ||
355 if ( labelTO != edgeTOi->label ) edgeTOi->label = labelTO;
356 if ( labelFROM != edgeFROMi->label) edgeFROMi->label = labelFROM;
359 if ( edgeFROMi->height < edgeTOi->height )
361 to_seg->
edge_list.insert(edgeTOi, *edgeFROMi);
373 while ( edgeFROMi != from_seg->
edge_list.end() )
375 labelFROM = eqT->RecursiveLookup(edgeFROMi->label);
376 if ( seen_table.
find(labelFROM) != seen_table.
end() ||
383 if ( labelFROM != edgeFROMi->label) edgeFROMi->label = labelFROM;
391 while ( edgeTOi != to_seg->
edge_list.end() )
393 labelTO = eqT->RecursiveLookup(edgeTOi->label);
394 if ( seen_table.
find(labelTO) != seen_table.
end() ||
404 if ( labelTO != edgeTOi->label ) edgeTOi->label = labelTO;
411 segments->Erase(FROM);
417 template <
class TScalarType>
421 const unsigned long FROM,
const unsigned long TO)
423 typename SegmentTableType::edge_list_t::iterator edgeTOi, edgeFROMi,
427 unsigned long labelTO, labelFROM;
433 if (from_seg == 0 || to_seg == 0)
436 itkGenericExceptionMacro ( <<
437 "itk::watershed::SegmentTreeGenerator::MergeSegments:: An unexpected and fatal error has occurred. This is probably the result of overthresholding of the input image.");
441 if ((from_seg->
min) < (to_seg->
min)) (to_seg->
min) = (from_seg->
min);
457 while ( edgeTOi != to_seg->
edge_list.end() &&
461 labelTO = eqT->RecursiveLookup(edgeTOi->label);
462 labelFROM = eqT->RecursiveLookup(edgeFROMi->label);
468 if ( seen_table.
find(labelTO) != seen_table.
end() ||
477 if ( seen_table.
find(labelFROM) != seen_table.
end() ||
485 if ( labelTO != edgeTOi->label ) edgeTOi->label = labelTO;
486 if ( labelFROM != edgeFROMi->label) edgeFROMi->label = labelFROM;
489 if ( edgeFROMi->height < edgeTOi->height )
491 to_seg->
edge_list.insert(edgeTOi, *edgeFROMi);
503 while ( edgeFROMi != from_seg->
edge_list.end() )
505 labelFROM = eqT->RecursiveLookup(edgeFROMi->label);
506 if ( seen_table.
find(labelFROM) != seen_table.
end() ||
513 if ( labelFROM != edgeFROMi->label) edgeFROMi->label = labelFROM;
521 while ( edgeTOi != to_seg->
edge_list.end() )
523 labelTO = eqT->RecursiveLookup(edgeTOi->label);
524 if ( seen_table.
find(labelTO) != seen_table.
end() ||
534 if ( labelTO != edgeTOi->label ) edgeTOi->label = labelTO;
541 segments->Erase(FROM);
547 template <
class TScalarType>
553 template <
class TScalarType>
557 Superclass::GenerateInputRequestedRegion();
570 template<
class TScalarType>
575 Superclass::PrintSelf(os,indent);
576 os << indent <<
"FloodLevel: " << m_FloodLevel << std::endl;
577 os << indent <<
"Merge: " << m_Merge << std::endl;
578 os << indent <<
"ConsumeInput: " << m_ConsumeInput << std::endl;
579 os << indent <<
"HighestCalculatedFloodLevel: " <<
580 m_HighestCalculatedFloodLevel << std::endl;