1 // =========================================================================
2 // @author Leonardo Florez Valencia
3 // @email florez-l@javeriana.edu.co
4 // =========================================================================
6 #ifndef __fpa__Base__MoriRegionGrow__hxx__
7 #define __fpa__Base__MoriRegionGrow__hxx__
10 #include <itkProgressReporter.h>
12 // -------------------------------------------------------------------------
13 template< class _TFilter, class _TMarksInterface, class _TSeedsInterface >
15 fpa::Base::MoriRegionGrow< _TFilter, _TMarksInterface, _TSeedsInterface >::
17 const TInputValue& lower, const TInputValue& upper,
18 const TInputValue& delta
21 this->SetLowerThreshold( lower );
22 this->SetUpperThreshold( upper );
23 this->SetDeltaThreshold( delta );
26 // -------------------------------------------------------------------------
27 template< class _TFilter, class _TMarksInterface, class _TSeedsInterface >
28 fpa::Base::MoriRegionGrow< _TFilter, _TMarksInterface, _TSeedsInterface >::
31 _TMarksInterface( this ),
32 _TSeedsInterface( this )
34 this->m_UpperThreshold = std::numeric_limits< TInputValue >::max( );
35 if( std::numeric_limits< TInputValue >::is_integer )
36 this->m_LowerThreshold = std::numeric_limits< TInputValue >::min( );
38 this->m_LowerThreshold = -this->m_UpperThreshold;
39 this->m_DeltaThreshold = TInputValue( 1 );
42 // -------------------------------------------------------------------------
43 template< class _TFilter, class _TMarksInterface, class _TSeedsInterface >
44 fpa::Base::MoriRegionGrow< _TFilter, _TMarksInterface, _TSeedsInterface >::
49 // -------------------------------------------------------------------------
50 template< class _TFilter, class _TMarksInterface, class _TSeedsInterface >
52 fpa::Base::MoriRegionGrow< _TFilter, _TMarksInterface, _TSeedsInterface >::
55 // Prepare progress counter
56 double prog_size = double( this->m_UpperThreshold - this->m_LowerThreshold );
57 prog_size /= double( this->m_DeltaThreshold );
58 itk::ProgressReporter progress( this, 0, prog_size, 100, 0, 1 );
61 this->_ConfigureOutputs( std::numeric_limits< TOutputValue >::max( ) );
62 this->_InitMarks( this->GetNumberOfSeeds( ) );
65 typedef std::pair< TVertex, unsigned long > _TNode;
66 std::queue< _TNode > queues[ 2 ];
67 unsigned long frontId = 1;
68 for( TVertex seed: this->GetSeeds( ) )
69 queues[ 0 ].push( _TNode( seed, frontId++ ) );
70 unsigned int cur_queue = 0;
71 unsigned int aux_queue = 1;
73 // Incremental strategy
74 TInputValue upper = this->m_LowerThreshold + this->m_DeltaThreshold;
75 this->m_Curve.clear( );
76 unsigned long count = 0;
77 while( upper <= this->m_UpperThreshold )
79 // Main growing strategy
80 while( queues[ cur_queue ].size( ) > 0 )
83 _TNode node = queues[ cur_queue ].front( );
84 queues[ cur_queue ].pop( );
85 if( this->_IsMarked( node.first ) )
87 this->_Mark( node.first, node.second );
89 // Apply inclusion predicate
90 TInputValue value = this->_GetInputValue( node.first );
91 bool in = ( ( this->m_LowerThreshold < value ) && ( value < upper ) );
94 if( value < this->m_UpperThreshold )
95 queues[ aux_queue ].push( node );
96 this->_Mark( node.first, 0 );
101 // Ok, value lays inside region
102 this->_SetOutputValue( node.first, this->m_Curve.size( ) + 1 );
106 TVertices neighbors = this->_GetNeighbors( node.first );
107 for( TVertex neigh: neighbors )
109 if( this->_IsMarked( neigh ) )
111 // Invoke stop at collisions
112 unsigned long nColl = this->_Collisions( node.first, neigh );
114 this->StopAtOneFront( ) &&
115 this->GetNumberOfSeeds( ) > 1 &&
119 while( queues[ 0 ].size( ) > 0 )
121 while( queues[ 1 ].size( ) > 0 )
127 queues[ cur_queue ].push( _TNode( neigh, node.second ) );
134 if( this->m_Curve.size( ) > 0 )
136 if( this->m_Curve.back( ).YValue < count )
137 this->m_Curve.push_back( TCurveData( upper, count ) );
138 if( this->m_Curve.size( ) > 2 )
140 long j = this->m_Curve.size( ) - 2;
141 double yp = double( this->m_Curve[ j + 1 ].YValue );
142 double yn = double( this->m_Curve[ j - 1 ].YValue );
143 double xp = double( this->m_Curve[ j + 1 ].XValue );
144 double xn = double( this->m_Curve[ j - 1 ].XValue );
145 this->m_Curve[ j ].Diff1 = ( yp - yn ) / ( xp - xn );
150 this->m_Curve.push_back( TCurveData( upper, count ) );
153 cur_queue = aux_queue;
154 aux_queue = ( cur_queue + 1 ) % 2;
157 upper += this->m_DeltaThreshold;
158 progress.CompletedPixel( );
162 // Compute optimum threshold
163 double dmax = -std::numeric_limits< double >::max( );
165 for( long j = 1; j < this->m_Curve.size( ) - 1; ++j )
167 double dp = this->m_Curve[ j + 1 ].Diff1;
168 double dn = this->m_Curve[ j - 1 ].Diff1;
169 double xp = double( this->m_Curve[ j + 1 ].XValue );
170 double xn = double( this->m_Curve[ j - 1 ].XValue );
171 double d2 = ( dp - dn ) / ( xp - xn );
180 this->m_OptimumThreshold = TOutputValue( jmax );
184 #endif // __fpa__Base__MoriRegionGrow__hxx__