1 #ifndef __fpa__Image__SkeletonFilter__hxx__
2 #define __fpa__Image__SkeletonFilter__hxx__
4 // -------------------------------------------------------------------------
5 #define __fpa__Image__SkeletonFilter__InputMacro( input_name, input_type, input_id ) \
6 template< class _TDistanceMap, class _TCostMap > \
7 typename fpa::Image::SkeletonFilter< _TDistanceMap, _TCostMap >:: \
8 input_type* fpa::Image::SkeletonFilter< _TDistanceMap, _TCostMap >:: \
12 dynamic_cast< input_type* >( \
13 this->Superclass::GetInput( input_id ) \
17 template< class _TDistanceMap, class _TCostMap > \
19 typename fpa::Image::SkeletonFilter< _TDistanceMap, _TCostMap >:: \
21 fpa::Image::SkeletonFilter< _TDistanceMap, _TCostMap >:: \
22 Get##input_name( ) const \
25 dynamic_cast< const input_type* >( \
26 this->Superclass::GetInput( input_id ) \
30 template< class _TDistanceMap, class _TCostMap > \
31 void fpa::Image::SkeletonFilter< _TDistanceMap, _TCostMap >:: \
32 Set##input_name( input_type* input ) \
34 this->Superclass::SetInput( input_id, input ); \
37 __fpa__Image__SkeletonFilter__InputMacro( DistanceMap, TDistanceMap, 0 );
38 __fpa__Image__SkeletonFilter__InputMacro( CostMap, TCostMap, 1 );
39 __fpa__Image__SkeletonFilter__InputMacro( MinimumSpanningTree, TMST, 2 );
41 // -------------------------------------------------------------------------
42 #define __fpa__Image__SkeletonFilter__OutputMacro( output_name, output_type, output_id ) \
43 template< class _TDistanceMap, class _TCostMap > \
44 typename fpa::Image::SkeletonFilter< _TDistanceMap, _TCostMap >:: \
45 output_type* fpa::Image::SkeletonFilter< _TDistanceMap, _TCostMap >:: \
49 dynamic_cast< output_type* >( \
50 this->Superclass::GetOutput( output_id ) \
54 template< class _TDistanceMap, class _TCostMap > \
56 fpa::Image::SkeletonFilter< _TDistanceMap, _TCostMap >:: \
57 output_type* fpa::Image::SkeletonFilter< _TDistanceMap, _TCostMap >:: \
58 Get##output_name( ) const \
61 dynamic_cast< const output_type* >( \
62 this->Superclass::GetOutput( output_id ) \
67 __fpa__Image__SkeletonFilter__OutputMacro( Skeleton, TSkeleton, 0 );
68 __fpa__Image__SkeletonFilter__OutputMacro( EndPoints, TIndices, 1 );
69 __fpa__Image__SkeletonFilter__OutputMacro( Bifurcations, TIndices, 2 );
71 // -------------------------------------------------------------------------
72 template< class _TDistanceMap, class _TCostMap >
73 fpa::Image::SkeletonFilter< _TDistanceMap, _TCostMap >::
77 this->SetNumbeOfRequiredInputs( 3 );
78 this->SetNumbeOfRequiredOutputs( 3 );
80 typename TIndices::Pointer end_points = TIndices::New( );
81 typename TIndices::Pointer bifurcations = TIndices::New( );
82 typename TSkeleton::Pointer skeleton = TSkeleton::New( );
83 this->SetNthOutput( 0, skeleton );
84 this->SetNthOutput( 1, end_points );
85 this->SetNthOutput( 2, bifurcations );
88 // -------------------------------------------------------------------------
89 template< class _TDistanceMap, class _TCostMap >
90 fpa::Image::SkeletonFilter< _TDistanceMap, _TCostMap >::
95 // -------------------------------------------------------------------------
96 template< class _TDistanceMap, class _TCostMap >
97 void fpa::Image::SkeletonFilter< _TDistanceMap, _TCostMap >::
101 const TDistanceMap* dmap = this->GetDistanceMap( );
102 const TCostMap* cmap = this->GetCostMap( );
103 const TMST* mst = this->GetMinimumSpanningTree( );
104 TIndices* end_points = this->GetEndPoints( );
105 TIndices* bifurcations = this->GetBifurcations( );
106 TSkeleton* skeleton = this->GetSkeleton( );
108 // 1. Check input correspondance
111 // 2. Detect end-points
112 this->_EndPoints( dmap, cmap, mst, end_points );
114 // 3. Build skeleton and keep track of bifurcations
115 this->_Skeleton( dmap, cmap, mst, end_points, bifurcations, skeleton );
118 // -------------------------------------------------------------------------
119 template< class _TDistanceMap, class _TCostMap >
120 void fpa::Image::SkeletonFilter< _TDistanceMap, _TCostMap >::
122 const TDistanceMap* dmap,
123 const TCostMap* cmap,
128 typedef itk::ImageRegionConstIteratorWithIndex< _TDistanceMap > _TDistMapIt;
129 typedef itk::ImageRegionConstIteratorWithIndex< _TCostMap > _TCostMapIt;
130 typedef std::multimap< double, TIndex, std::greater< double > > _TQueue;
131 typedef typename _TQueue::value_type _TQueueValue;
132 typedef itk::Image< unsigned char, _TCostMap::ImageDimension > _TMarks;
135 typename _TMarks::Pointer marks = _TMarks::New( );
136 marks->SetLargestPossibleRegion( dmap->GetLargestPossibleRegion( ) );
137 marks->SetRequestedRegion( dmap->GetRequestedRegion( ) );
138 marks->SetBufferedRegion( dmap->GetBufferedRegion( ) );
139 marks->SetSpacing( dmap->GetSpacing( ) );
140 marks->SetOrigin( dmap->GetOrigin( ) );
141 marks->SetDirection( dmap->GetDirection( ) );
143 marks->FillBuffer( 0 );
147 _TDistMapIt dIt( dmap, dmap->GetRequestedRegion( ) );
148 _TCostMapIt cIt( cmap, cmap->GetRequestedRegion( ) );
151 for( ; !dIt.IsAtEnd( ) && !cIt.IsAtEnd( ); ++dIt, ++cIt )
153 double d = double( dIt.Get( ) );
156 double v = double( cIt.Get( ) ) / ( d * d );
157 queue.insert( _TQueueValue( v, dIt.GetIndex( ) ) );
163 // BFS from maximum queue
164 while( queue.size( ) > 0 )
167 auto nIt = queue.begin( );
171 unsigned char m = marks->GetPixel( n.second );
172 if( ( m & 0x01 ) == 0x01 )
175 // Mark it and update end-points
177 marks->SetPixel( n.second, m );
178 end_points->Get( ).insert( n.second );
181 typename TMST::TPath::Pointer path;
182 mst->GetPath( path, n.second );
183 for( unsigned long i = 0; i < path->GetSize( ); ++i )
185 TIndex idx = path->GetVertex( path->GetSize( ) - 1 - i );
186 typename _TCostMap::PointType cnt;
187 cmap->TransformIndexToPhysicalPoint( idx, cnt );
188 double d = double( dmap->GetPixel( idx ) );
192 std::queue< TIndex > q;
194 while( q.size( ) > 0 )
196 TIndex v = q.front( );
198 unsigned char m = marks->GetPixel( v );
199 if( ( m & 0x02 ) == 0x02 )
202 marks->SetPixel( v, m );
204 for( unsigned int x = 0; x < _TCostMap::ImageDimension; ++x )
206 for( int y = -1; y <= 1; y += 2 )
210 if( region.IsInside( w ) )
212 typename _TCostMap::PointType p;
213 cmap->TransformIndexToPhysicalPoint( w, p );
214 if( cnt.EuclideanDistanceTo( p ) <= d )
230 // -------------------------------------------------------------------------
231 template< class _TDistanceMap, class _TCostMap >
232 void fpa::Image::SkeletonFilter< _TDistanceMap, _TCostMap >::
234 const TDistanceMap* dmap,
235 const TCostMap* cmap,
238 TIndices* bifurcations,
244 #endif // __fpa__Image__SkeletonFilter__hxx__