]> Creatis software - FrontAlgorithms.git/blob - lib/fpa/Base/RegionGrow.hxx
9e7bb7b801276b1db0a853c042f3ce1cdc77c1c7
[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   for( TVertex seed: this->GetSeeds( ) )
95     q.push( _TNode( seed, frontId++ ) );
96
97   // Main loop
98   while( q.size( ) > 0 )
99   {
100     // Get next candidate
101     _TNode node = q.front( );
102     q.pop( );
103     if( this->_IsMarked( node.first ) )
104       continue;
105     this->_Mark( node.first, node.second );
106
107     // Apply inclusion predicate
108     TInputValue value = this->_GetInputValue( node.first );
109     bool inside = false;
110     if( this->m_IntensityFunctor.IsNotNull( ) )
111       inside = this->m_IntensityFunctor->Evaluate( value );
112     if( this->m_VertexFunctor.IsNotNull( ) )
113       inside &= this->m_VertexFunctor->Evaluate( node.first );
114     if( !inside )
115       continue;
116
117     // Ok, pixel lays inside region
118     this->_SetOutputValue( node.first, this->m_InsideValue );
119
120     // Add neighborhood
121     TVertices neighbors = this->_GetNeighbors( node.first );
122     for( TVertex neigh: neighbors )
123     {
124       if( this->_IsMarked( neigh ) )
125       {
126         // Invoke stop at collisions
127         unsigned long nColl = this->_Collisions( node.first, neigh );
128         if(
129           this->StopAtOneFront( ) &&
130           this->GetNumberOfSeeds( ) > 1 &&
131           nColl == 1
132           )
133           while( q.size( ) > 0 )
134             q.pop( );
135       }
136       else
137         q.push( _TNode( neigh, node.second ) );
138
139     } // rof
140
141   } // elihw
142   this->_FreeMarks( );
143 }
144
145 #endif // __fpa__Base__RegionGrow__hxx__
146
147 // eof - $RCSfile$