#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include /* #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include */ // ------------------------------------------------------------------------- const unsigned int Dim = 3; typedef unsigned char TPixel; typedef float TScalar; typedef itk::Image< TPixel, Dim > TImage; typedef itk::Image< TScalar, Dim > TScalarImage; typedef itk::ImageToVTKImageFilter< TImage > TVTKInputImage; // ------------------------------------------------------------------------- template< class I > void ReadImage( typename I::Pointer& image, const std::string& filename ); template< class I, class O > void DistanceMap( const typename I::Pointer& input, typename O::Pointer& output ); // ------------------------------------------------------------------------- int main( int argc, char* argv[] ) { if( argc < 2 ) { std::cerr << "Usage: " << argv[ 0 ] << " input_image" << std::endl; return( 1 ); } // fi std::string input_image_fn = argv[ 1 ]; // Read image TImage::Pointer input_image; try { ReadImage< TImage >( input_image, input_image_fn ); } catch( itk::ExceptionObject& err ) { std::cerr << "Error caught while reading \"" << input_image_fn << "\": " << err << std::endl; return( 1 ); } // yrt TVTKInputImage::Pointer vtk_input_image = TVTKInputImage::New( ); vtk_input_image->SetInput( input_image ); vtk_input_image->Update( ); // Show input image and let some interaction fpa::VTK::ImageMPR view; view.SetBackground( 0.3, 0.2, 0.8 ); view.SetSize( 800, 800 ); view.SetImage( vtk_input_image->GetOutput( ) ); // Allow some interaction and wait for, at least, one seed view.Render( ); while( view.GetNumberOfSeeds( ) == 0 ) view.Start( ); // Get seed double p[ 3 ]; view.GetSeed( 0, p ); TImage::PointType pnt; TImage::IndexType seed; pnt[ 0 ] = TImage::PointType::ValueType( p[ 0 ] ); pnt[ 1 ] = TImage::PointType::ValueType( p[ 1 ] ); pnt[ 2 ] = TImage::PointType::ValueType( p[ 2 ] ); input_image->TransformPhysicalPointToIndex( pnt, seed ); // Compute squared distance map TScalarImage::Pointer dmap; DistanceMap< TImage, TScalarImage >( input_image, dmap ); // Prepare cost conversion function typedef fpa::Base::Functors::InvertCostFunction< TScalar > TFunction; TFunction::Pointer function = TFunction::New( ); // Prepare Dijkstra filter typedef fpa::Image::DijkstraWithEndPointDetection< TScalarImage, TScalarImage > TFilter; TFilter::Pointer filter = TFilter::New( ); filter->SetInput( dmap ); filter->SetConversionFunction( function ); filter->SetNeighborhoodOrder( 2 ); filter->StopAtOneFrontOff( ); filter->AddSeed( seed, TScalar( 0 ) ); // Prepare graphical debugger typedef fpa::VTK::Image3DObserver< TFilter, vtkRenderWindow > TDebugger; TDebugger::Pointer debugger = TDebugger::New( ); debugger->SetRenderWindow( view.GetWindow( ) ); debugger->SetRenderPercentage( 0.0001 ); filter->AddObserver( itk::AnyEvent( ), debugger ); filter->ThrowEventsOn( ); // Go! std::time_t start, end; std::time( &start ); filter->Update( ); std::time( &end ); std::cout << "Extraction time = " << std::difftime( end, start ) << " s." << std::endl; /* TODO // Save final total cost map itk::ImageFileWriter< TOutputImage >::Pointer output_image_writer = itk::ImageFileWriter< TOutputImage >::New( ); output_image_writer->SetFileName( output_image_fn ); output_image_writer->SetInput( filter->GetOutput( ) ); try { output_image_writer->Update( ); } catch( itk::ExceptionObject& err ) { std::cerr << "Error while writing image to " << output_image_fn << ": " << err << std::endl; return( 1 ); } // yrt */ return( 0 ); } // ------------------------------------------------------------------------- template< class I > void ReadImage( typename I::Pointer& image, const std::string& filename ) { typename itk::ImageFileReader< I >::Pointer reader = itk::ImageFileReader< I >::New( ); reader->SetFileName( filename ); reader->Update( ); typename itk::MinimumMaximumImageCalculator< I >::Pointer minmax = itk::MinimumMaximumImageCalculator< I >::New( ); minmax->SetImage( reader->GetOutput( ) ); minmax->Compute( ); double vmin = double( minmax->GetMinimum( ) ); double vmax = double( minmax->GetMaximum( ) ); typename itk::ShiftScaleImageFilter< I, I >::Pointer shift = itk::ShiftScaleImageFilter< I, I >::New( ); shift->SetInput( reader->GetOutput( ) ); shift->SetScale( vmax - vmin ); shift->SetShift( vmin / ( vmax - vmin ) ); shift->Update( ); image = shift->GetOutput( ); image->DisconnectPipeline( ); } // ------------------------------------------------------------------------- template< class I, class O > void DistanceMap( const typename I::Pointer& input, typename O::Pointer& output ) { typename itk::SignedMaurerDistanceMapImageFilter< I, O >::Pointer dmap = itk::SignedMaurerDistanceMapImageFilter< I, O >::New( ); dmap->SetInput( input ); dmap->SetBackgroundValue( ( typename I::PixelType )( 0 ) ); dmap->InsideIsPositiveOn( ); dmap->SquaredDistanceOn( ); dmap->UseImageSpacingOn( ); std::time_t start, end; std::time( &start ); dmap->Update( ); std::time( &end ); std::cout << "Distance map time = " << std::difftime( end, start ) << " s." << std::endl; output = dmap->GetOutput( ); output->DisconnectPipeline( ); } // eof - $RCSfile$