]> Creatis software - FrontAlgorithms.git/blob - libs/fpa/Image/RegionGrow.hxx
2208070885b1795365d98543c9a1fa10e6e8fd46
[FrontAlgorithms.git] / libs / fpa / Image / RegionGrow.hxx
1 // =========================================================================
2 // @author Leonardo Florez Valencia
3 // @email florez-l@javeriana.edu.co
4 // =========================================================================
5
6 #ifndef __fpa__Image__RegionGrow__hxx__
7 #define __fpa__Image__RegionGrow__hxx__
8
9 #include <queue>
10
11 // -------------------------------------------------------------------------
12 template< class _TInputImage, class _TOutputImage >
13 void fpa::Image::RegionGrow< _TInputImage, _TOutputImage >::
14 SetPredicate( TIntensityFunctor* functor )
15 {
16   if( this->m_IntensityFunctor.GetPointer( ) != functor )
17   {
18     this->m_IntensityFunctor = functor;
19     this->Modified( );
20
21   } // fi
22 }
23
24 // -------------------------------------------------------------------------
25 template< class _TInputImage, class _TOutputImage >
26 fpa::Image::RegionGrow< _TInputImage, _TOutputImage >::
27 RegionGrow( )
28   : Superclass( ),
29     TSeedsInterface( this ),
30     TMarksInterface( this ),
31     m_InsideValue( TInputPixel( 0 ) ),
32     m_OutsideValue( TInputPixel( 0 ) )
33 {
34 }
35
36 // -------------------------------------------------------------------------
37 template< class _TInputImage, class _TOutputImage >
38 fpa::Image::RegionGrow< _TInputImage, _TOutputImage >::
39 ~RegionGrow( )
40 {
41 }
42
43 // -------------------------------------------------------------------------
44 template< class _TInputImage, class _TOutputImage >
45 void fpa::Image::RegionGrow< _TInputImage, _TOutputImage >::
46 GenerateInputRequestedRegion( )
47 {
48   this->Superclass::GenerateInputRequestedRegion( );
49   if( this->GetInput( ) )
50   {
51     TInputImage* input =
52       const_cast< TInputImage* >( this->GetInput( ) );
53     input->SetRequestedRegionToLargestPossibleRegion( );
54
55   } // fi
56 }
57
58 // -------------------------------------------------------------------------
59 template< class _TInputImage, class _TOutputImage >
60 void fpa::Image::RegionGrow< _TInputImage, _TOutputImage >::
61 EnlargeOutputRequestedRegion( itk::DataObject* output )
62 {
63   this->Superclass::EnlargeOutputRequestedRegion( output );
64   output->SetRequestedRegionToLargestPossibleRegion( );
65 }
66
67 // -------------------------------------------------------------------------
68 template< class _TInputImage, class _TOutputImage >
69 void fpa::Image::RegionGrow< _TInputImage, _TOutputImage >::
70 GenerateData( )
71 {
72   const TInputImage* input = this->GetInput( );
73   TOutputImage* output = this->GetOutput( );
74   TRegion region = input->GetRequestedRegion( );
75
76   // Configure output
77   output->SetBufferedRegion( region );
78   output->Allocate( );
79   output->FillBuffer( this->m_OutsideValue );
80
81   // Init marks
82   this->_InitMarks( this->GetNumberOfSeeds( ) );
83
84   // Init queue
85   typedef std::pair< TIndex, unsigned long > _TNode;
86   std::queue< _TNode > q;
87   unsigned long frontId = 1;
88   for( TIndex seed: this->GetSeeds( ) )
89     q.push( _TNode( seed, frontId++ ) );
90
91   // Main loop
92   while( q.size( ) > 0 )
93   {
94     // Get next candidate
95     _TNode node = q.front( );
96     q.pop( );
97     if( this->_IsMarked( node.first ) )
98       continue;
99     this->_Mark( node.first, node.second );
100
101     // Apply inclusion predicate
102     TInputPixel value = input->GetPixel( node.first );
103     bool inside = false;
104     if( this->m_IntensityFunctor.IsNotNull( ) )
105       inside = this->m_IntensityFunctor->Evaluate( value );
106     if( !inside )
107       continue;
108
109     // Ok, pixel lays inside region
110     output->SetPixel( node.first, this->m_InsideValue );
111
112     // Add neighborhood
113     for( unsigned int d = 0; d < TInputImage::ImageDimension; ++d )
114     {
115       TIndex neigh = node.first;
116       for( int i = -1; i <= 1; i += 2 )
117       {
118         neigh[ d ] = node.first[ d ] + i;
119         if( region.IsInside( neigh ) )
120         {
121           if( this->_IsMarked( neigh ) )
122           {
123             unsigned long nColl = this->_Collisions( node.first, neigh );
124             if( nColl == 1 && this->StopAtOneFront( ) )
125               while( q.size( ) > 0 )
126                 q.pop( );
127           }
128           else
129             q.push( _TNode( neigh, node.second ) );
130
131         } // fi
132
133       } // rof
134
135     } // rof
136
137   } // elihw
138   this->_FreeMarks( );
139 }
140
141 #endif // __fpa__Image__RegionGrow__hxx__
142
143 // eof - $RCSfile$