]> Creatis software - FrontAlgorithms.git/blob - lib/fpa/Common/SliceBySliceRandomWalker.hxx
...
[FrontAlgorithms.git] / lib / fpa / Common / SliceBySliceRandomWalker.hxx
1 // =========================================================================
2 // @author Leonardo Florez Valencia
3 // @email florez-l@javeriana.edu.co
4 // =========================================================================
5 #ifndef __fpa__Common__SliceBySliceRandomWalker__hxx__
6 #define __fpa__Common__SliceBySliceRandomWalker__hxx__
7
8 #include <vector>
9 #include <itkExtractImageFilter.h>
10 #include <itkImageRegionConstIterator.h>
11 #include <itkImageRegionIterator.h>
12 #include <itkJoinSeriesImageFilter.h>
13 #include <itkMaximumImageFilter.h>
14 #include <itkMinimumMaximumImageCalculator.h>
15 #include <fpa/Common/RandomWalker.h>
16 #include <fpa/Functors/Dijkstra/Image/Gaussian.h>
17
18 // -------------------------------------------------------------------------
19 template< class _TImage, class _TLabels, class _TScalarImage >
20 fpa::Common::SliceBySliceRandomWalker< _TImage, _TLabels, _TScalarImage >::
21 SliceBySliceRandomWalker( )
22   : Superclass( ),
23     m_Epsilon( TScalar( 1e-5 ) ),
24     m_Beta( TScalar( 1 ) ),
25     m_VesselnessThreshold( TScalar( 5 ) )
26 {
27   ivqITKInputConfigureMacro( InputLabels, TLabels );
28   ivqITKInputConfigureMacro( InputVesselness, TScalarImage );
29 }
30
31 // -------------------------------------------------------------------------
32 template< class _TImage, class _TLabels, class _TScalarImage >
33 fpa::Common::SliceBySliceRandomWalker< _TImage, _TLabels, _TScalarImage >::
34 ~SliceBySliceRandomWalker( )
35 {
36 }
37
38 // -------------------------------------------------------------------------
39 template< class _TImage, class _TLabels, class _TScalarImage >
40 void
41 fpa::Common::SliceBySliceRandomWalker< _TImage, _TLabels, _TScalarImage >::
42 GenerateData( )
43 {
44   typedef itk::Image< TPixel, TImage::ImageDimension - 1 > _TSliceImage;
45   typedef itk::Image< TLabel, TImage::ImageDimension - 1 > _TSliceLabels;
46   typedef itk::Image< TScalar, TImage::ImageDimension - 1 > _TSliceScalarImage;
47
48   // Preare I/O objects
49   const TImage* input = this->GetInput( );
50   const TLabels* labels = this->GetInputLabels( );
51   const TScalarImage* vesselness = this->GetInputVesselness( );
52   this->AllocateOutputs( );
53
54   // Get vesselness range
55   typedef itk::MinimumMaximumImageCalculator< TScalarImage > _TMinMax;
56   typename _TMinMax::Pointer vMinMax = _TMinMax::New( );
57   vMinMax->SetImage( vesselness );
58   vMinMax->Compute( );
59   TScalar vMax = vMinMax->GetMaximum( );
60
61   // Some values
62   typename TImage::RegionType region = input->GetRequestedRegion( );
63   typename TImage::IndexType regionIndex = region.GetIndex( );
64   typename TImage::SizeType sliceSize = region.GetSize( );
65   int numSlices = sliceSize[ 2 ];
66   sliceSize[ 2 ] = 0;
67   this->m_VesselnessValue  = TScalar( 0.01 );
68   this->m_VesselnessValue *= this->m_VesselnessThreshold * vMax;
69
70   // Composite image
71   typename TScalarImage::Pointer composite;
72   this->_Composite( composite, labels, vesselness, vMax );
73
74   // Extract slices
75   std::vector< typename _TSliceImage::Pointer > data3D( numSlices );
76   std::vector< typename _TSliceLabels::Pointer > binaryTree( numSlices );
77   std::vector< typename _TSliceScalarImage::Pointer > fusion( numSlices );
78   for( int i = 0; i < numSlices; ++i )
79   {
80     // Prepare extraction region
81     typename TImage::IndexType sliceIndex = regionIndex;
82     sliceIndex[ 2 ] += i;
83     typename TImage::RegionType sliceRegion( sliceIndex, sliceSize );
84
85     // Extract regions
86     typename _TSliceImage::Pointer input_slice;
87     typename _TSliceLabels::Pointer labels_slice;
88     typename _TSliceScalarImage::Pointer composite_slice;
89     this->_Slice( input_slice, input, sliceRegion );
90     this->_Slice( labels_slice, labels, sliceRegion );
91     this->_Slice( composite_slice, composite.GetPointer( ), sliceRegion );
92
93     // Update vectors with each image
94     data3D[ i ] = input_slice;
95     binaryTree[ i ] = labels_slice;
96     fusion[ i ] = composite_slice;
97
98   } // rof
99
100   // Random walker slice-by-slice
101   this->_RandomWalker( binaryTree, data3D, fusion, true );
102   this->_RandomWalker( binaryTree, data3D, fusion, false );
103
104   // Join results
105   typedef itk::JoinSeriesImageFilter< _TSliceLabels, TLabels > _TJoin;
106   typename _TJoin::Pointer join = _TJoin::New( );
107   for( int i = 0; i < numSlices; ++i )
108     join->SetInput( i, binaryTree[ i ] );
109   join->Update( );
110   this->GetOutput( )->Graft( join->GetOutput( ) );
111 }
112
113 // -------------------------------------------------------------------------
114 template< class _TImage, class _TLabels, class _TScalarImage >
115 void
116 fpa::Common::SliceBySliceRandomWalker< _TImage, _TLabels, _TScalarImage >::
117 _Composite(
118   typename TScalarImage::Pointer& composite,
119   const TLabels* labels,
120   const TScalarImage* vesselness,
121   const TScalar& maxVess
122   )
123 {
124   // Some values
125   typename TScalarImage::RegionType region = labels->GetRequestedRegion( );
126
127   // Composite image
128   composite = TScalarImage::New( );
129   composite->CopyInformation( vesselness );
130   composite->SetBufferedRegion( vesselness->GetBufferedRegion( ) );
131   composite->Allocate( );
132   itk::ImageRegionConstIterator< TScalarImage > v( vesselness, region );
133   itk::ImageRegionConstIterator< TLabels > l( labels, region );
134   itk::ImageRegionIterator< TScalarImage > c( composite, region );
135   v.GoToBegin( );
136   l.GoToBegin( );
137   c.GoToBegin( );
138   for( ; !v.IsAtEnd( ); ++v, ++l, ++c )
139     c.Set( ( l.Get( ) != 0 )? maxVess: v.Get( ) );
140 }
141
142 // -------------------------------------------------------------------------
143 template< class _TImage, class _TLabels, class _TScalarImage >
144 template< class _TSlicePtr, class _TInput >
145 void
146 fpa::Common::SliceBySliceRandomWalker< _TImage, _TLabels, _TScalarImage >::
147 _Slice(
148   _TSlicePtr& slice,
149   const _TInput* input,
150   typename _TInput::RegionType region
151   )
152 {
153   typedef typename _TSlicePtr::ObjectType _TSlice;
154   typedef itk::ExtractImageFilter< _TInput, _TSlice > _TExtract;
155
156   typename _TExtract::Pointer extract = _TExtract::New( );
157   extract->SetInput( input );
158   extract->SetExtractionRegion( region );
159   extract->SetDirectionCollapseToIdentity( );
160   extract->Update( );
161   slice = extract->GetOutput( );
162   slice->DisconnectPipeline( );
163 }
164
165 // -------------------------------------------------------------------------
166 template< class _TImage, class _TLabels, class _TScalarImage >
167 template< class _TBinaryTree, class _TData3D, class _TFusion >
168 void
169 fpa::Common::SliceBySliceRandomWalker< _TImage, _TLabels, _TScalarImage >::
170 _RandomWalker(
171   _TBinaryTree& binaryTree,
172   const _TData3D& data3D,
173   const _TFusion& fusion,
174   bool down
175   )
176 {
177   typedef typename _TBinaryTree::value_type     _TSliceBinaryPtr;
178   typedef typename _TData3D::value_type         _TSliceData3DPtr;
179   typedef typename _TFusion::value_type         _TSliceFusionPtr;
180   typedef typename _TSliceBinaryPtr::ObjectType _TSliceBinary;
181   typedef typename _TSliceData3DPtr::ObjectType _TSliceData3D;
182   typedef typename _TSliceFusionPtr::ObjectType _TSliceFusion;
183   typedef typename _TSliceFusion::PixelType     _TSliceScalar;
184
185   int numSlices = binaryTree.size( );
186   int z = ( down )? -1: numSlices;
187   int o = ( down )? 1: -1;
188   while( ( down && z < numSlices - 2 ) || ( !down && z > 1 ) )
189   {
190     z += o;
191     _TSliceBinaryPtr tmp = binaryTree[ z ];
192     _TSliceBinaryPtr next = binaryTree[ z + o ];
193     _TSliceData3DPtr data = data3D[ z + o ];
194     _TSliceFusionPtr vess = fusion[ z + o ];
195     typename _TSliceBinary::RegionType region = tmp->GetRequestedRegion( );
196
197     // Create seeds and background
198     _TSliceBinaryPtr seeds = _TSliceBinary::New( );
199     seeds->CopyInformation( tmp );
200     seeds->SetRequestedRegion( region );
201     seeds->Allocate( );
202     seeds->FillBuffer( 0 );
203
204     itk::ImageRegionConstIterator< _TSliceBinary > tIt( tmp, region );
205     itk::ImageRegionConstIterator< _TSliceFusion > vIt( vess, region );
206     itk::ImageRegionIterator< _TSliceBinary > sIt( seeds, region );
207     tIt.GoToBegin( );
208     vIt.GoToBegin( );
209     sIt.GoToBegin( );
210     int len = 0;
211     int numO = 0;
212     int numB = 0;
213     for( ; !tIt.IsAtEnd( ); ++tIt, ++vIt, ++sIt )
214     {
215       if( tIt.Get( ) != 0 )
216       {
217         len++;
218         if( vIt.Get( ) > this->m_VesselnessValue )
219         {
220           sIt.Set( 1 );
221           numO++;
222
223         } // fi
224
225       } // fi
226
227       if( vIt.Get( ) < this->m_VesselnessValue )
228       {
229         sIt.Set( 2 );
230         numB++;
231
232       } // fi
233
234     } // rof
235
236     if( len == 0 )
237       continue;
238
239     // Random walker function
240     typedef fpa::Functors::Dijkstra::Image::Gaussian< _TSliceData3D, _TSliceScalar > _TFunction;
241     typename _TFunction::Pointer edge = _TFunction::New( );
242     edge->SetBeta( this->m_Beta );
243     edge->SetEpsilon( this->m_Epsilon );
244     edge->TreatAsWeightOff( );
245
246     // Real random walker
247     typedef fpa::Common::RandomWalker< _TSliceData3D, _TSliceBinary, _TSliceScalar > _TRandomWalker;
248     typename _TRandomWalker::Pointer rw = _TRandomWalker::New( );
249     rw->SetInput( data );
250     rw->SetInputLabels( seeds );
251     rw->SetEdgeFunction( edge );
252
253     // Keep maximum
254     typedef itk::MaximumImageFilter< _TSliceBinary > _TMax;
255     typename _TMax::Pointer max = _TMax::New();
256     max->SetInput( 0, rw->GetOutput( ) );
257     max->SetInput( 1, next );
258     max->Update( );
259     binaryTree[ z + o ] = max->GetOutput( );
260     binaryTree[ z + o ]->DisconnectPipeline( );
261
262   } // elihw
263 }
264
265 #endif // __fpa__Common__SliceBySliceRandomWalker__hxx__
266 // eof - $RCSfile$