]> Creatis software - FrontAlgorithms.git/blob - lib/fpa/Base/RegionGrow.hxx
b942dfd9eb1fb6f1fb4eb7c6bd6b667f68847388
[FrontAlgorithms.git] / lib / fpa / Base / RegionGrow.hxx
1 // =========================================================================
2 // @author Leonardo Florez Valencia
3 // @email florez-l@javeriana.edu.co
4 // =========================================================================
5
6 #ifndef __fpa__Base__RegionGrow__hxx__
7 #define __fpa__Base__RegionGrow__hxx__
8
9 #include <queue>
10
11 // -------------------------------------------------------------------------
12 template< class _TFilter, class _TMarksInterface, class _TSeedsInterface >
13 const typename
14 fpa::Base::RegionGrow< _TFilter, _TMarksInterface, _TSeedsInterface >::
15 TIntensityFunctor*
16 fpa::Base::RegionGrow< _TFilter, _TMarksInterface, _TSeedsInterface >::
17 GetIntensityPredicate( ) const
18 {
19   return( this->m_IntensityFunctor );
20 }
21
22 // -------------------------------------------------------------------------
23 template< class _TFilter, class _TMarksInterface, class _TSeedsInterface >
24 const typename
25 fpa::Base::RegionGrow< _TFilter, _TMarksInterface, _TSeedsInterface >::
26 TVertexFunctor*
27 fpa::Base::RegionGrow< _TFilter, _TMarksInterface, _TSeedsInterface >::
28 GetVertexPredicate( ) const
29 {
30   return( this->m_VertexFunctor );
31 }
32
33 // -------------------------------------------------------------------------
34 template< class _TFilter, class _TMarksInterface, class _TSeedsInterface >
35 void
36 fpa::Base::RegionGrow< _TFilter, _TMarksInterface, _TSeedsInterface >::
37 SetPredicate( TIntensityFunctor* functor )
38 {
39   if( this->m_IntensityFunctor.GetPointer( ) != functor )
40   {
41     this->m_IntensityFunctor = functor;
42     this->Modified( );
43
44   } // fi
45 }
46
47 // -------------------------------------------------------------------------
48 template< class _TFilter, class _TMarksInterface, class _TSeedsInterface >
49 void
50 fpa::Base::RegionGrow< _TFilter, _TMarksInterface, _TSeedsInterface >::
51 SetPredicate( TVertexFunctor* functor )
52 {
53   if( this->m_VertexFunctor.GetPointer( ) != functor )
54   {
55     this->m_VertexFunctor = functor;
56     this->Modified( );
57
58   } // fi
59 }
60
61 // -------------------------------------------------------------------------
62 template< class _TFilter, class _TMarksInterface, class _TSeedsInterface >
63 fpa::Base::RegionGrow< _TFilter, _TMarksInterface, _TSeedsInterface >::
64 RegionGrow( )
65   : Superclass( ),
66     _TMarksInterface( this ),
67     _TSeedsInterface( this ),
68     m_InsideValue( TOutputValue( 1 ) ),
69     m_OutsideValue( TOutputValue( 0 ) )
70 {
71 }
72
73 // -------------------------------------------------------------------------
74 template< class _TFilter, class _TMarksInterface, class _TSeedsInterface >
75 fpa::Base::RegionGrow< _TFilter, _TMarksInterface, _TSeedsInterface >::
76 ~RegionGrow( )
77 {
78 }
79
80 // -------------------------------------------------------------------------
81 template< class _TFilter, class _TMarksInterface, class _TSeedsInterface >
82 void
83 fpa::Base::RegionGrow< _TFilter, _TMarksInterface, _TSeedsInterface >::
84 GenerateData( )
85 {
86   // Init objects
87   this->_ConfigureOutputs( this->m_OutsideValue );
88   this->_InitMarks( this->GetNumberOfSeeds( ) );
89
90   // Init queue
91   typedef std::pair< TVertex, unsigned long > _TNode;
92   std::queue< _TNode > q;
93   unsigned long frontId = 1;
94   typename TSeedsInterface::TSeeds::const_iterator sIt = this->BeginSeeds( );
95   for( ; sIt != this->EndSeeds( ); ++sIt )
96     q.push( _TNode( *sIt, frontId++ ) );
97
98   // Main loop
99   while( q.size( ) > 0 )
100   {
101     // Get next candidate
102     _TNode node = q.front( );
103     q.pop( );
104     if( this->_IsMarked( node.first ) )
105       continue;
106     this->_Mark( node.first, node.second );
107
108     // Apply inclusion predicate
109     TInputValue value = this->_GetInputValue( node.first );
110     bool inside = false;
111     if( this->m_IntensityFunctor.IsNotNull( ) )
112       inside = this->m_IntensityFunctor->Evaluate( value );
113     if( this->m_VertexFunctor.IsNotNull( ) )
114       inside &= this->m_VertexFunctor->Evaluate( node.first );
115     if( !inside )
116       continue;
117
118     // Ok, pixel lays inside region
119     this->_SetOutputValue( node.first, this->m_InsideValue );
120
121     // Add neighborhood
122     TVertices neighbors = this->_GetNeighbors( node.first );
123     typename TVertices::const_iterator neighIt = neighbors.begin( );
124     for( ; neighIt != neighbors.end( ); ++neighIt )
125     {
126       TVertex neigh = *neighIt;
127       if( this->_IsMarked( neigh ) )
128       {
129         // Invoke stop at collisions
130         unsigned long nColl = this->_Collisions( node.first, neigh );
131         if(
132           this->StopAtOneFront( ) &&
133           this->GetNumberOfSeeds( ) > 1 &&
134           nColl == 1
135           )
136           while( q.size( ) > 0 )
137             q.pop( );
138       }
139       else
140         q.push( _TNode( neigh, node.second ) );
141
142     } // rof
143
144   } // elihw
145   this->_FreeMarks( );
146 }
147
148 #endif // __fpa__Base__RegionGrow__hxx__
149
150 // eof - $RCSfile$