10 #include <itkConstNeighborhoodIterator.h>
11 #include <itkNeighborhoodIterator.h>
12 #include <itkDanielssonDistanceMapImageFilter.h>
14 #include <itkImageFileReader.h>
15 #include <itkImageFileWriter.h>
16 #include <itkImageToVTKImageFilter.h>
18 #include <itkMinimumMaximumImageCalculator.h>
19 #include <itkInvertIntensityImageFilter.h>
21 #include <vtkPoints.h>
22 #include <vtkCellArray.h>
23 #include <vtkFloatArray.h>
24 #include <vtkPolyData.h>
25 #include <vtkPolyDataWriter.h>
26 #include <vtkSmartPointer.h>
27 #include <vtkImageMarchingCubes.h>
28 #include <vtkLookupTable.h>
30 #include <fpa/Image/DijkstraWithSphereBacktracking.h>
31 #include <fpa/VTK/ImageMPR.h>
32 #include <fpa/VTK/Image3DObserver.h>
34 // -------------------------------------------------------------------------
35 const unsigned int Dim = 3;
37 typedef float TScalar;
38 typedef itk::Image< TPixel, Dim > TImage;
39 typedef itk::ImageToVTKImageFilter< TImage > TVTKImage;
41 typedef itk::ImageFileReader< TImage > TImageReader;
42 typedef itk::ImageFileWriter< TImage > TImageWriter;
43 typedef fpa::Image::DijkstraWithSphereBacktracking< TImage, TScalar > TDijkstra;
45 typedef fpa::VTK::ImageMPR TMPR;
46 typedef fpa::VTK::Image3DObserver< TDijkstra, vtkRenderWindow > TDijkstraObs;
54 bool operator<( const TBranch& other ) const
56 return( other.Length < this->Length );
59 typedef std::set< TBranch > TBranches;
61 // -------------------------------------------------------------------------
62 int main( int argc, char* argv[] )
67 << "Usage: " << argv[ 0 ]
68 << " input_image x y z output_image"
74 std::string input_image_fn = argv[ 1 ];
75 TImage::PointType seed_pnt;
76 seed_pnt[ 0 ] = std::atof( argv[ 2 ] );
77 seed_pnt[ 1 ] = std::atof( argv[ 3 ] );
78 seed_pnt[ 2 ] = std::atof( argv[ 4 ] );
79 std::string output_image_fn = argv[ 5 ];
80 bool visual_debug = false;
82 visual_debug = ( std::atoi( argv[ 6 ] ) == 1 );
85 TImageReader::Pointer input_image_reader = TImageReader::New( );
86 input_image_reader->SetFileName( input_image_fn );
89 input_image_reader->Update( );
91 catch( itk::ExceptionObject& err )
93 std::cerr << "Error caught: " << err << std::endl;
97 TImage::ConstPointer input_image = input_image_reader->GetOutput( );
100 TVTKImage::Pointer vtk_image = TVTKImage::New( );
101 vtk_image->SetInput( input_image );
102 vtk_image->Update( );
105 view.SetBackground( 0.3, 0.2, 0.8 );
106 view.SetSize( 800, 800 );
107 view.SetImage( vtk_image->GetOutput( ) );
110 vtkSmartPointer< vtkImageMarchingCubes > mc =
111 vtkSmartPointer< vtkImageMarchingCubes >::New( );
112 mc->SetInputData( vtk_image->GetOutput( ) );
113 mc->SetValue( 0, 1e-2 );
115 view.AddPolyData( mc->GetOutput( ), 1, 1, 1, 0.4 );
118 // Allow some interaction
122 TImage::IndexType seed_idx;
123 input_image->TransformPhysicalPointToIndex( seed_pnt, seed_idx );
124 std::cout << seed_idx << " " << seed_pnt << std::endl;
130 TDijkstra::Pointer paths = TDijkstra::New( );
131 paths->AddSeed( seed_idx, TScalar( 0 ) );
132 paths->SetInput( input_image );
133 paths->SetNeighborhoodOrder( 2 );
137 // Configure observer
138 TDijkstraObs::Pointer obs = TDijkstraObs::New( );
139 obs->SetRenderWindow( view.GetWindow( ) );
140 paths->AddObserver( itk::AnyEvent( ), obs );
141 paths->ThrowEventsOn( );
144 paths->ThrowEventsOff( );
145 std::clock_t start = std::clock( );
147 std::clock_t end = std::clock( );
148 double seconds = double( end - start ) / double( CLOCKS_PER_SEC );
149 std::cout << "Paths extraction time = " << seconds << std::endl;
152 vtkSmartPointer< vtkPoints > points =
153 vtkSmartPointer< vtkPoints >::New( );
154 vtkSmartPointer< vtkCellArray > cells =
155 vtkSmartPointer< vtkCellArray >::New( );
156 vtkSmartPointer< vtkFloatArray > scalars =
157 vtkSmartPointer< vtkFloatArray >::New( );
159 const TDijkstra::TMarkImage* marks = paths->GetOutputMarkImage( );
160 TDijkstra::TMark max_mark = paths->GetNumberOfBranches( );
161 const TDijkstra::TVertices& endpoints = paths->GetEndPoints( );
162 const TDijkstra::TVertices& bifurcations = paths->GetBifurcationPoints( );
163 const TDijkstra::TTree& tree = paths->GetFinalTree( );
164 TDijkstra::TVertices::const_iterator epIt = endpoints.begin( );
166 TDijkstra::TMarkImage::Pointer new_marks = TDijkstra::TMarkImage::New( );
167 new_marks->SetLargestPossibleRegion( marks->GetLargestPossibleRegion( ) );
168 new_marks->SetRequestedRegion( marks->GetRequestedRegion( ) );
169 new_marks->SetBufferedRegion( marks->GetBufferedRegion( ) );
170 new_marks->SetOrigin( marks->GetOrigin( ) );
171 new_marks->SetSpacing( marks->GetSpacing( ) );
172 new_marks->SetDirection( marks->GetDirection( ) );
173 new_marks->Allocate( );
174 new_marks->FillBuffer( 0 );
176 std::cout << max_mark << std::endl;
177 std::cout << endpoints.size( ) << std::endl;
181 for( ; epIt != endpoints.end( ); ++epIt )
183 TDijkstra::TVertex idx = *epIt;
184 TDijkstra::TTree::const_iterator tIt = tree.find( idx );
185 TImage::PointType pnt, prev;
186 input_image->TransformIndexToPhysicalPoint( idx, pnt );
189 input_image->TransformIndexToPhysicalPoint( idx, pnt );
192 points->InsertNextPoint( pnt[ 0 ], pnt[ 1 ], pnt[ 2 ] );
193 scalars->InsertNextTuple1( double( tIt->second.second ) );
194 new_marks->SetPixel( idx, tIt->second.second );
198 cells->InsertNextCell( 2 );
199 cells->InsertCellPoint( points->GetNumberOfPoints( ) - 2 );
200 cells->InsertCellPoint( points->GetNumberOfPoints( ) - 1 );
201 branch.Length += prev.EuclideanDistanceTo( pnt );
205 idx = tIt->second.first;
207 if( std::find( bifurcations.begin( ), bifurcations.end( ), idx ) != bifurcations.end( ) )
209 branches.insert( branch );
212 branch.Length = double( 0 );
215 tIt = tree.find( idx );
217 } while( idx != tIt->second.first );
224 TImage::PointType ori = input_image->GetOrigin( );
225 std::cout << ori << std::endl;
226 for( TBranches::const_iterator bIt = branches.begin( ); bIt != branches.end( ); ++bIt, ++i )
228 TImage::PointType::VectorType v1 = bIt->V1 - ori;
229 TImage::PointType::VectorType v2 = bIt->V2 - ori;
231 << std::setiosflags( std::ios::fixed) << std::setprecision( 3 )
233 << bIt->Length << "\t"
240 << ( v2 - v1 ).GetNorm( )
246 vtkSmartPointer< vtkPolyData > vtk_tree =
247 vtkSmartPointer< vtkPolyData >::New( );
248 vtk_tree->SetPoints( points );
249 vtk_tree->SetLines( cells );
250 vtk_tree->GetPointData( )->SetScalars( scalars );
252 view.AddPolyData( vtk_tree );
256 vtkSmartPointer< vtkPolyDataWriter > writer =
257 vtkSmartPointer< vtkPolyDataWriter >::New( );
258 writer->SetInputData( vtk_tree );
259 writer->SetFileName( output_image_fn.c_str( ) );
262 itk::ImageFileWriter< TDijkstra::TMarkImage >::Pointer marks_writer =
263 itk::ImageFileWriter< TDijkstra::TMarkImage >::New( );
264 marks_writer->SetInput( new_marks );
265 marks_writer->SetFileName( "marks.mhd" );
266 marks_writer->Update( );
269 TImageWriter::Pointer dijkstra_writer =
270 TImageWriter::New( );
271 dijkstra_writer->SetInput( paths->GetOutput( ) );
272 dijkstra_writer->SetFileName( "dijkstra.mhd" );
273 dijkstra_writer->Update( );