1 #ifndef __FPA__IMAGE__DIJKSTRAWITHSPHEREBACKTRACKING__HXX__
2 #define __FPA__IMAGE__DIJKSTRAWITHSPHEREBACKTRACKING__HXX__
5 #include <itkImageRegionConstIteratorWithIndex.h>
6 #include <itkImageRegionIteratorWithIndex.h>
8 // -------------------------------------------------------------------------
9 template< class I, class C >
10 fpa::Image::DijkstraWithSphereBacktracking< I, C >::
11 DijkstraWithSphereBacktracking( )
16 // -------------------------------------------------------------------------
17 template< class I, class C >
18 fpa::Image::DijkstraWithSphereBacktracking< I, C >::
19 ~DijkstraWithSphereBacktracking( )
23 // -------------------------------------------------------------------------
24 template< class I, class C >
25 void fpa::Image::DijkstraWithSphereBacktracking< I, C >::
28 const I* img = this->GetInput( );
29 typename I::SpacingType spac = img->GetSpacing( );
30 double max_spac = spac[ 0 ];
31 for( unsigned int d = 1; d < I::ImageDimension; ++d )
33 ( max_spac < double( spac[ d ] ) )? double( spac[ d ] ): max_spac;
34 max_spac *= double( 3 );
37 for( unsigned int s = 0; s < this->m_Seeds.size( ); ++s )
39 _TNode seed = this->m_Seeds[ s ];
40 _TRegion region = this->_Region( seed.Vertex, max_spac );
41 itk::ImageRegionConstIteratorWithIndex< I > iIt( img, region );
44 _TPixel max_value = iIt.Get( );
45 for( ++iIt; !iIt.IsAtEnd( ); ++iIt )
47 if( iIt.Get( ) > max_value )
49 seed.Vertex = iIt.GetIndex( );
50 seed.Parent = seed.Vertex;
51 max_value = iIt.Get( );
56 this->m_Seeds[ s ] = seed;
61 this->Superclass::_BeforeMainLoop( );
62 this->m_Candidates.clear( );
65 // -------------------------------------------------------------------------
66 template< class I, class C >
67 void fpa::Image::DijkstraWithSphereBacktracking< I, C >::
70 typedef itk::Image< bool, I::ImageDimension > _TMarkImage;
72 // Finish base algorithm
73 this->Superclass::_AfterMainLoop( );
74 this->m_FinalTree.clear( );
75 this->m_EndPoints.clear( );
76 this->m_BifurcationPoints.clear( );
77 if( this->m_Candidates.size( ) == 0 )
79 this->InvokeEvent( TEndEvent( ) );
81 // Get some input values
82 const I* input = this->GetInput( );
83 typename I::SpacingType spac = input->GetSpacing( );
84 double max_spac = spac[ 0 ];
85 for( unsigned int d = 1; d < I::ImageDimension; ++d )
87 ( max_spac < double( spac[ d ] ) )? double( spac[ d ] ): max_spac;
88 max_spac *= double( 3 );
90 // Prepare an object to hold marks
91 typename _TMarkImage::Pointer marks = _TMarkImage::New( );
92 marks->SetLargestPossibleRegion( input->GetLargestPossibleRegion( ) );
93 marks->SetRequestedRegion( input->GetRequestedRegion( ) );
94 marks->SetBufferedRegion( input->GetBufferedRegion( ) );
95 marks->SetOrigin( input->GetOrigin( ) );
96 marks->SetSpacing( input->GetSpacing( ) );
97 marks->SetDirection( input->GetDirection( ) );
99 marks->FillBuffer( false );
101 // Iterate over the candidates, starting from the candidates that
102 // are near thin branches
103 typename _TCandidates::const_reverse_iterator cIt =
104 this->m_Candidates.rbegin( );
105 for( int backId = 0; cIt != this->m_Candidates.rend( ); ++cIt )
107 // If pixel hasn't been visited, continue
108 TVertex v = cIt->second;
109 if( marks->GetPixel( v ) )
112 // Compute nearest start candidate
113 _TRegion region = this->_Region( v, max_spac );
114 itk::ImageRegionConstIteratorWithIndex< I > iIt( input, region );
116 TVertex max_vertex = iIt.GetIndex( );
117 _TPixel max_value = iIt.Get( );
118 for( ++iIt; !iIt.IsAtEnd( ); ++iIt )
120 _TPixel value = iIt.Get( );
121 if( value > max_value )
124 max_vertex = iIt.GetIndex( );
131 if( marks->GetPixel( max_vertex ) )
134 this->m_EndPoints.push_back( max_vertex );
136 // Construct path (at least the part that hasn't been iterated)
137 bool terminate = false;
140 if( this->m_FinalTree.find( max_vertex ) == this->m_FinalTree.end( ) )
142 // Mark a sphere around current point as visited
143 double dist = std::sqrt( double( input->GetPixel( max_vertex ) ) );
144 region = this->_Region( max_vertex, dist * double( 1.25 ) );
145 itk::ImageRegionIteratorWithIndex< _TMarkImage >
146 mIt( marks, region );
147 for( mIt.GoToBegin( ); !mIt.IsAtEnd( ); ++mIt )
150 // Next vertex in current path
151 this->InvokeEvent( TBacktrackingEvent( max_vertex, backId ) );
152 this->m_FinalTree[ max_vertex ] = this->_Parent( max_vertex );
156 // A bifurcation point has been reached!
157 this->m_BifurcationPoints.push_back( max_vertex );
161 max_vertex = this->_Parent( max_vertex );
163 } while( max_vertex != this->_Parent( max_vertex ) && !terminate );
167 this->m_FinalTree[ max_vertex ] = max_vertex;
168 this->InvokeEvent( TEndBacktrackingEvent( backId ) );
175 // -------------------------------------------------------------------------
176 template< class I, class C >
177 bool fpa::Image::DijkstraWithSphereBacktracking< I, C >::
178 _UpdateNeigh( _TNode& nn, const _TNode& n )
180 C nc = this->_Cost( nn.Vertex, n.Vertex );
181 if( TCost( 0 ) < nc )
184 nn.Cost = n.Cost + ( TCost( 1 ) / std::pow( nc, 4 ) );
192 // -------------------------------------------------------------------------
193 template< class I, class C >
194 bool fpa::Image::DijkstraWithSphereBacktracking< I, C >::
195 _UpdateResult( _TNode& n )
197 bool ret = this->Superclass::_UpdateResult( n );
200 TCost nc = this->_Cost( n.Vertex, n.Parent );
201 if( TCost( 0 ) < nc )
203 TCost cc = n.Cost / nc;
204 this->m_Candidates.insert( _TCandidate( cc, n.Vertex ) );
206 this->GetOutput( )->SetPixel( n.Vertex, cc );
214 // -------------------------------------------------------------------------
215 template< class I, class C >
216 typename fpa::Image::DijkstraWithSphereBacktracking< I, C >::
217 _TRegion fpa::Image::DijkstraWithSphereBacktracking< I, C >::
218 _Region( const TVertex& c, const double& r )
220 typename I::ConstPointer input = this->GetInput( );
221 typename I::SpacingType spac = input->GetSpacing( );
222 _TRegion region = input->GetLargestPossibleRegion( );
223 typename I::IndexType idx0 = region.GetIndex( );
224 typename I::IndexType idx1 = idx0 + region.GetSize( );
226 // Compute region size and index
227 typename I::IndexType i0, i1;
229 for( unsigned int d = 0; d < I::ImageDimension; ++d )
231 long s = long( std::ceil( r / double( spac[ d ] ) ) );
232 i0[ d ] = c[ d ] - s;
233 i1[ d ] = c[ d ] + s;
235 if( i0[ d ] < idx0[ d ] ) i0[ d ] = idx0[ d ];
236 if( i1[ d ] < idx0[ d ] ) i1[ d ] = idx0[ d ];
237 if( i0[ d ] > idx1[ d ] ) i0[ d ] = idx1[ d ];
238 if( i1[ d ] > idx1[ d ] ) i1[ d ] = idx1[ d ];
239 size[ d ] = i1[ d ] - i0[ d ];
243 // Prepare region and return it
244 region.SetIndex( i0 );
245 region.SetSize( size );
249 #endif // __FPA__IMAGE__DIJKSTRAWITHSPHEREBACKTRACKING__HXX__