]> Creatis software - FrontAlgorithms.git/blob - libs/fpa/Image/RegionGrow.hxx
0cf74deca72c5af32a8834e34fa38e525357b4a2
[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 void fpa::Image::RegionGrow< _TInputImage, _TOutputImage >::
27 AddSeed( const TIndex& seed )
28 {
29   if( this->m_Seeds.insert( seed ).second )
30     this->Modified( );
31 }
32
33 // -------------------------------------------------------------------------
34 template< class _TInputImage, class _TOutputImage >
35 fpa::Image::RegionGrow< _TInputImage, _TOutputImage >::
36 RegionGrow( )
37   : Superclass( ),
38     m_InsideValue( TInputPixel( 0 ) ),
39     m_OutsideValue( TInputPixel( 0 ) )
40 {
41 }
42
43 // -------------------------------------------------------------------------
44 template< class _TInputImage, class _TOutputImage >
45 fpa::Image::RegionGrow< _TInputImage, _TOutputImage >::
46 ~RegionGrow( )
47 {
48 }
49
50 // -------------------------------------------------------------------------
51 template< class _TInputImage, class _TOutputImage >
52 void fpa::Image::RegionGrow< _TInputImage, _TOutputImage >::
53 GenerateInputRequestedRegion( )
54 {
55   this->Superclass::GenerateInputRequestedRegion( );
56   if( this->GetInput( ) )
57   {
58     TInputImage* input =
59       const_cast< TInputImage* >( this->GetInput( ) );
60     input->SetRequestedRegionToLargestPossibleRegion( );
61
62   } // fi
63 }
64
65 // -------------------------------------------------------------------------
66 template< class _TInputImage, class _TOutputImage >
67 void fpa::Image::RegionGrow< _TInputImage, _TOutputImage >::
68 EnlargeOutputRequestedRegion( itk::DataObject* output )
69 {
70   this->Superclass::EnlargeOutputRequestedRegion( output );
71   output->SetRequestedRegionToLargestPossibleRegion( );
72 }
73
74 // -------------------------------------------------------------------------
75 template< class _TInputImage, class _TOutputImage >
76 void fpa::Image::RegionGrow< _TInputImage, _TOutputImage >::
77 GenerateData( )
78 {
79   const TInputImage* input = this->GetInput( );
80   TOutputImage* output = this->GetOutput( );
81   TRegion region = input->GetRequestedRegion( );
82
83   // Configure output
84   output->SetBufferedRegion( region );
85   output->Allocate( );
86   output->FillBuffer( this->m_OutsideValue );
87
88   // Init marks
89   typedef itk::Image< bool, TInputImage::ImageDimension > _TMarks;
90   typename _TMarks::Pointer marks = _TMarks::New( );
91   marks->CopyInformation( input );
92   marks->SetRequestedRegion( region );
93   marks->SetBufferedRegion( input->GetBufferedRegion( ) );
94   marks->Allocate( );
95   marks->FillBuffer( false );
96
97   // Init queue
98   std::queue< TIndex > q;
99   for( TIndex seed: this->m_Seeds )
100     q.push( seed );
101
102   // Main loop
103   while( q.size( ) > 0 )
104   {
105     // Get next candidate
106     TIndex node = q.front( );
107     q.pop( );
108     if( marks->GetPixel( node ) )
109       continue;
110     marks->SetPixel( node, true );
111
112     // Apply inclusion predicate
113     TInputPixel value = input->GetPixel( node );
114     bool inside = false;
115     if( this->m_IntensityFunctor.IsNotNull( ) )
116       inside = this->m_IntensityFunctor->Evaluate( value );
117     if( !inside )
118       continue;
119
120     // Ok, pixel lays inside region
121     output->SetPixel( node, this->m_InsideValue );
122
123     // Add neighborhood
124     for( unsigned int d = 0; d < TInputImage::ImageDimension; ++d )
125     {
126       TIndex neigh = node;
127       for( int i = -1; i <= 1; i += 2 )
128       {
129         neigh[ d ] = node[ d ] + i;
130         if( region.IsInside( neigh ) )
131           q.push( neigh );
132
133       } // rof
134
135     } // rof
136
137   } // elihw
138 }
139
140 #endif // __fpa__Image__RegionGrow__hxx__
141
142 // eof - $RCSfile$