8 #include <itkImageToVTKImageFilter.h>
10 #include <itkImageFileReader.h>
11 #include <itkImageFileWriter.h>
13 #include <fpa/VTK/ImageMPR.h>
14 #include <fpa/Image/IncrementalRegionGrow.h>
15 #include <fpa/Image/Functors/RegionGrowThresholdFunction.h>
18 #include <vtkCamera.h>
19 #include <vtkImageActor.h>
20 #include <vtkInteractorStyleImage.h>
21 #include <vtkPointHandleRepresentation3D.h>
22 #include <vtkProperty.h>
23 #include <vtkRenderer.h>
24 #include <vtkRenderWindow.h>
25 #include <vtkRenderWindowInteractor.h>
26 #include <vtkSeedRepresentation.h>
27 #include <vtkSeedWidget.h>
28 #include <vtkSmartPointer.h>
30 #include <fpa/Image/Functors/ImageAbsoluteDifferenceCostFunction.h>
31 #include <fpa/VTK/Image3DObserver.h>
34 // -------------------------------------------------------------------------
35 const unsigned int Dim = 3;
36 typedef short TInputPixel;
37 typedef short TOutputPixel;
39 typedef itk::Image< TInputPixel, Dim > TInputImage;
40 typedef itk::Image< TOutputPixel, Dim > TOutputImage;
41 typedef itk::ImageToVTKImageFilter< TInputImage > TVTKInputImage;
43 // -------------------------------------------------------------------------
44 int main( int argc, char* argv[] )
49 << "Usage: " << argv[ 0 ] << std::endl
50 << "\tinput_image" << std::endl
51 << "\toutput_image" << std::endl
52 << "\tneighborhood_order" << std::endl
53 << "\tstop_at_one_front" << std::endl
54 << "\tinit_threshold" << std::endl
55 << "\tend_threshold" << std::endl
56 << "\tsamples" << std::endl
57 << "\t[input_seeds]" << std::endl;
61 std::string input_image_fn = argv[ 1 ];
62 std::string output_image_fn = argv[ 2 ];
63 unsigned int neighborhood_order = std::atoi( argv[ 3 ] );
64 bool stop_at_one_front = ( std::atoi( argv[ 4 ] ) != 0 );
65 TInputPixel init_threshold = TInputPixel( std::atof( argv[ 5 ] ) );
66 TInputPixel end_threshold = TInputPixel( std::atof( argv[ 6 ] ) );
67 unsigned int samples = TInputPixel( std::atof( argv[ 7 ] ) );
68 std::string input_seeds_fn = ( argc >= 9 )? argv[ 8 ]: "";
71 itk::ImageFileReader< TInputImage >::Pointer input_image_reader =
72 itk::ImageFileReader< TInputImage >::New( );
73 input_image_reader->SetFileName( input_image_fn );
76 input_image_reader->Update( );
78 catch( itk::ExceptionObject& err )
81 << "Error while reading image from " << input_image_fn << ": "
86 TInputImage::ConstPointer input_image = input_image_reader->GetOutput( );
87 TVTKInputImage::Pointer vtk_input_image = TVTKInputImage::New( );
88 vtk_input_image->SetInput( input_image );
89 vtk_input_image->Update( );
91 // Show input image and let some interaction
92 fpa::VTK::ImageMPR view;
93 view.SetBackground( 0.3, 0.2, 0.8 );
94 view.SetSize( 600, 600 );
95 view.SetImage( vtk_input_image->GetOutput( ) );
99 std::vector< TInputImage::IndexType > input_seeds;
100 if( input_seeds_fn != "" )
102 std::ifstream input_seeds_str( input_seeds_fn.c_str( ) );
103 if( input_seeds_str )
106 input_seeds_str >> nSeeds;
107 for( unsigned int i = 0; i < nSeeds; ++i )
109 TInputImage::PointType pnt;
110 input_seeds_str >> pnt[ 0 ] >> pnt[ 1 ] >> pnt[ 2 ];
112 TInputImage::IndexType idx;
113 input_image_reader->GetOutput( )->
114 TransformPhysicalPointToIndex( pnt, idx );
115 input_seeds.push_back( idx );
117 view.AddSeed( pnt[ 0 ], pnt[ 1 ], pnt[ 2 ] );
120 input_seeds_str.close( );
123 std::cerr << "Error reading \"" << input_seeds_fn << "\"" << std::endl;
127 // Allow some interaction
129 if( input_seeds.size( ) == 0 )
131 while( view.GetNumberOfSeeds( ) == 0 )
134 for( unsigned int i = 0; i < view.GetNumberOfSeeds( ); ++i )
137 view.GetSeed( i, p );
139 TInputImage::PointType pnt;
144 TInputImage::IndexType idx;
145 input_image_reader->GetOutput( )->
146 TransformPhysicalPointToIndex( pnt, idx );
147 input_seeds.push_back( idx );
154 // Prepare region grow filter and cost function
156 IncrementalRegionGrow< TInputImage, TOutputImage > TFilter;
157 typedef fpa::Image::Functors::
158 RegionGrowThresholdFunction< TInputImage > TFunction;
160 TFilter::Pointer filter = TFilter::New( );
161 filter->SetInput( input_image_reader->GetOutput( ) );
164 typedef fpa::Image::Dijkstra< TInputImage, TOutputImage > TFilter;
165 typedef fpa::Image::Functors::
166 ImageAbsoluteDifferenceCostFunction< TFilter::TInputImage, TFilter::TResult >
169 TCost::Pointer cost = TCost::New( );
171 TFilter::Pointer filter = TFilter::New( );
172 filter->SetInput( input_image );
173 filter->SetCostFunction( cost );
174 filter->SetConversionFunction( NULL );
175 filter->SetNeighborhoodOrder( neighborhood_order );
176 filter->SetStopAtOneFront( stop_at_one_front );
178 // Get user-given seeds
179 std::ifstream input_seeds_str( input_seeds_fn.c_str( ) );
180 if( !input_seeds_str )
182 std::cerr << "Error opening \"" << input_seeds_fn << "\"" << std::endl;
188 input_seeds_str >> nSeeds;
189 std::vector< TInputImage::IndexType > input_seeds;
190 for( unsigned int s = 0; s < nSeeds; s++ )
192 TInputImage::IndexType idx;
193 input_seeds_str >> idx[ 0 ] >> idx[ 1 ] >> idx[ 2 ];
194 input_seeds.push_back( idx );
197 input_seeds_str.close( );
199 filter->AddSeed( input_seeds[ init_seed ], 0 );
200 filter->AddSeed( input_seeds[ end_seed ], 0 );
202 // Prepare graphical debugger
203 typedef fpa::VTK::Image3DObserver< TFilter, vtkRenderWindow > TDebugger;
204 TDebugger::Pointer debugger = TDebugger::New( );
205 debugger->SetRenderWindow( view.GetWindow( ) );
206 debugger->SetRenderPercentage( 0.0001 );
207 filter->AddObserver( itk::AnyEvent( ), debugger );
208 filter->ThrowEventsOn( );
213 // Save final total cost map
214 itk::ImageFileWriter< TOutputImage >::Pointer output_image_writer =
215 itk::ImageFileWriter< TOutputImage >::New( );
216 output_image_writer->SetFileName( output_image_fn );
217 output_image_writer->SetInput( filter->GetOutput( ) );
220 output_image_writer->Update( );
222 catch( itk::ExceptionObject& err )
225 << "Error while writing image to " << output_image_fn << ": "