From: Leonardo Florez-Valencia Date: Fri, 5 Jun 2015 00:10:06 +0000 (-0500) Subject: CMake updated. Some other filters added. X-Git-Url: https://git.creatis.insa-lyon.fr/pubgit/?a=commitdiff_plain;h=015105c2f44abb80923a59adfb1a01713506744f;p=FrontAlgorithms.git CMake updated. Some other filters added. --- diff --git a/CMakeLists.txt b/CMakeLists.txt index 5182771..2ada831 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,20 +1,8 @@ -CMAKE_MINIMUM_REQUIRED(VERSION 2.6) - -# for CMake 2.6 corrected behaviour (see "cmake --help-policy CMP0003") -IF( - COMMAND cmake_policy AND - ${CMAKE_MAJOR_VERSION} EQUAL 2 AND - ${CMAKE_MINOR_VERSION} GREATER 4 - ) - CMAKE_POLICY(SET CMP0003 NEW) - CMAKE_POLICY(SET CMP0005 NEW) - CMAKE_POLICY(SET CMP0011 NEW) - CMAKE_POLICY(SET CMP0012 NEW) -ENDIF( - COMMAND cmake_policy AND - ${CMAKE_MAJOR_VERSION} EQUAL 2 AND - ${CMAKE_MINOR_VERSION} GREATER 4 - ) +CMAKE_MINIMUM_REQUIRED(VERSION 2.8) + +IF(POLICY CMP0020) + CMAKE_POLICY(SET CMP0020 NEW) +ENDIF(POLICY CMP0020) ## ================ ## = Project name = @@ -45,38 +33,15 @@ ENDIF(BUILD_SHARED_LIBS) INCLUDE(GenerateExportHeader) -## ------------------------------------------------------------------------- -## If compiling on UNIX-like OS, an error could arise when using ITKVtkGlue: -## -## :0:0: warning: "vtkRenderingCore_AUTOINIT" redefined -## :0:0: note: this is the location of the previous definition -## -## This is avoided by not including the VTK_USE_FILE. Nevertheless, this fails -## on MS-Win OS. -## -## This is due to object factories. To avoid this, and let the project be -## usable on UNIX-like and MS-Win, the way to find ITK and VTK differs -## ------------------------------------------------------------------------- - -IF(UNIX) - FIND_PACKAGE(ITK REQUIRED) - FIND_PACKAGE(VTK REQUIRED) - INCLUDE(${ITK_USE_FILE}) - IF(NOT ITKVtkGlue_LOADED) - MESSAGE(FATAL_ERROR "ITKVtkGlue module is required but not available.") - ENDIF(NOT ITKVtkGlue_LOADED) -ELSE(UNIX) - FIND_PACKAGE(ITK REQUIRED) - INCLUDE(${ITK_USE_FILE}) - IF(ITKVtkGlue_LOADED) - FIND_PACKAGE(VTK REQUIRED) - INCLUDE(${VTK_USE_FILE}) - ELSE(ITKVtkGlue_LOADED) - FIND_PACKAGE(ItkVtkGlue REQUIRED) - INCLUDE(${ItkVtkGlue_USE_FILE}) - SET(Glue ItkVtkGlue) - ENDIF(ITKVtkGlue_LOADED) -ENDIF(UNIX) +FIND_PACKAGE(ITK REQUIRED) +INCLUDE(${ITK_USE_FILE}) + +FIND_PACKAGE(VTK REQUIRED) +INCLUDE(${VTK_USE_FILE}) + +IF(ITKVtkGlue_LOADED) + MESSAGE(FATAL_ERROR "ITKVtkGlue module is available. Please re-compile your ITK without it. It could lead to nasty compilation problems... Just waiting for Kitware to solve it.") +ENDIF(ITKVtkGlue_LOADED) OPTION(USE_cpPlugins "Build cpPlugins based stuff" OFF) IF(USE_cpPlugins) diff --git a/appli/examples/CMakeLists.txt b/appli/examples/CMakeLists.txt index 122dcee..6b3f71c 100644 --- a/appli/examples/CMakeLists.txt +++ b/appli/examples/CMakeLists.txt @@ -1,25 +1,30 @@ -SET( - SIMPLE_EXAMPLES - example_Image_Dijkstra_EndPointDetection_WithoutVTK - ) -FOREACH(EX ${SIMPLE_EXAMPLES}) - ADD_EXECUTABLE(${EX} ${EX}.cxx) - TARGET_LINK_LIBRARIES(${EX} FrontAlgorithms) -ENDFOREACH(EX) +#SET( +# SIMPLE_EXAMPLES +# example_Image_Dijkstra_EndPointDetection_WithoutVTK +# ) +#FOREACH(EX ${SIMPLE_EXAMPLES}) +# ADD_EXECUTABLE(${EX} ${EX}.cxx) +# TARGET_LINK_LIBRARIES(${EX} FrontAlgorithms) +#ENDFOREACH(EX) SET( SIMPLE_VTK_EXAMPLES example_Image_RegionGrow_AllPixels example_Image_RegionGrow_AllRGBPixels - example_Image_RegionGrow_GaussianModelEstimation - example_Image_Dijkstra_CostFromInput - example_Image_Dijkstra_CostFromRGBInput - example_Image_Dijkstra_DanielssonCost - example_Image_Dijkstra_DanielssonCost_TwoSeedsPath + example_Image_RegionGrow_ConnectedPixels + example_Image_RegionGrow_ConnectedRGBPixels example_Image_Dijkstra_EndPointDetection - example_Image_Dijkstra_LabelSkeleton - example_ShowSkeleton - ) +# example_Image_RegionGrow_GaussianModelEstimation +# example_Image_IncrementalRegionGrow_Thresholds +# example_Image_Dijkstra_CostFromInput +# example_Image_Dijkstra_CostFromRGBInput +# example_Image_Dijkstra_AbsoluteDifferenceCost +# example_Image_Dijkstra_DanielssonCost +# example_Image_Dijkstra_DanielssonCost_TwoSeedsPath +# example_Image_Dijkstra_LabelSkeleton +# example_ShowSkeleton +# example_CircleOfWillis +) FOREACH(EX ${SIMPLE_VTK_EXAMPLES}) ADD_EXECUTABLE(${EX} ${EX}.cxx) TARGET_LINK_LIBRARIES( diff --git a/appli/examples/example_CircleOfWillis.cxx b/appli/examples/example_CircleOfWillis.cxx new file mode 100644 index 0000000..e00ca3d --- /dev/null +++ b/appli/examples/example_CircleOfWillis.cxx @@ -0,0 +1,141 @@ +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include + +// ------------------------------------------------------------------------- +const unsigned int Dimension = 3; +typedef short TPixel; + +typedef itk::Image< TPixel, Dimension > TImage; + +// ------------------------------------------------------------------------- +int main( int argc, char* argv[] ) +{ + if( argc < 3 ) + { + std::cerr + << "Usage: " << argv[ 0 ] + << " input_image input_seeds" + << std::endl; + return( 1 ); + + } // fi + std::string input_image_fn = argv[ 1 ]; + std::string input_seeds_fn = argv[ 2 ]; + + // Read image + itk::ImageFileReader< TImage >::Pointer input_image_reader = + itk::ImageFileReader< TImage >::New( ); + input_image_reader->SetFileName( input_image_fn ); + try + { + input_image_reader->Update( ); + } + catch( itk::ExceptionObject& err ) + { + std::cerr << "Error caugth: " << err << std::endl; + return( 1 ); + + } // yrt + TImage::ConstPointer input_image = input_image_reader->GetOutput( ); + itk::ImageToVTKImageFilter< TImage >::Pointer input_image_vtk = + itk::ImageToVTKImageFilter< TImage >::New( ); + input_image_vtk->SetInput( input_image ); + input_image_vtk->Update( ); + + // Read seeds + std::ifstream input_seeds_fs( input_seeds_fn.c_str( ) ); + if( !input_seeds_fs ) + { + std::cerr + << "Error opening file \"" << input_seeds_fn << "\"" << std::endl; + return( 1 ); + + } // fi + + // Read seed points + std::string str_val; + unsigned int number_of_points; + input_seeds_fs >> str_val >> number_of_points; + input_seeds_fs >> str_val; // X + input_seeds_fs >> str_val; // Y + input_seeds_fs >> str_val; // Z + input_seeds_fs >> str_val; // value + input_seeds_fs >> str_val; // Label + + vtkSmartPointer< vtkPoints > input_seeds_points = + vtkSmartPointer< vtkPoints >::New( ); + vtkSmartPointer< vtkCellArray > input_seeds_cells = + vtkSmartPointer< vtkCellArray >::New( ); + vtkSmartPointer< vtkFloatArray > input_seeds_ids = + vtkSmartPointer< vtkFloatArray >::New( ); + + input_seeds_ids->SetNumberOfComponents( 1 ); + input_seeds_ids->SetNumberOfTuples( number_of_points ); + + double min_value = std::numeric_limits< double >::max( ); + double max_value = double( 0 ); + for( unsigned int i = 0; i < number_of_points; ++i ) + { + unsigned int x, y, z; + double value; + input_seeds_fs >> x >> y >> z >> value >> str_val; + + min_value = ( value < min_value )? value: min_value; + max_value = ( value > max_value )? value: max_value; + + TImage::IndexType idx; + idx[ 0 ] = x; + idx[ 1 ] = y; + idx[ 2 ] = z; + TImage::PointType pnt; + input_image->TransformIndexToPhysicalPoint( idx, pnt ); + + input_seeds_points->InsertNextPoint( pnt[ 0 ], pnt[ 1 ], pnt[ 2 ] ); + input_seeds_cells->InsertNextCell( 1 ); + input_seeds_cells->InsertCellPoint( i ); + input_seeds_ids->SetTuple1( + i, double( i ) / double( number_of_points - 1 ) + ); + + + } // rof + input_seeds_fs.close( ); + + vtkSmartPointer< vtkPolyData > input_seeds = + vtkSmartPointer< vtkPolyData >::New( ); + input_seeds->SetPoints( input_seeds_points ); + input_seeds->SetVerts( input_seeds_cells ); + input_seeds->GetPointData( )->SetScalars( input_seeds_ids ); + + // Show input image and let some interaction + fpa::VTK::ImageMPR view; + view.SetBackground( 0.3, 0.2, 0.8 ); + view.SetSize( 600, 600 ); + view.SetImage( input_image_vtk->GetOutput( ) ); + view.SetWindowLevel( + max_value - min_value, + ( min_value + max_value ) / double( 2 ) + ); + view.AddPolyData( input_seeds ); + view.Render( ); + view.Start( ); + + return( 0 ); +} + +// eof - $RCSfile$ diff --git a/appli/examples/example_Image_Dijkstra_AbsoluteDifferenceCost.cxx b/appli/examples/example_Image_Dijkstra_AbsoluteDifferenceCost.cxx new file mode 100644 index 0000000..47affc1 --- /dev/null +++ b/appli/examples/example_Image_Dijkstra_AbsoluteDifferenceCost.cxx @@ -0,0 +1,164 @@ +#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 float TInputPixel; +typedef float TOutputPixel; + +typedef itk::Image< TInputPixel, Dim > TInputImage; +typedef itk::Image< TOutputPixel, Dim > TOutputImage; +typedef itk::ImageToVTKImageFilter< TInputImage > TVTKInputImage; + +// ------------------------------------------------------------------------- +int main( int argc, char* argv[] ) +{ + if( argc < 8 ) + { + std::cerr + << "Usage: " << argv[ 0 ] + << " input_image input_seeds output_image" + << " neighborhood_order stop_at_one_front" + << " init_seed end_seed" + << std::endl; + return( 1 ); + + } // fi + std::string input_image_fn = argv[ 1 ]; + std::string input_seeds_fn = argv[ 2 ]; + std::string output_image_fn = argv[ 3 ]; + unsigned int neighborhood_order = std::atoi( argv[ 4 ] ); + bool stop_at_one_front = ( std::atoi( argv[ 5 ] ) != 0 ); + unsigned int init_seed = std::atoi( argv[ 6 ] ); + unsigned int end_seed = std::atoi( argv[ 7 ] ); + + // Read image + itk::ImageFileReader< TInputImage >::Pointer input_image_reader = + itk::ImageFileReader< TInputImage >::New( ); + input_image_reader->SetFileName( input_image_fn ); + try + { + input_image_reader->Update( ); + } + catch( itk::ExceptionObject& err ) + { + std::cerr + << "Error while reading image from " << input_image_fn << ": " + << err << std::endl; + return( 1 ); + + } // yrt + TInputImage::ConstPointer input_image = input_image_reader->GetOutput( ); + 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( 600, 600 ); + view.SetImage( vtk_input_image->GetOutput( ) ); + + // Allow some interaction + view.Render( ); + view.Start( ); + + // Prepare region grow filter and cost function + typedef fpa::Image::Dijkstra< TInputImage, TOutputImage > TFilter; + typedef fpa::Image::Functors:: + ImageAbsoluteDifferenceCostFunction< TFilter::TInputImage, TFilter::TResult > + TCost; + + TCost::Pointer cost = TCost::New( ); + + TFilter::Pointer filter = TFilter::New( ); + filter->SetInput( input_image ); + filter->SetCostFunction( cost ); + filter->SetConversionFunction( NULL ); + filter->SetNeighborhoodOrder( neighborhood_order ); + filter->SetStopAtOneFront( stop_at_one_front ); + + // Get user-given seeds + std::ifstream input_seeds_str( input_seeds_fn.c_str( ) ); + if( !input_seeds_str ) + { + std::cerr << "Error opening \"" << input_seeds_fn << "\"" << std::endl; + return( 1 ); + + } // fi + + unsigned int nSeeds; + input_seeds_str >> nSeeds; + std::vector< TInputImage::IndexType > input_seeds; + for( unsigned int s = 0; s < nSeeds; s++ ) + { + TInputImage::IndexType idx; + input_seeds_str >> idx[ 0 ] >> idx[ 1 ] >> idx[ 2 ]; + input_seeds.push_back( idx ); + + } // rof + input_seeds_str.close( ); + + filter->AddSeed( input_seeds[ init_seed ], 0 ); + filter->AddSeed( input_seeds[ end_seed ], 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! + filter->Update( ); + + // 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 ); +} + +// eof - $RCSfile$ diff --git a/appli/examples/example_Image_Dijkstra_EndPointDetection.cxx b/appli/examples/example_Image_Dijkstra_EndPointDetection.cxx index a334de3..aea0fe5 100644 --- a/appli/examples/example_Image_Dijkstra_EndPointDetection.cxx +++ b/appli/examples/example_Image_Dijkstra_EndPointDetection.cxx @@ -7,415 +7,291 @@ #include #include -#include -#include -#include - #include -#include - -#include #include -#include -#include - +#include +#include #include #include #include +#include -#include -#include -#include -#include -#include -#include +#include "fpa_Utility.h" // ------------------------------------------------------------------------- -const unsigned int Dim = 3; +const unsigned int Dim = 2; 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 > -void SaveImage( const I* image, const std::string& filename ); - -template< class I, class O > -void DistanceMap( - const typename I::Pointer& input, typename O::Pointer& output - ); +typedef itk::Image< TPixel, Dim > TImage; +typedef itk::Image< TScalar, Dim > TScalarImage; // ------------------------------------------------------------------------- int main( int argc, char* argv[] ) { - if( argc < 9 ) + if( argc < 7 ) { std::cerr << "Usage: " << argv[ 0 ] << std::endl - << " input_image" << std::endl - << " output_distancemap" << std::endl - << " output_costmap" << std::endl - << " output_labels" << std::endl - << " output_minimum_spanning_tree" << std::endl - << " output_endpoints" << std::endl - << " output_bifurcations" << std::endl - << " output_branches" << std::endl + << "\tinput_image" << std::endl + << "\toutput_labels" << std::endl + << "\toutput_minimum_spanning_tree" << std::endl + << "\toutput_endpoints" << std::endl + << "\toutput_bifurcations" << std::endl + << "\toutput_branches" << std::endl << std::endl; return( 1 ); } // fi std::string input_image_fn = argv[ 1 ]; - std::string distancemap_fn = argv[ 2 ]; - std::string output_costmap_fn = argv[ 3 ]; - std::string output_labels_fn = argv[ 4 ]; - std::string mst_output_fn = argv[ 5 ]; - std::string endpoints_output_fn = argv[ 6 ]; - std::string bifurcations_output_fn = argv[ 7 ]; - std::string branches_output_fn = argv[ 8 ]; + std::string output_labels_fn = argv[ 2 ]; + std::string output_minimum_spanning_tree_fn = argv[ 3 ]; + std::string output_endpoints_fn = argv[ 4 ]; + std::string output_bifurcations_fn = argv[ 5 ]; + std::string output_branches_fn = argv[ 6 ]; // Read image TImage::Pointer input_image; - try + std::string err = fpa_Utility::ReadImage( input_image, input_image_fn ); + if( err != "" ) { - ReadImage< TImage >( input_image, input_image_fn ); - } - catch( itk::ExceptionObject& err ) - { - std::cerr - << "Error caught while reading \"" - << input_image_fn << "\": " << err - << std::endl; + std::cerr << err << std::endl; return( 1 ); - } // yrt + } // fi - TVTKInputImage::Pointer vtk_input_image = TVTKInputImage::New( ); + // Show image and wait for, at least, one seed + itk::ImageToVTKImageFilter< TImage >::Pointer vtk_input_image = + itk::ImageToVTKImageFilter< TImage >::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( ) ); - - vtkSmartPointer< vtkImageMarchingCubes > mc = - vtkSmartPointer< vtkImageMarchingCubes >::New( ); - mc->SetInputData( vtk_input_image->GetOutput( ) ); - mc->SetValue( 0, 1e-1 ); - mc->Update( ); - view.AddPolyData( mc->GetOutput( ), 1, 1, 1, 0.4 ); - - // 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 ); + fpa_Utility::Viewer2DWithSeeds viewer; + viewer.SetImage( vtk_input_image->GetOutput( ) ); + while( viewer.GetNumberOfSeeds( ) == 0 ) + viewer.Start( ); // Compute squared distance map - TScalarImage::Pointer dmap; - DistanceMap< TImage, TScalarImage >( input_image, dmap ); + typename + itk::SignedMaurerDistanceMapImageFilter< TImage, TScalarImage >::Pointer + dmap = + itk::SignedMaurerDistanceMapImageFilter< TImage, TScalarImage >::New( ); + dmap->SetInput( input_image ); + dmap->SetBackgroundValue( TPixel( 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; // Prepare cost conversion function - typedef fpa::Base::Functors::InvertCostFunction< TScalar > TFunction; - TFunction::Pointer function = TFunction::New( ); + typedef fpa::Base::Functors::InvertCostFunction< TScalar > TCostFunction; + TCostFunction::Pointer cost_f = TCostFunction::New( ); // Prepare Dijkstra filter - typedef fpa::Image::DijkstraWithEndPointDetection< TScalarImage, TScalarImage > TFilter; + typedef fpa::Image:: + DijkstraWithEndPointDetection< TScalarImage, TScalarImage > TFilter; TFilter::Pointer filter = TFilter::New( ); - filter->SetInput( dmap ); - filter->SetConversionFunction( function ); + filter->SetInput( dmap->GetOutput( ) ); + filter->SetConversionFunction( cost_f ); filter->SetNeighborhoodOrder( 2 ); filter->StopAtOneFrontOff( ); - filter->AddSeed( seed, TScalar( 0 ) ); + + // Associate seed + TImage::PointType pnt; + TImage::IndexType idx; + viewer.GetSeed( pnt, 0 ); + if( input_image->TransformPhysicalPointToIndex( pnt, idx ) ) + filter->AddSeed( idx, 0 ); // Prepare graphical debugger - typedef fpa::VTK::Image3DObserver< TFilter, vtkRenderWindow > TDebugger; + typedef fpa::VTK::Image2DObserver< TFilter, vtkRenderWindow > TDebugger; TDebugger::Pointer debugger = TDebugger::New( ); - debugger->SetRenderWindow( view.GetWindow( ) ); - debugger->SetRenderPercentage( 0.0001 ); + debugger->SetRenderWindow( viewer.Window ); + debugger->SetRenderPercentage( 0.01 ); 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; - - // Outputs - const TFilter::TOutputImage* accumulated_costs = filter->GetOutput( ); - const TFilter::TLabelImage* labeled_image = filter->GetLabelImage( ); - const TFilter::TMinimumSpanningTree* mst = filter->GetMinimumSpanningTree( ); - const TFilter::TUniqueVertices* endpoints = filter->GetEndPoints( ); - const TFilter::TUniqueVertices* bifurcations = filter->GetBifurcations( ); - const TFilter::TBranches* branches = filter->GetBranches( ); - unsigned long nBranches = filter->GetNumberOfBranches( ); - - // Save outputs - SaveImage( dmap.GetPointer( ), distancemap_fn ); - SaveImage( accumulated_costs, output_costmap_fn ); - SaveImage( labeled_image, output_labels_fn ); + << "s." << std::endl; + + // Create new actors + typedef vtkSmartPointer< fpa::VTK::UniqueVerticesToPolyDataFilter< TFilter::TUniqueVertices, TFilter::TInputImage > > TVertices2PD; + + TVertices2PD endpoints2pd = TVertices2PD::New( ); + endpoints2pd->SetInput( filter->GetEndPoints( ) ); + endpoints2pd->SetImage( filter->GetInput( ) ); + endpoints2pd->Update( ); + + vtkSmartPointer< vtkPolyDataMapper > endpoints_mapper = + vtkSmartPointer< vtkPolyDataMapper >::New( ); + endpoints_mapper->SetInputConnection( endpoints2pd->GetOutputPort( ) ); + + vtkSmartPointer< vtkActor > endpoints_actor = + vtkSmartPointer< vtkActor >::New( ); + endpoints_actor->SetMapper( endpoints_mapper ); + endpoints_actor->GetProperty( )->SetColor( 0, 1, 0 ); + endpoints_actor->GetProperty( )->SetPointSize( 5 ); + viewer.Renderer->AddActor( endpoints_actor ); + + TVertices2PD bifurcations2pd = TVertices2PD::New( ); + bifurcations2pd->SetInput( filter->GetBifurcations( ) ); + bifurcations2pd->SetImage( filter->GetInput( ) ); + bifurcations2pd->Update( ); + + vtkSmartPointer< vtkPolyDataMapper > bifurcations_mapper = + vtkSmartPointer< vtkPolyDataMapper >::New( ); + bifurcations_mapper->SetInputConnection( bifurcations2pd->GetOutputPort( ) ); + + vtkSmartPointer< vtkActor > bifurcations_actor = + vtkSmartPointer< vtkActor >::New( ); + bifurcations_actor->SetMapper( bifurcations_mapper ); + bifurcations_actor->GetProperty( )->SetColor( 1, 0, 0 ); + bifurcations_actor->GetProperty( )->SetPointSize( 5 ); + viewer.Renderer->AddActor( bifurcations_actor ); + + // Some more interaction and finish + viewer.Render( ); + viewer.Start( ); + + // Save results + err = fpa_Utility::SaveImage( filter->GetLabelImage( ), output_labels_fn ); + if( err != "" ) + std::cerr << err << std::endl; fpa::IO::MinimumSpanningTreeWriter< TFilter::TMinimumSpanningTree >::Pointer mst_writer = fpa::IO::MinimumSpanningTreeWriter< TFilter::TMinimumSpanningTree >::New( ); - mst_writer->SetInput( mst ); - mst_writer->SetFileName( mst_output_fn ); + mst_writer->SetInput( filter->GetMinimumSpanningTree( ) ); + mst_writer->SetFileName( output_minimum_spanning_tree_fn ); mst_writer->Update( ); fpa::IO::UniqueValuesContainerWriter< TFilter::TUniqueVertices >::Pointer endpoints_writer = fpa::IO::UniqueValuesContainerWriter< TFilter::TUniqueVertices >::New( ); - endpoints_writer->SetInput( endpoints ); - endpoints_writer->SetFileName( endpoints_output_fn ); + endpoints_writer->SetInput( filter->GetEndPoints( ) ); + endpoints_writer->SetFileName( output_endpoints_fn ); endpoints_writer->Update( ); fpa::IO::UniqueValuesContainerWriter< TFilter::TUniqueVertices >::Pointer bifurcations_writer = fpa::IO::UniqueValuesContainerWriter< TFilter::TUniqueVertices >::New( ); - bifurcations_writer->SetInput( bifurcations ); - bifurcations_writer->SetFileName( bifurcations_output_fn ); + bifurcations_writer->SetInput( filter->GetBifurcations( ) ); + bifurcations_writer->SetFileName( output_bifurcations_fn ); bifurcations_writer->Update( ); fpa::IO::MatrixValuesContainerWriter< TFilter::TBranches >::Pointer branches_writer = fpa::IO::MatrixValuesContainerWriter< TFilter::TBranches >::New( ); - branches_writer->SetInput( branches ); - branches_writer->SetFileName( branches_output_fn ); + branches_writer->SetInput( filter->GetBranches( ) ); + branches_writer->SetFileName( output_branches_fn ); branches_writer->Update( ); - // Show endpoints - vtkSmartPointer< vtkPoints > endpoints_points = - vtkSmartPointer< vtkPoints >::New( ); - vtkSmartPointer< vtkCellArray > endpoints_cells = - vtkSmartPointer< vtkCellArray >::New( ); - for( - TFilter::TUniqueVertices::ConstIterator epIt = endpoints->Begin( ); - epIt != endpoints->End( ); - ++epIt - ) - { - TImage::PointType pnt; - input_image->TransformIndexToPhysicalPoint( *epIt, pnt ); - endpoints_points->InsertNextPoint( pnt[ 0 ], pnt[ 1 ], pnt[ 2 ] ); - endpoints_cells->InsertNextCell( 1 ); - endpoints_cells-> - InsertCellPoint( endpoints_points->GetNumberOfPoints( ) - 1 ); - - } // rof - vtkSmartPointer< vtkPolyData > endpoints_polydata = - vtkSmartPointer< vtkPolyData >::New( ); - endpoints_polydata->SetPoints( endpoints_points ); - endpoints_polydata->SetVerts( endpoints_cells ); - view.AddPolyData( endpoints_polydata, 0, 0, 1, 1 ); - - // Show bifurcations - vtkSmartPointer< vtkPoints > bifurcations_points = - vtkSmartPointer< vtkPoints >::New( ); - vtkSmartPointer< vtkCellArray > bifurcations_cells = - vtkSmartPointer< vtkCellArray >::New( ); - for( - TFilter::TUniqueVertices::ConstIterator bfIt = bifurcations->Begin( ); - bfIt != bifurcations->End( ); - ++bfIt - ) - { - TImage::PointType pnt; - input_image->TransformIndexToPhysicalPoint( *bfIt, pnt ); - bifurcations_points->InsertNextPoint( pnt[ 0 ], pnt[ 1 ], pnt[ 2 ] ); - bifurcations_cells->InsertNextCell( 1 ); - bifurcations_cells-> - InsertCellPoint( bifurcations_points->GetNumberOfPoints( ) - 1 ); - - } // rof - vtkSmartPointer< vtkPolyData > bifurcations_polydata = - vtkSmartPointer< vtkPolyData >::New( ); - bifurcations_polydata->SetPoints( bifurcations_points ); - bifurcations_polydata->SetVerts( bifurcations_cells ); - view.AddPolyData( bifurcations_polydata, 0, 1, 0, 1 ); - - // Show branches (simple and detailed) - vtkSmartPointer< vtkPoints > simple_branches_points = - vtkSmartPointer< vtkPoints >::New( ); - vtkSmartPointer< vtkCellArray > simple_branches_cells = - vtkSmartPointer< vtkCellArray >::New( ); - - vtkSmartPointer< vtkPoints > detailed_branches_points = - vtkSmartPointer< vtkPoints >::New( ); - vtkSmartPointer< vtkCellArray > detailed_branches_cells = - vtkSmartPointer< vtkCellArray >::New( ); - vtkSmartPointer< vtkFloatArray > detailed_branches_scalars = - vtkSmartPointer< vtkFloatArray >::New( ); - - TFilter::TBranches::ConstIterator brIt = branches->Begin( ); - for( ; brIt != branches->End( ); ++brIt ) - { - // Branch's first point - TImage::PointType first_point; - input_image->TransformIndexToPhysicalPoint( brIt->first, first_point ); - unsigned long first_id = simple_branches_points->GetNumberOfPoints( ); - simple_branches_points->InsertNextPoint( - first_point[ 0 ], first_point[ 1 ], first_point[ 2 ] - ); - - TFilter::TBranches::ConstRowIterator brRowIt = branches->Begin( brIt ); - for( ; brRowIt != branches->End( brIt ); ++brRowIt ) - { - // Branch's second point - TImage::PointType second_point; - input_image-> - TransformIndexToPhysicalPoint( brRowIt->first, second_point ); - unsigned long second_id = simple_branches_points->GetNumberOfPoints( ); - simple_branches_points->InsertNextPoint( - second_point[ 0 ], second_point[ 1 ], second_point[ 2 ] - ); - simple_branches_cells->InsertNextCell( 2 ); - simple_branches_cells->InsertCellPoint( first_id ); - simple_branches_cells->InsertCellPoint( second_id ); - - // Detailed path - double pathId = double( brRowIt->second - 1 ) / double( nBranches - 1 ); - TFilter::TVertices path; - mst->GetPath( path, brIt->first, brRowIt->first ); - TFilter::TVertices::const_iterator pIt = path.begin( ); - for( ; pIt != path.end( ); ++pIt ) - { - TImage::PointType path_point; - input_image->TransformIndexToPhysicalPoint( *pIt, path_point ); - detailed_branches_points->InsertNextPoint( - path_point[ 0 ], path_point[ 1 ], path_point[ 2 ] - ); - detailed_branches_scalars->InsertNextTuple1( pathId ); - if( pIt != path.begin( ) ) - { - unsigned long nPoints = - detailed_branches_points->GetNumberOfPoints( ); - detailed_branches_cells->InsertNextCell( 2 ); - detailed_branches_cells->InsertCellPoint( nPoints - 2 ); - detailed_branches_cells->InsertCellPoint( nPoints - 1 ); - - } // fi - - } // rof - - } // rof - - } // rof - vtkSmartPointer< vtkPolyData > simple_branches_polydata = - vtkSmartPointer< vtkPolyData >::New( ); - simple_branches_polydata->SetPoints( simple_branches_points ); - simple_branches_polydata->SetLines( simple_branches_cells ); - view.AddPolyData( simple_branches_polydata, 1, 0, 1, 1 ); - - vtkSmartPointer< vtkPolyData > detailed_branches_polydata = - vtkSmartPointer< vtkPolyData >::New( ); - detailed_branches_polydata->SetPoints( detailed_branches_points ); - detailed_branches_polydata->SetLines( detailed_branches_cells ); - detailed_branches_polydata-> - GetPointData( )->SetScalars( detailed_branches_scalars ); - view.AddPolyData( detailed_branches_polydata, 1 ); - - // Let some more interaction - view.Render( ); - view.Start( ); - 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 > -void SaveImage( const I* image, const std::string& filename ) -{ - typename itk::ImageFileWriter< I >::Pointer writer = - itk::ImageFileWriter< I >::New( ); - writer->SetInput( image ); - writer->SetFileName( filename ); - try - { - writer->Update( ); - } - catch( itk::ExceptionObject& err ) - { - std::cerr - << "Error saving \"" << filename << "\": " << err - << std::endl; - - } // yrt -} - -// ------------------------------------------------------------------------- -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; +// eof - $RCSfile$ - output = dmap->GetOutput( ); - output->DisconnectPipeline( ); -} +/* TODO + vtkSmartPointer< vtkPoints > simple_branches_points = + vtkSmartPointer< vtkPoints >::New( ); + vtkSmartPointer< vtkCellArray > simple_branches_cells = + vtkSmartPointer< vtkCellArray >::New( ); + + vtkSmartPointer< vtkPoints > detailed_branches_points = + vtkSmartPointer< vtkPoints >::New( ); + vtkSmartPointer< vtkCellArray > detailed_branches_cells = + vtkSmartPointer< vtkCellArray >::New( ); + vtkSmartPointer< vtkFloatArray > detailed_branches_scalars = + vtkSmartPointer< vtkFloatArray >::New( ); + + TFilter::TBranches::ConstIterator brIt = branches->Begin( ); + for( ; brIt != branches->End( ); ++brIt ) + { + // Branch's first point + TImage::PointType first_point; + input_image->TransformIndexToPhysicalPoint( brIt->first, first_point ); + unsigned long first_id = simple_branches_points->GetNumberOfPoints( ); + simple_branches_points->InsertNextPoint( + first_point[ 0 ], first_point[ 1 ], first_point[ 2 ] + ); + + TFilter::TBranches::ConstRowIterator brRowIt = branches->Begin( brIt ); + for( ; brRowIt != branches->End( brIt ); ++brRowIt ) + { + // Branch's second point + TImage::PointType second_point; + input_image-> + TransformIndexToPhysicalPoint( brRowIt->first, second_point ); + unsigned long second_id = simple_branches_points->GetNumberOfPoints( ); + simple_branches_points->InsertNextPoint( + second_point[ 0 ], second_point[ 1 ], second_point[ 2 ] + ); + simple_branches_cells->InsertNextCell( 2 ); + simple_branches_cells->InsertCellPoint( first_id ); + simple_branches_cells->InsertCellPoint( second_id ); + + // Detailed path + double pathId = double( brRowIt->second - 1 ) / double( nBranches - 1 ); + TFilter::TVertices path; + mst->GetPath( path, brIt->first, brRowIt->first ); + TFilter::TVertices::const_iterator pIt = path.begin( ); + for( ; pIt != path.end( ); ++pIt ) + { + TImage::PointType path_point; + input_image->TransformIndexToPhysicalPoint( *pIt, path_point ); + detailed_branches_points->InsertNextPoint( + path_point[ 0 ], path_point[ 1 ], path_point[ 2 ] + ); + detailed_branches_scalars->InsertNextTuple1( pathId ); + if( pIt != path.begin( ) ) + { + unsigned long nPoints = + detailed_branches_points->GetNumberOfPoints( ); + detailed_branches_cells->InsertNextCell( 2 ); + detailed_branches_cells->InsertCellPoint( nPoints - 2 ); + detailed_branches_cells->InsertCellPoint( nPoints - 1 ); + + } // fi + + } // rof + + } // rof + + } // rof + vtkSmartPointer< vtkPolyData > simple_branches_polydata = + vtkSmartPointer< vtkPolyData >::New( ); + simple_branches_polydata->SetPoints( simple_branches_points ); + simple_branches_polydata->SetLines( simple_branches_cells ); + view.AddPolyData( simple_branches_polydata, 1, 0, 1, 1 ); + + vtkSmartPointer< vtkPolyData > detailed_branches_polydata = + vtkSmartPointer< vtkPolyData >::New( ); + detailed_branches_polydata->SetPoints( detailed_branches_points ); + detailed_branches_polydata->SetLines( detailed_branches_cells ); + detailed_branches_polydata-> + GetPointData( )->SetScalars( detailed_branches_scalars ); + view.AddPolyData( detailed_branches_polydata, 1 ); + + // Let some more interaction + view.Render( ); + view.Start( ); + + return( 0 ); + } +*/ // eof - $RCSfile$ diff --git a/appli/examples/example_Image_IncrementalRegionGrow_Thresholds.cxx b/appli/examples/example_Image_IncrementalRegionGrow_Thresholds.cxx new file mode 100644 index 0000000..3261b60 --- /dev/null +++ b/appli/examples/example_Image_IncrementalRegionGrow_Thresholds.cxx @@ -0,0 +1,235 @@ +#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 short TInputPixel; +typedef short TOutputPixel; + +typedef itk::Image< TInputPixel, Dim > TInputImage; +typedef itk::Image< TOutputPixel, Dim > TOutputImage; +typedef itk::ImageToVTKImageFilter< TInputImage > TVTKInputImage; + +// ------------------------------------------------------------------------- +int main( int argc, char* argv[] ) +{ + if( argc < 8 ) + { + std::cerr + << "Usage: " << argv[ 0 ] << std::endl + << "\tinput_image" << std::endl + << "\toutput_image" << std::endl + << "\tneighborhood_order" << std::endl + << "\tstop_at_one_front" << std::endl + << "\tinit_threshold" << std::endl + << "\tend_threshold" << std::endl + << "\tsamples" << std::endl + << "\t[input_seeds]" << std::endl; + return( 1 ); + + } // fi + std::string input_image_fn = argv[ 1 ]; + std::string output_image_fn = argv[ 2 ]; + unsigned int neighborhood_order = std::atoi( argv[ 3 ] ); + bool stop_at_one_front = ( std::atoi( argv[ 4 ] ) != 0 ); + TInputPixel init_threshold = TInputPixel( std::atof( argv[ 5 ] ) ); + TInputPixel end_threshold = TInputPixel( std::atof( argv[ 6 ] ) ); + unsigned int samples = TInputPixel( std::atof( argv[ 7 ] ) ); + std::string input_seeds_fn = ( argc >= 9 )? argv[ 8 ]: ""; + + // Read image + itk::ImageFileReader< TInputImage >::Pointer input_image_reader = + itk::ImageFileReader< TInputImage >::New( ); + input_image_reader->SetFileName( input_image_fn ); + try + { + input_image_reader->Update( ); + } + catch( itk::ExceptionObject& err ) + { + std::cerr + << "Error while reading image from " << input_image_fn << ": " + << err << std::endl; + return( 1 ); + + } // yrt + TInputImage::ConstPointer input_image = input_image_reader->GetOutput( ); + 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( 600, 600 ); + view.SetImage( vtk_input_image->GetOutput( ) ); + view.Render( ); + + // Read seeds + std::vector< TInputImage::IndexType > input_seeds; + if( input_seeds_fn != "" ) + { + std::ifstream input_seeds_str( input_seeds_fn.c_str( ) ); + if( input_seeds_str ) + { + unsigned int nSeeds; + input_seeds_str >> nSeeds; + for( unsigned int i = 0; i < nSeeds; ++i ) + { + TInputImage::PointType pnt; + input_seeds_str >> pnt[ 0 ] >> pnt[ 1 ] >> pnt[ 2 ]; + + TInputImage::IndexType idx; + input_image_reader->GetOutput( )-> + TransformPhysicalPointToIndex( pnt, idx ); + input_seeds.push_back( idx ); + + view.AddSeed( pnt[ 0 ], pnt[ 1 ], pnt[ 2 ] ); + + } // rof + input_seeds_str.close( ); + } + else + std::cerr << "Error reading \"" << input_seeds_fn << "\"" << std::endl; + + } // fi + + // Allow some interaction + view.Render( ); + if( input_seeds.size( ) == 0 ) + { + while( view.GetNumberOfSeeds( ) == 0 ) + view.Start( ); + + for( unsigned int i = 0; i < view.GetNumberOfSeeds( ); ++i ) + { + double p[ 3 ]; + view.GetSeed( i, p ); + + TInputImage::PointType pnt; + pnt[ 0 ] = p[ 0 ]; + pnt[ 1 ] = p[ 1 ]; + pnt[ 2 ] = p[ 2 ]; + + TInputImage::IndexType idx; + input_image_reader->GetOutput( )-> + TransformPhysicalPointToIndex( pnt, idx ); + input_seeds.push_back( idx ); + + } // rof + } + else + view.Start( ); + + // Prepare region grow filter and cost function + typedef fpa::Image:: + IncrementalRegionGrow< TInputImage, TOutputImage > TFilter; + typedef fpa::Image::Functors:: + RegionGrowThresholdFunction< TInputImage > TFunction; + + TFilter::Pointer filter = TFilter::New( ); + filter->SetInput( input_image_reader->GetOutput( ) ); + + /* + typedef fpa::Image::Dijkstra< TInputImage, TOutputImage > TFilter; + typedef fpa::Image::Functors:: + ImageAbsoluteDifferenceCostFunction< TFilter::TInputImage, TFilter::TResult > + TCost; + + TCost::Pointer cost = TCost::New( ); + + TFilter::Pointer filter = TFilter::New( ); + filter->SetInput( input_image ); + filter->SetCostFunction( cost ); + filter->SetConversionFunction( NULL ); + filter->SetNeighborhoodOrder( neighborhood_order ); + filter->SetStopAtOneFront( stop_at_one_front ); + + // Get user-given seeds + std::ifstream input_seeds_str( input_seeds_fn.c_str( ) ); + if( !input_seeds_str ) + { + std::cerr << "Error opening \"" << input_seeds_fn << "\"" << std::endl; + return( 1 ); + + } // fi + + unsigned int nSeeds; + input_seeds_str >> nSeeds; + std::vector< TInputImage::IndexType > input_seeds; + for( unsigned int s = 0; s < nSeeds; s++ ) + { + TInputImage::IndexType idx; + input_seeds_str >> idx[ 0 ] >> idx[ 1 ] >> idx[ 2 ]; + input_seeds.push_back( idx ); + + } // rof + input_seeds_str.close( ); + + filter->AddSeed( input_seeds[ init_seed ], 0 ); + filter->AddSeed( input_seeds[ end_seed ], 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! + filter->Update( ); + + // 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 ); +} + +// eof - $RCSfile$ diff --git a/appli/examples/example_Image_RegionGrow_AllPixels.cxx b/appli/examples/example_Image_RegionGrow_AllPixels.cxx index 9484957..db7db5f 100644 --- a/appli/examples/example_Image_RegionGrow_AllPixels.cxx +++ b/appli/examples/example_Image_RegionGrow_AllPixels.cxx @@ -6,30 +6,16 @@ #include #include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - #include -#include +#include #include +#include "fpa_Utility.h" + // ------------------------------------------------------------------------- const unsigned int Dim = 2; typedef unsigned char TPixel; - -typedef itk::Image< TPixel, Dim > TImage; -typedef itk::ImageToVTKImageFilter< TImage > TVTKImage; +typedef itk::Image< TPixel, Dim > TImage; // ------------------------------------------------------------------------- int main( int argc, char* argv[] ) @@ -48,99 +34,49 @@ int main( int argc, char* argv[] ) bool stop_at_one_front = ( std::atoi( argv[ 3 ] ) != 0 ); // Read image - itk::ImageFileReader< TImage >::Pointer input_image_reader = - itk::ImageFileReader< TImage >::New( ); - input_image_reader->SetFileName( input_image_fn ); - try + TImage::Pointer input_image; + std::string err = fpa_Utility::ReadImage( input_image, input_image_fn ); + if( err != "" ) { - input_image_reader->Update( ); - } - catch( itk::ExceptionObject& err ) - { - std::cerr - << "Error while reading image from " << input_image_fn << ": " - << err << std::endl; + std::cerr << err << std::endl; return( 1 ); - } // yrt - TImage::ConstPointer input_image = input_image_reader->GetOutput( ); - TVTKImage::Pointer vtk_input_image = TVTKImage::New( ); + } // fi + + // Show image and wait for, at least, one seed + itk::ImageToVTKImageFilter< TImage >::Pointer vtk_input_image = + itk::ImageToVTKImageFilter< TImage >::New( ); vtk_input_image->SetInput( input_image ); vtk_input_image->Update( ); - // VTK visualization - vtkSmartPointer< vtkImageActor > actor = - vtkSmartPointer< vtkImageActor >::New( ); - actor->SetInputData( vtk_input_image->GetOutput( ) ); - - vtkSmartPointer< vtkRenderer > renderer = - vtkSmartPointer< vtkRenderer >::New( ); - renderer->SetBackground( 0.1, 0.2, 0.7 ); - renderer->AddActor( actor ); - vtkSmartPointer< vtkRenderWindow > window = - vtkSmartPointer< vtkRenderWindow >::New( ); - window->SetSize( 800, 800 ); - window->AddRenderer( renderer ); - - // Correct camera due to the loaded image - vtkCamera* camera = renderer->GetActiveCamera( ); - camera->SetViewUp( 0, -1, 0 ); - camera->SetPosition( 0, 0, -1 ); - camera->SetFocalPoint( 0, 0, 0 ); - - // VTK interaction - vtkSmartPointer< vtkInteractorStyleImage > imageStyle = - vtkSmartPointer< vtkInteractorStyleImage >::New( ); - vtkSmartPointer< vtkRenderWindowInteractor > interactor = - vtkSmartPointer< vtkRenderWindowInteractor >::New( ); - interactor->SetInteractorStyle( imageStyle ); - window->SetInteractor( interactor ); - - // Create the widget and its representation - vtkSmartPointer< vtkPointHandleRepresentation3D > handle = - vtkSmartPointer< vtkPointHandleRepresentation3D >::New( ); - handle->GetProperty( )->SetColor( 1, 0, 0 ); - vtkSmartPointer< vtkSeedRepresentation > rep = - vtkSmartPointer< vtkSeedRepresentation >::New( ); - rep->SetHandleRepresentation( handle ); - - vtkSmartPointer< vtkSeedWidget > widget = - vtkSmartPointer< vtkSeedWidget >::New( ); - widget->SetInteractor( interactor ); - widget->SetRepresentation( rep ); - - // Let some interaction - interactor->Initialize( ); - renderer->ResetCamera( ); - window->Render( ); - widget->On( ); - interactor->Start( ); + fpa_Utility::Viewer2DWithSeeds viewer; + viewer.SetImage( vtk_input_image->GetOutput( ) ); + while( viewer.GetNumberOfSeeds( ) == 0 ) + viewer.Start( ); + + // Region growing types + typedef fpa::Image::RegionGrow< TImage > TFilter; + typedef fpa::Image::Functors:: + RegionGrowAllBelongsFunction< TImage > TFunction; // Prepare region grow function - typedef fpa::Base::Functors::TautologyFunction< TImage::PixelType > TFunction; TFunction::Pointer function = TFunction::New( ); // Prepare region grow filter - typedef fpa::Image::RegionGrow< TImage, TImage > TFilter; TFilter::Pointer filter = TFilter::New( ); filter->SetInput( input_image ); - filter->SetMembershipFunction( function ); + filter->SetGrowingFunction( function ); filter->SetNeighborhoodOrder( neighborhood_order ); filter->SetOutsideValue( TPixel( 0 ) ); filter->SetInsideValue( std::numeric_limits< TPixel >::max( ) ); filter->SetStopAtOneFront( stop_at_one_front ); - // Get user-given seeds - for( unsigned int s = 0; s < rep->GetNumberOfSeeds( ); s++ ) + // Associate seeds + for( unsigned long s = 0; s < viewer.GetNumberOfSeeds( ); ++s ) { - double pos[ 3 ]; - rep->GetSeedWorldPosition( s, pos ); - TImage::PointType pnt; - pnt[ 0 ] = TImage::PointType::ValueType( pos[ 0 ] ); - pnt[ 1 ] = TImage::PointType::ValueType( pos[ 1 ] ); - TImage::IndexType idx; + viewer.GetSeed( pnt, s ); if( input_image->TransformPhysicalPointToIndex( pnt, idx ) ) filter->AddSeed( idx, 0 ); @@ -149,7 +85,7 @@ int main( int argc, char* argv[] ) // Prepare graphical debugger typedef fpa::VTK::Image2DObserver< TFilter, vtkRenderWindow > TDebugger; TDebugger::Pointer debugger = TDebugger::New( ); - debugger->SetRenderWindow( window ); + debugger->SetRenderWindow( viewer.Window ); debugger->SetRenderPercentage( 0.01 ); filter->AddObserver( itk::AnyEvent( ), debugger ); filter->ThrowEventsOn( ); @@ -157,6 +93,8 @@ int main( int argc, char* argv[] ) // Go! filter->Update( ); + // Some more interaction and finish + viewer.Start( ); return( 0 ); } diff --git a/appli/examples/example_Image_RegionGrow_AllRGBPixels.cxx b/appli/examples/example_Image_RegionGrow_AllRGBPixels.cxx index fdb90fa..c46c758 100644 --- a/appli/examples/example_Image_RegionGrow_AllRGBPixels.cxx +++ b/appli/examples/example_Image_RegionGrow_AllRGBPixels.cxx @@ -4,34 +4,20 @@ #include #include -#include #include - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include +#include #include -#include +#include #include +#include "fpa_Utility.h" + // ------------------------------------------------------------------------- const unsigned int Dim = 2; typedef unsigned char TPixel; - typedef itk::Image< itk::RGBPixel< TPixel >, Dim > TColorImage; typedef itk::Image< TPixel, Dim > TImage; -typedef itk::ImageToVTKImageFilter< TColorImage > TVTKImage; // ------------------------------------------------------------------------- int main( int argc, char* argv[] ) @@ -50,99 +36,49 @@ int main( int argc, char* argv[] ) bool stop_at_one_front = ( std::atoi( argv[ 3 ] ) != 0 ); // Read image - itk::ImageFileReader< TColorImage >::Pointer input_image_reader = - itk::ImageFileReader< TColorImage >::New( ); - input_image_reader->SetFileName( input_image_fn ); - try + TColorImage::Pointer input_image; + std::string err = fpa_Utility::ReadImage( input_image, input_image_fn ); + if( err != "" ) { - input_image_reader->Update( ); - } - catch( itk::ExceptionObject& err ) - { - std::cerr - << "Error while reading image from " << input_image_fn << ": " - << err << std::endl; + std::cerr << err << std::endl; return( 1 ); - } // yrt - TColorImage::ConstPointer input_image = input_image_reader->GetOutput( ); - TVTKImage::Pointer vtk_input_image = TVTKImage::New( ); + } // fi + + // Show image and wait for, at least, one seed + itk::ImageToVTKImageFilter< TColorImage >::Pointer vtk_input_image = + itk::ImageToVTKImageFilter< TColorImage >::New( ); vtk_input_image->SetInput( input_image ); vtk_input_image->Update( ); - // VTK visualization - vtkSmartPointer< vtkImageActor > actor = - vtkSmartPointer< vtkImageActor >::New( ); - actor->SetInputData( vtk_input_image->GetOutput( ) ); - - vtkSmartPointer< vtkRenderer > renderer = - vtkSmartPointer< vtkRenderer >::New( ); - renderer->SetBackground( 0.1, 0.2, 0.7 ); - renderer->AddActor( actor ); - vtkSmartPointer< vtkRenderWindow > window = - vtkSmartPointer< vtkRenderWindow >::New( ); - window->SetSize( 800, 800 ); - window->AddRenderer( renderer ); - - // Correct camera due to the loaded image - vtkCamera* camera = renderer->GetActiveCamera( ); - camera->SetViewUp( 0, -1, 0 ); - camera->SetPosition( 0, 0, -1 ); - camera->SetFocalPoint( 0, 0, 0 ); - - // VTK interaction - vtkSmartPointer< vtkInteractorStyleImage > imageStyle = - vtkSmartPointer< vtkInteractorStyleImage >::New( ); - vtkSmartPointer< vtkRenderWindowInteractor > interactor = - vtkSmartPointer< vtkRenderWindowInteractor >::New( ); - interactor->SetInteractorStyle( imageStyle ); - window->SetInteractor( interactor ); - - // Create the widget and its representation - vtkSmartPointer< vtkPointHandleRepresentation3D > handle = - vtkSmartPointer< vtkPointHandleRepresentation3D >::New( ); - handle->GetProperty( )->SetColor( 1, 0, 0 ); - vtkSmartPointer< vtkSeedRepresentation > rep = - vtkSmartPointer< vtkSeedRepresentation >::New( ); - rep->SetHandleRepresentation( handle ); - - vtkSmartPointer< vtkSeedWidget > widget = - vtkSmartPointer< vtkSeedWidget >::New( ); - widget->SetInteractor( interactor ); - widget->SetRepresentation( rep ); - - // Let some interaction - interactor->Initialize( ); - renderer->ResetCamera( ); - window->Render( ); - widget->On( ); - interactor->Start( ); + fpa_Utility::Viewer2DWithSeeds viewer; + viewer.SetImage( vtk_input_image->GetOutput( ) ); + while( viewer.GetNumberOfSeeds( ) == 0 ) + viewer.Start( ); + + // Region growing types + typedef fpa::Image::RegionGrow< TColorImage, TImage > TFilter; + typedef fpa::Image::Functors:: + RegionGrowAllBelongsFunction< TColorImage > TFunction; // Prepare region grow function - typedef fpa::Base::Functors::TautologyFunction< TColorImage::PixelType > TFunction; TFunction::Pointer function = TFunction::New( ); // Prepare region grow filter - typedef fpa::Image::RegionGrow< TColorImage, TImage > TFilter; TFilter::Pointer filter = TFilter::New( ); filter->SetInput( input_image ); - filter->SetMembershipFunction( function ); + filter->SetGrowingFunction( function ); filter->SetNeighborhoodOrder( neighborhood_order ); filter->SetOutsideValue( TPixel( 0 ) ); filter->SetInsideValue( std::numeric_limits< TPixel >::max( ) ); filter->SetStopAtOneFront( stop_at_one_front ); - // Get user-given seeds - for( unsigned int s = 0; s < rep->GetNumberOfSeeds( ); s++ ) + // Associate seeds + for( unsigned long s = 0; s < viewer.GetNumberOfSeeds( ); ++s ) { - double pos[ 3 ]; - rep->GetSeedWorldPosition( s, pos ); - TImage::PointType pnt; - pnt[ 0 ] = TImage::PointType::ValueType( pos[ 0 ] ); - pnt[ 1 ] = TImage::PointType::ValueType( pos[ 1 ] ); - TImage::IndexType idx; + viewer.GetSeed( pnt, s ); if( input_image->TransformPhysicalPointToIndex( pnt, idx ) ) filter->AddSeed( idx, 0 ); @@ -151,14 +87,16 @@ int main( int argc, char* argv[] ) // Prepare graphical debugger typedef fpa::VTK::Image2DObserver< TFilter, vtkRenderWindow > TDebugger; TDebugger::Pointer debugger = TDebugger::New( ); - debugger->SetRenderWindow( window ); - debugger->SetRenderPercentage( 0.001 ); + debugger->SetRenderWindow( viewer.Window ); + debugger->SetRenderPercentage( 0.01 ); filter->AddObserver( itk::AnyEvent( ), debugger ); filter->ThrowEventsOn( ); // Go! filter->Update( ); + // Some more interaction and finish + viewer.Start( ); return( 0 ); } diff --git a/appli/examples/example_Image_RegionGrow_ConnectedPixels.cxx b/appli/examples/example_Image_RegionGrow_ConnectedPixels.cxx new file mode 100644 index 0000000..4f65ce6 --- /dev/null +++ b/appli/examples/example_Image_RegionGrow_ConnectedPixels.cxx @@ -0,0 +1,98 @@ +#include +#include +#include +#include + +#include +#include + +#include +#include +#include + +#include "fpa_Utility.h" + +// ------------------------------------------------------------------------- +const unsigned int Dim = 2; +typedef unsigned char TPixel; +typedef itk::Image< TPixel, Dim > TImage; + +// ------------------------------------------------------------------------- +int main( int argc, char* argv[] ) +{ + if( argc < 3 ) + { + std::cerr + << "Usage: " << argv[ 0 ] + << " input_image neighborhood_order" + << std::endl; + return( 1 ); + + } // fi + std::string input_image_fn = argv[ 1 ]; + unsigned int neighborhood_order = std::atoi( argv[ 2 ] ); + + // Read image + TImage::Pointer input_image; + std::string err = fpa_Utility::ReadImage( input_image, input_image_fn ); + if( err != "" ) + { + std::cerr << err << std::endl; + return( 1 ); + + } // fi + + // Show image and wait for, at least, one seed + itk::ImageToVTKImageFilter< TImage >::Pointer vtk_input_image = + itk::ImageToVTKImageFilter< TImage >::New( ); + vtk_input_image->SetInput( input_image ); + vtk_input_image->Update( ); + + fpa_Utility::Viewer2DWithSeeds viewer; + viewer.SetImage( vtk_input_image->GetOutput( ) ); + while( viewer.GetNumberOfSeeds( ) == 0 ) + viewer.Start( ); + + // Region growing types + typedef fpa::Image::RegionGrow< TImage > TFilter; + typedef fpa::Image::Functors:: + RegionGrowThresholdFunction< TImage > TFunction; + + // Prepare region grow function + TFunction::Pointer function = TFunction::New( ); + + // Prepare region grow filter + TFilter::Pointer filter = TFilter::New( ); + filter->SetInput( input_image ); + filter->SetGrowingFunction( function ); + filter->SetNeighborhoodOrder( neighborhood_order ); + filter->SetOutsideValue( TPixel( 0 ) ); + filter->SetInsideValue( std::numeric_limits< TPixel >::max( ) ); + filter->StopAtOneFrontOff( ); + + // Associate seed + TImage::PointType pnt; + TImage::IndexType idx; + viewer.GetSeed( pnt, 0 ); + if( input_image->TransformPhysicalPointToIndex( pnt, idx ) ) + filter->AddSeed( idx, 0 ); + function->SetLowerThreshold( input_image->GetPixel( idx ) ); + function->SetUpperThreshold( input_image->GetPixel( idx ) ); + + // Prepare graphical debugger + typedef fpa::VTK::Image2DObserver< TFilter, vtkRenderWindow > TDebugger; + TDebugger::Pointer debugger = TDebugger::New( ); + debugger->SetRenderWindow( viewer.Window ); + debugger->SetRenderPercentage( 0.01 ); + filter->AddObserver( itk::AnyEvent( ), debugger ); + filter->ThrowEventsOn( ); + + // Go! + filter->Update( ); + + // Some more interaction and finish + viewer.Start( ); + return( 0 ); +} + +// eof - $RCSfile$ diff --git a/appli/examples/example_Image_RegionGrow_ConnectedRGBPixels.cxx b/appli/examples/example_Image_RegionGrow_ConnectedRGBPixels.cxx new file mode 100644 index 0000000..0dc0137 --- /dev/null +++ b/appli/examples/example_Image_RegionGrow_ConnectedRGBPixels.cxx @@ -0,0 +1,100 @@ +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include + +#include "fpa_Utility.h" + +// ------------------------------------------------------------------------- +const unsigned int Dim = 2; +typedef unsigned char TPixel; +typedef itk::Image< itk::RGBPixel< TPixel >, Dim > TColorImage; +typedef itk::Image< TPixel, Dim > TImage; + +// ------------------------------------------------------------------------- +int main( int argc, char* argv[] ) +{ + if( argc < 3 ) + { + std::cerr + << "Usage: " << argv[ 0 ] + << " input_image neighborhood_order" + << std::endl; + return( 1 ); + + } // fi + std::string input_image_fn = argv[ 1 ]; + unsigned int neighborhood_order = std::atoi( argv[ 2 ] ); + + // Read image + TColorImage::Pointer input_image; + std::string err = fpa_Utility::ReadImage( input_image, input_image_fn ); + if( err != "" ) + { + std::cerr << err << std::endl; + return( 1 ); + + } // fi + + // Show image and wait for, at least, one seed + itk::ImageToVTKImageFilter< TColorImage >::Pointer vtk_input_image = + itk::ImageToVTKImageFilter< TColorImage >::New( ); + vtk_input_image->SetInput( input_image ); + vtk_input_image->Update( ); + + fpa_Utility::Viewer2DWithSeeds viewer; + viewer.SetImage( vtk_input_image->GetOutput( ) ); + while( viewer.GetNumberOfSeeds( ) == 0 ) + viewer.Start( ); + + // Region growing types + typedef fpa::Image::RegionGrow< TColorImage, TImage > TFilter; + typedef fpa::Image::Functors:: + RegionGrowThresholdFunction< TColorImage > TFunction; + + // Prepare region grow function + TFunction::Pointer function = TFunction::New( ); + + // Prepare region grow filter + TFilter::Pointer filter = TFilter::New( ); + filter->SetInput( input_image ); + filter->SetGrowingFunction( function ); + filter->SetNeighborhoodOrder( neighborhood_order ); + filter->SetOutsideValue( TPixel( 0 ) ); + filter->SetInsideValue( std::numeric_limits< TPixel >::max( ) ); + filter->StopAtOneFrontOff( ); + + // Associate seed + TImage::PointType pnt; + TImage::IndexType idx; + viewer.GetSeed( pnt, 0 ); + if( input_image->TransformPhysicalPointToIndex( pnt, idx ) ) + filter->AddSeed( idx, 0 ); + function->SetLowerThreshold( input_image->GetPixel( idx ) ); + function->SetUpperThreshold( input_image->GetPixel( idx ) ); + + // Prepare graphical debugger + typedef fpa::VTK::Image2DObserver< TFilter, vtkRenderWindow > TDebugger; + TDebugger::Pointer debugger = TDebugger::New( ); + debugger->SetRenderWindow( viewer.Window ); + debugger->SetRenderPercentage( 0.01 ); + filter->AddObserver( itk::AnyEvent( ), debugger ); + filter->ThrowEventsOn( ); + + // Go! + filter->Update( ); + + // Some more interaction and finish + viewer.Start( ); + return( 0 ); +} + +// eof - $RCSfile$ diff --git a/appli/examples/example_IncrementalRegionGrow_Thresholds.cxx b/appli/examples/example_IncrementalRegionGrow_Thresholds.cxx new file mode 100644 index 0000000..47affc1 --- /dev/null +++ b/appli/examples/example_IncrementalRegionGrow_Thresholds.cxx @@ -0,0 +1,164 @@ +#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 float TInputPixel; +typedef float TOutputPixel; + +typedef itk::Image< TInputPixel, Dim > TInputImage; +typedef itk::Image< TOutputPixel, Dim > TOutputImage; +typedef itk::ImageToVTKImageFilter< TInputImage > TVTKInputImage; + +// ------------------------------------------------------------------------- +int main( int argc, char* argv[] ) +{ + if( argc < 8 ) + { + std::cerr + << "Usage: " << argv[ 0 ] + << " input_image input_seeds output_image" + << " neighborhood_order stop_at_one_front" + << " init_seed end_seed" + << std::endl; + return( 1 ); + + } // fi + std::string input_image_fn = argv[ 1 ]; + std::string input_seeds_fn = argv[ 2 ]; + std::string output_image_fn = argv[ 3 ]; + unsigned int neighborhood_order = std::atoi( argv[ 4 ] ); + bool stop_at_one_front = ( std::atoi( argv[ 5 ] ) != 0 ); + unsigned int init_seed = std::atoi( argv[ 6 ] ); + unsigned int end_seed = std::atoi( argv[ 7 ] ); + + // Read image + itk::ImageFileReader< TInputImage >::Pointer input_image_reader = + itk::ImageFileReader< TInputImage >::New( ); + input_image_reader->SetFileName( input_image_fn ); + try + { + input_image_reader->Update( ); + } + catch( itk::ExceptionObject& err ) + { + std::cerr + << "Error while reading image from " << input_image_fn << ": " + << err << std::endl; + return( 1 ); + + } // yrt + TInputImage::ConstPointer input_image = input_image_reader->GetOutput( ); + 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( 600, 600 ); + view.SetImage( vtk_input_image->GetOutput( ) ); + + // Allow some interaction + view.Render( ); + view.Start( ); + + // Prepare region grow filter and cost function + typedef fpa::Image::Dijkstra< TInputImage, TOutputImage > TFilter; + typedef fpa::Image::Functors:: + ImageAbsoluteDifferenceCostFunction< TFilter::TInputImage, TFilter::TResult > + TCost; + + TCost::Pointer cost = TCost::New( ); + + TFilter::Pointer filter = TFilter::New( ); + filter->SetInput( input_image ); + filter->SetCostFunction( cost ); + filter->SetConversionFunction( NULL ); + filter->SetNeighborhoodOrder( neighborhood_order ); + filter->SetStopAtOneFront( stop_at_one_front ); + + // Get user-given seeds + std::ifstream input_seeds_str( input_seeds_fn.c_str( ) ); + if( !input_seeds_str ) + { + std::cerr << "Error opening \"" << input_seeds_fn << "\"" << std::endl; + return( 1 ); + + } // fi + + unsigned int nSeeds; + input_seeds_str >> nSeeds; + std::vector< TInputImage::IndexType > input_seeds; + for( unsigned int s = 0; s < nSeeds; s++ ) + { + TInputImage::IndexType idx; + input_seeds_str >> idx[ 0 ] >> idx[ 1 ] >> idx[ 2 ]; + input_seeds.push_back( idx ); + + } // rof + input_seeds_str.close( ); + + filter->AddSeed( input_seeds[ init_seed ], 0 ); + filter->AddSeed( input_seeds[ end_seed ], 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! + filter->Update( ); + + // 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 ); +} + +// eof - $RCSfile$ diff --git a/appli/examples/fpa_Utility.h b/appli/examples/fpa_Utility.h new file mode 100644 index 0000000..4cdf521 --- /dev/null +++ b/appli/examples/fpa_Utility.h @@ -0,0 +1,157 @@ +#ifndef __FPA__UTILITY__H__ +#define __FPA__UTILITY__H__ + +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace fpa_Utility +{ + /** + */ + struct Viewer2DWithSeeds + { + vtkSmartPointer< vtkImageData > Image; + vtkSmartPointer< vtkImageActor > ImageActor; + vtkSmartPointer< vtkRenderer > Renderer; + vtkSmartPointer< vtkRenderWindow > Window; + vtkSmartPointer< vtkInteractorStyleImage > Style; + vtkSmartPointer< vtkRenderWindowInteractor > Interactor; + vtkSmartPointer< vtkPointHandleRepresentation3D > Handle; + vtkSmartPointer< vtkSeedRepresentation > Representation; + vtkSmartPointer< vtkSeedWidget > Widget; + + Viewer2DWithSeeds( ) + { + this->ImageActor = vtkSmartPointer< vtkImageActor >::New( ); + this->Renderer = vtkSmartPointer< vtkRenderer >::New( ); + this->Window = vtkSmartPointer< vtkRenderWindow >::New( ); + this->Style = vtkSmartPointer< vtkInteractorStyleImage >::New( ); + this->Interactor = vtkSmartPointer< vtkRenderWindowInteractor >::New( ); + this->Handle = vtkSmartPointer< vtkPointHandleRepresentation3D >::New( ); + this->Representation = vtkSmartPointer< vtkSeedRepresentation >::New( ); + this->Widget = vtkSmartPointer< vtkSeedWidget >::New( ); + + this->Renderer->SetBackground( 0.1, 0.2, 0.7 ); + this->Window->SetSize( 600, 600 ); + this->Window->AddRenderer( this->Renderer ); + this->Interactor->SetInteractorStyle( this->Style ); + this->Window->SetInteractor( this->Interactor ); + this->Handle->GetProperty( )->SetColor( 1, 0, 0 ); + this->Representation->SetHandleRepresentation( this->Handle ); + this->Widget->SetInteractor( this->Interactor ); + this->Widget->SetRepresentation( this->Representation ); + } + void SetImage( vtkImageData* image ) + { + this->Image = image; + this->ImageActor->SetInputData( this->Image ); + this->Renderer->AddActor( this->ImageActor ); + + // Correct camera due to the loaded image + vtkCamera* camera = this->Renderer->GetActiveCamera( ); + camera->SetViewUp( 0, -1, 0 ); + camera->SetPosition( 0, 0, -1 ); + camera->SetFocalPoint( 0, 0, 0 ); + + // Prepare visualization + this->Interactor->Initialize( ); + this->Renderer->ResetCamera( ); + } + void Render( ) + { + this->Window->Render( ); + } + void Start( ) + { + this->Window->Render( ); + this->Widget->On( ); + this->Interactor->Start( ); + } + unsigned long GetNumberOfSeeds( ) const + { + return( this->Representation->GetNumberOfSeeds( ) ); + } + + template< class P > + bool GetSeed( P& seed, unsigned long i ) + { + if( i < this->Representation->GetNumberOfSeeds( ) ) + { + double pos[ 3 ]; + this->Representation->GetSeedWorldPosition( i, pos ); + + seed[ 0 ] = ( typename P::ValueType )( pos[ 0 ] ); + seed[ 1 ] = ( typename P::ValueType )( pos[ 1 ] ); + + return( true ); + } + else + return( false ); + } + }; + + // ----------------------------------------------------------------------- + template< class Ip > + std::string ReadImage( Ip& image, const std::string& fname ) + { + typename itk::ImageFileReader< typename Ip::ObjectType >::Pointer r = + itk::ImageFileReader< typename Ip::ObjectType >::New( ); + r->SetFileName( fname ); + try + { + r->Update( ); + } + catch( itk::ExceptionObject& err ) + { + std::stringstream str; + str << "Error while reading image from " << fname << ": " << err; + return( str.str( ) ); + + } // yrt + image = r->GetOutput( ); + image->DisconnectPipeline( ); + return( "" ); + } + + // ----------------------------------------------------------------------- + template< class I > + std::string SaveImage( const I* image, const std::string& fname ) + { + typename itk::ImageFileWriter< I >::Pointer w = + itk::ImageFileWriter< I >::New( ); + w->SetInput( image ); + w->SetFileName( fname ); + try + { + w->Update( ); + } + catch( itk::ExceptionObject& err ) + { + std::stringstream str; + str << "Error while reading image from " << fname << ": " << err; + return( str.str( ) ); + + } // yrt + return( "" ); + } + +} // ecapseman + +#endif // __FPA__UTILITY__H__ + +// eof - $RCSfile$ diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt index 1ddfbb5..6973e32 100644 --- a/lib/CMakeLists.txt +++ b/lib/CMakeLists.txt @@ -39,7 +39,11 @@ SET( SET( ${LIB_NAME}_LINK_LIBRARIES ${ITK_LIBRARIES} - ${VTK_LIBRARIES} + vtkFiltersSources + vtkInteractionWidgets + vtkRenderingVolumeOpenGL + vtkRenderingFreeTypeOpenGL + vtkIOMPIImage ) ## ===================== @@ -61,8 +65,6 @@ GENERATE_EXPORT_HEADER( TARGET_LINK_LIBRARIES( ${LIB_NAME} ${${LIB_NAME}_LINK_LIBRARIES} - ${ITK_LIBRARIES} - vtkInteractionWidgets ) ## eof - $RCSfile$ diff --git a/lib/fpa/Base/Algorithm.h b/lib/fpa/Base/Algorithm.h index cc8497d..132c610 100644 --- a/lib/fpa/Base/Algorithm.h +++ b/lib/fpa/Base/Algorithm.h @@ -20,12 +20,13 @@ namespace fpa * @param V Vertex type. * @param C Vertex value type. * @param R Result value type. + * @param S Space type where vertices are. * @param VC Vertex lexicographical compare. * @param B Base class for this algorithm. It should be any itk-based * filter (itk::ProcessObject). * */ - template< class V, class C, class R, class VC, class B > + template< class V, class C, class R, class S, class VC, class B > class Algorithm : public B { @@ -38,6 +39,7 @@ namespace fpa typedef V TVertex; typedef C TValue; typedef R TResult; + typedef S TSpace; typedef VC TVertexCompare; fpa_Base_NewEvent( TStartEvent ); diff --git a/lib/fpa/Base/Algorithm.hxx b/lib/fpa/Base/Algorithm.hxx index dbcdc60..aa1c283 100644 --- a/lib/fpa/Base/Algorithm.hxx +++ b/lib/fpa/Base/Algorithm.hxx @@ -5,8 +5,8 @@ #include // ------------------------------------------------------------------------- -template< class V, class C, class R, class VC, class B > -fpa::Base::Algorithm< V, C, R, VC, B >::_TNode:: +template< class V, class C, class R, class S, class VC, class B > +fpa::Base::Algorithm< V, C, R, S, VC, B >::_TNode:: _TNode( ) : Result( TResult( 0 ) ), FrontId( -1 ), @@ -15,16 +15,16 @@ _TNode( ) } // ------------------------------------------------------------------------- -template< class V, class C, class R, class VC, class B > -fpa::Base::Algorithm< V, C, R, VC, B >::_TNode:: +template< class V, class C, class R, class S, class VC, class B > +fpa::Base::Algorithm< V, C, R, S, VC, B >::_TNode:: ~_TNode( ) { } // ------------------------------------------------------------------------- -template< class V, class C, class R, class VC, class B > -typename fpa::Base::Algorithm< V, C, R, VC, B >:: -TMinimumSpanningTree* fpa::Base::Algorithm< V, C, R, VC, B >:: +template< class V, class C, class R, class S, class VC, class B > +typename fpa::Base::Algorithm< V, C, R, S, VC, B >:: +TMinimumSpanningTree* fpa::Base::Algorithm< V, C, R, S, VC, B >:: GetMinimumSpanningTree( ) { return( @@ -35,9 +35,9 @@ GetMinimumSpanningTree( ) } // ------------------------------------------------------------------------- -template< class V, class C, class R, class VC, class B > -const typename fpa::Base::Algorithm< V, C, R, VC, B >:: -TMinimumSpanningTree* fpa::Base::Algorithm< V, C, R, VC, B >:: +template< class V, class C, class R, class S, class VC, class B > +const typename fpa::Base::Algorithm< V, C, R, S, VC, B >:: +TMinimumSpanningTree* fpa::Base::Algorithm< V, C, R, S, VC, B >:: GetMinimumSpanningTree( ) const { return( @@ -48,8 +48,8 @@ GetMinimumSpanningTree( ) const } // ------------------------------------------------------------------------- -template< class V, class C, class R, class VC, class B > -void fpa::Base::Algorithm< V, C, R, VC, B >:: +template< class V, class C, class R, class S, class VC, class B > +void fpa::Base::Algorithm< V, C, R, S, VC, B >:: GraftMinimumSpanningTree( itk::DataObject* obj ) { TMinimumSpanningTree* mst = dynamic_cast< TMinimumSpanningTree* >( obj ); @@ -58,8 +58,8 @@ GraftMinimumSpanningTree( itk::DataObject* obj ) } // ------------------------------------------------------------------------- -template< class V, class C, class R, class VC, class B > -void fpa::Base::Algorithm< V, C, R, VC, B >:: +template< class V, class C, class R, class S, class VC, class B > +void fpa::Base::Algorithm< V, C, R, S, VC, B >:: InvokeEvent( const itk::EventObject& e ) { if( this->m_ThrowEvents ) @@ -67,8 +67,8 @@ InvokeEvent( const itk::EventObject& e ) } // ------------------------------------------------------------------------- -template< class V, class C, class R, class VC, class B > -void fpa::Base::Algorithm< V, C, R, VC, B >:: +template< class V, class C, class R, class S, class VC, class B > +void fpa::Base::Algorithm< V, C, R, S, VC, B >:: InvokeEvent( const itk::EventObject& e ) const { if( this->m_ThrowEvents ) @@ -76,8 +76,8 @@ InvokeEvent( const itk::EventObject& e ) const } // ------------------------------------------------------------------------- -template< class V, class C, class R, class VC, class B > -void fpa::Base::Algorithm< V, C, R, VC, B >:: +template< class V, class C, class R, class S, class VC, class B > +void fpa::Base::Algorithm< V, C, R, S, VC, B >:: AddSeed( const TVertex& s, const TResult& r ) { _TNode ns; @@ -91,17 +91,17 @@ AddSeed( const TVertex& s, const TResult& r ) } // ------------------------------------------------------------------------- -template< class V, class C, class R, class VC, class B > -const typename fpa::Base::Algorithm< V, C, R, VC, B >:: -TVertex& fpa::Base::Algorithm< V, C, R, VC, B >:: +template< class V, class C, class R, class S, class VC, class B > +const typename fpa::Base::Algorithm< V, C, R, S, VC, B >:: +TVertex& fpa::Base::Algorithm< V, C, R, S, VC, B >:: GetSeed( const unsigned int& id ) const { return( this->m_SeedVertices[ id ] ); } // ------------------------------------------------------------------------- -template< class V, class C, class R, class VC, class B > -void fpa::Base::Algorithm< V, C, R, VC, B >:: +template< class V, class C, class R, class S, class VC, class B > +void fpa::Base::Algorithm< V, C, R, S, VC, B >:: ClearSeeds( ) { this->m_Seeds.clear( ); @@ -110,16 +110,16 @@ ClearSeeds( ) } // ------------------------------------------------------------------------- -template< class V, class C, class R, class VC, class B > -unsigned long fpa::Base::Algorithm< V, C, R, VC, B >:: +template< class V, class C, class R, class S, class VC, class B > +unsigned long fpa::Base::Algorithm< V, C, R, S, VC, B >:: GetNumberOfSeeds( ) const { return( this->m_Seeds.size( ) ); } // ------------------------------------------------------------------------- -template< class V, class C, class R, class VC, class B > -fpa::Base::Algorithm< V, C, R, VC, B >:: +template< class V, class C, class R, class S, class VC, class B > +fpa::Base::Algorithm< V, C, R, S, VC, B >:: Algorithm( ) : Superclass( ), m_ThrowEvents( false ), @@ -133,15 +133,15 @@ Algorithm( ) } // ------------------------------------------------------------------------- -template< class V, class C, class R, class VC, class B > -fpa::Base::Algorithm< V, C, R, VC, B >:: +template< class V, class C, class R, class S, class VC, class B > +fpa::Base::Algorithm< V, C, R, S, VC, B >:: ~Algorithm( ) { } // ------------------------------------------------------------------------- -template< class V, class C, class R, class VC, class B > -void fpa::Base::Algorithm< V, C, R, VC, B >:: +template< class V, class C, class R, class S, class VC, class B > +void fpa::Base::Algorithm< V, C, R, S, VC, B >:: GenerateData( ) { unsigned long N = this->m_Seeds.size( ); @@ -163,8 +163,8 @@ GenerateData( ) } // ------------------------------------------------------------------------- -template< class V, class C, class R, class VC, class B > -void fpa::Base::Algorithm< V, C, R, VC, B >:: +template< class V, class C, class R, class S, class VC, class B > +void fpa::Base::Algorithm< V, C, R, S, VC, B >:: _Loop( ) { this->InvokeEvent( TStartLoopEvent( ) ); @@ -236,36 +236,36 @@ _Loop( ) } // ------------------------------------------------------------------------- -template< class V, class C, class R, class VC, class B > -void fpa::Base::Algorithm< V, C, R, VC, B >:: +template< class V, class C, class R, class S, class VC, class B > +void fpa::Base::Algorithm< V, C, R, S, VC, B >:: _BeforeGenerateData( ) { } // ------------------------------------------------------------------------- -template< class V, class C, class R, class VC, class B > -void fpa::Base::Algorithm< V, C, R, VC, B >:: +template< class V, class C, class R, class S, class VC, class B > +void fpa::Base::Algorithm< V, C, R, S, VC, B >:: _AfterGenerateData( ) { } // ------------------------------------------------------------------------- -template< class V, class C, class R, class VC, class B > -void fpa::Base::Algorithm< V, C, R, VC, B >:: +template< class V, class C, class R, class S, class VC, class B > +void fpa::Base::Algorithm< V, C, R, S, VC, B >:: _BeforeLoop( ) { } // ------------------------------------------------------------------------- -template< class V, class C, class R, class VC, class B > -void fpa::Base::Algorithm< V, C, R, VC, B >:: +template< class V, class C, class R, class S, class VC, class B > +void fpa::Base::Algorithm< V, C, R, S, VC, B >:: _AfterLoop( ) { } // ------------------------------------------------------------------------- -template< class V, class C, class R, class VC, class B > -bool fpa::Base::Algorithm< V, C, R, VC, B >:: +template< class V, class C, class R, class S, class VC, class B > +bool fpa::Base::Algorithm< V, C, R, S, VC, B >:: _UpdateCollisions( const TVertex& a, const TVertex& b ) { bool ret = false; @@ -322,17 +322,17 @@ _UpdateCollisions( const TVertex& a, const TVertex& b ) } // ------------------------------------------------------------------------- -template< class V, class C, class R, class VC, class B > -bool fpa::Base::Algorithm< V, C, R, VC, B >:: +template< class V, class C, class R, class S, class VC, class B > +bool fpa::Base::Algorithm< V, C, R, S, VC, B >:: _NeedToStop( ) const { return( false ); } // ------------------------------------------------------------------------- -template< class V, class C, class R, class VC, class B > -typename fpa::Base::Algorithm< V, C, R, VC, B >:: -_TNode& fpa::Base::Algorithm< V, C, R, VC, B >:: +template< class V, class C, class R, class S, class VC, class B > +typename fpa::Base::Algorithm< V, C, R, S, VC, B >:: +_TNode& fpa::Base::Algorithm< V, C, R, S, VC, B >:: _Node( const TVertex& v ) { typename _TNodes::iterator vIt = this->m_Marks.find( v ); @@ -351,9 +351,9 @@ _Node( const TVertex& v ) } // ------------------------------------------------------------------------- -template< class V, class C, class R, class VC, class B > -const typename fpa::Base::Algorithm< V, C, R, VC, B >:: -_TNode& fpa::Base::Algorithm< V, C, R, VC, B >:: +template< class V, class C, class R, class S, class VC, class B > +const typename fpa::Base::Algorithm< V, C, R, S, VC, B >:: +_TNode& fpa::Base::Algorithm< V, C, R, S, VC, B >:: _Node( const TVertex& v ) const { typename _TNodes::const_iterator vIt = this->m_Marks.find( v ); @@ -361,24 +361,24 @@ _Node( const TVertex& v ) const } // ------------------------------------------------------------------------- -template< class V, class C, class R, class VC, class B > -void fpa::Base::Algorithm< V, C, R, VC, B >:: +template< class V, class C, class R, class S, class VC, class B > +void fpa::Base::Algorithm< V, C, R, S, VC, B >:: _InitMarks( ) { this->m_Marks.clear( ); } // ------------------------------------------------------------------------- -template< class V, class C, class R, class VC, class B > -void fpa::Base::Algorithm< V, C, R, VC, B >:: +template< class V, class C, class R, class S, class VC, class B > +void fpa::Base::Algorithm< V, C, R, S, VC, B >:: _Mark( const TVertex& v, const _TNode& node ) { this->m_Marks[ v ] = node; } // ------------------------------------------------------------------------- -template< class V, class C, class R, class VC, class B > -void fpa::Base::Algorithm< V, C, R, VC, B >:: +template< class V, class C, class R, class S, class VC, class B > +void fpa::Base::Algorithm< V, C, R, S, VC, B >:: _InitQueue( ) { this->_QueueClear( ); diff --git a/lib/fpa/Base/Dijkstra.h b/lib/fpa/Base/Dijkstra.h index 602608e..69fe86a 100644 --- a/lib/fpa/Base/Dijkstra.h +++ b/lib/fpa/Base/Dijkstra.h @@ -14,24 +14,26 @@ namespace fpa * @param V Vertex type. * @param C Vertex value type. * @param R Result value type. + * @param S Space type where vertices are. * @param VC Vertex lexicographical compare. * @param B Base class for this algorithm. It should be any itk-based * filter (itk::ProcessObject). * */ - template< class V, class C, class R, class VC, class B > + template< class V, class C, class R, class S, class VC, class B > class Dijkstra - : public Algorithm< V, C, R, VC, B > + : public Algorithm< V, C, R, S, VC, B > { public: typedef Dijkstra Self; - typedef Algorithm< V, C, R, VC, B > Superclass; + typedef Algorithm< V, C, R, S, VC, B > Superclass; typedef itk::SmartPointer< Self > Pointer; typedef itk::SmartPointer< const Self > ConstPointer; typedef typename Superclass::TVertex TVertex; typedef typename Superclass::TValue TValue; typedef typename Superclass::TResult TResult; + typedef typename Superclass::TSpace TSpace; typedef typename Superclass::TVertexCompare TVertexCompare; typedef typename Superclass::TMinimumSpanningTree TMinimumSpanningTree; @@ -69,6 +71,10 @@ namespace fpa public: itkTypeMacro( Dijkstra, Algorithm ); + itkBooleanMacro( LocalCosts ); + itkGetConstMacro( LocalCosts, bool ); + itkSetMacro( LocalCosts, bool ); + protected: Dijkstra( ); virtual ~Dijkstra( ); @@ -92,6 +98,7 @@ namespace fpa Self& operator=( const Self& other ); protected: + bool m_LocalCosts; _TQueue m_Queue; }; diff --git a/lib/fpa/Base/Dijkstra.hxx b/lib/fpa/Base/Dijkstra.hxx index 2a2ccf5..25d5650 100644 --- a/lib/fpa/Base/Dijkstra.hxx +++ b/lib/fpa/Base/Dijkstra.hxx @@ -4,23 +4,24 @@ #include // ------------------------------------------------------------------------- -template< class V, class C, class R, class VC, class B > -fpa::Base::Dijkstra< V, C, R, VC, B >:: +template< class V, class C, class R, class S, class VC, class B > +fpa::Base::Dijkstra< V, C, R, S, VC, B >:: Dijkstra( ) - : Superclass( ) + : Superclass( ), + m_LocalCosts( false ) { } // ------------------------------------------------------------------------- -template< class V, class C, class R, class VC, class B > -fpa::Base::Dijkstra< V, C, R, VC, B >:: +template< class V, class C, class R, class S, class VC, class B > +fpa::Base::Dijkstra< V, C, R, S, VC, B >:: ~Dijkstra( ) { } // ------------------------------------------------------------------------- -template< class V, class C, class R, class VC, class B > -bool fpa::Base::Dijkstra< V, C, R, VC, B >:: +template< class V, class C, class R, class S, class VC, class B > +bool fpa::Base::Dijkstra< V, C, R, S, VC, B >:: _ComputeNeighborResult( TResult& result, const TVertex& neighbor, const TVertex& parent ) const @@ -32,7 +33,7 @@ _ComputeNeighborResult( if( result >= TResult( 0 ) ) { _TNode pn = this->_Node( parent ); - if( pn.Label == Self::AliveLabel ) + if( pn.Label == Self::AliveLabel && !this->m_LocalCosts ) result += pn.Result; return( true ); } @@ -41,16 +42,16 @@ _ComputeNeighborResult( } // ------------------------------------------------------------------------- -template< class V, class C, class R, class VC, class B > -bool fpa::Base::Dijkstra< V, C, R, VC, B >:: +template< class V, class C, class R, class S, class VC, class B > +bool fpa::Base::Dijkstra< V, C, R, S, VC, B >:: _IsQueueEmpty( ) const { return( this->m_Queue.empty( ) ); } // ------------------------------------------------------------------------- -template< class V, class C, class R, class VC, class B > -void fpa::Base::Dijkstra< V, C, R, VC, B >:: +template< class V, class C, class R, class S, class VC, class B > +void fpa::Base::Dijkstra< V, C, R, S, VC, B >:: _QueuePush( const TVertex& v, const _TNode& n ) { _TQueueNode qn; @@ -61,8 +62,8 @@ _QueuePush( const TVertex& v, const _TNode& n ) } // ------------------------------------------------------------------------- -template< class V, class C, class R, class VC, class B > -void fpa::Base::Dijkstra< V, C, R, VC, B >:: +template< class V, class C, class R, class S, class VC, class B > +void fpa::Base::Dijkstra< V, C, R, S, VC, B >:: _QueuePop( TVertex& v, _TNode& n ) { _TQueueNode qn = this->m_Queue.front( ); @@ -73,8 +74,8 @@ _QueuePop( TVertex& v, _TNode& n ) } // ------------------------------------------------------------------------- -template< class V, class C, class R, class VC, class B > -void fpa::Base::Dijkstra< V, C, R, VC, B >:: +template< class V, class C, class R, class S, class VC, class B > +void fpa::Base::Dijkstra< V, C, R, S, VC, B >:: _QueueClear( ) { this->m_Queue.clear( ); diff --git a/lib/fpa/Base/Functors/TautologyFunction.h b/lib/fpa/Base/Functors/TautologyFunction.h index f79666d..d8eec46 100644 --- a/lib/fpa/Base/Functors/TautologyFunction.h +++ b/lib/fpa/Base/Functors/TautologyFunction.h @@ -11,7 +11,7 @@ namespace fpa { /** */ - template< class V > + template< class S, class V > class TautologyFunction : public itk::FunctionBase< V, bool > { @@ -21,12 +21,18 @@ namespace fpa typedef itk::SmartPointer< Self > Pointer; typedef itk::SmartPointer< const Self > ConstPointer; + typedef S TSpace; + typedef V TVertex; + public: itkNewMacro( Self ); itkTypeMacro( TautologyFunction, itkFunctionBase ); + itkGetConstObjectMacro( Space, TSpace ); + itkSetConstObjectMacro( Space, TSpace ); + public: - virtual bool Evaluate( const V& input ) const + virtual bool Evaluate( const TVertex& input ) const { return( true ); } protected: @@ -40,6 +46,9 @@ namespace fpa // Purposely not implemented TautologyFunction( const Self& ); void operator=( const Self& ); + + protected: + typename TSpace::ConstPointer m_Space; }; } // ecapseman diff --git a/lib/fpa/Base/IncrementalRegionGrow.h b/lib/fpa/Base/IncrementalRegionGrow.h new file mode 100644 index 0000000..7385f91 --- /dev/null +++ b/lib/fpa/Base/IncrementalRegionGrow.h @@ -0,0 +1,85 @@ +#ifndef __FPA__BASE__INCREMENTALREGIONGROW__H__ +#define __FPA__BASE__INCREMENTALREGIONGROW__H__ + +#include +#include +#include + +namespace fpa +{ + namespace Base + { + /** + * Region grow is a front propagation with no costs. + */ + template< class V, class R, class VV, class VC, class B > + class IncrementalRegionGrow + : public RegionGrow< V, R, VV, VC, B > + { + public: + /// Standard class typdedefs + typedef IncrementalRegionGrow Self; + typedef RegionGrow< V, R, VV, VC, B > Superclass; + typedef itk::SmartPointer< Self > Pointer; + typedef itk::SmartPointer< const Self > ConstPointer; + + typedef typename Superclass::TVertex TVertex; + typedef typename Superclass::TValue TValue; + typedef typename Superclass::TResult TResult; + typedef typename Superclass::TVertexCompare TVertexCompare; + typedef typename Superclass::TGrowingFunction TGrowingFunction; + + typedef std::vector< typename TGrowingFunction::Pointer > TFunctions; + typedef std::vector< unsigned long > TVolumes; + + protected: + typedef typename Superclass::_TVertices _TVertices; + typedef typename Superclass::_TCollision _TCollision; + typedef typename Superclass::_TCollisionsRow _TCollisionsRow; + typedef typename Superclass::_TCollisions _TCollisions; + typedef typename Superclass::_TNode _TNode; + typedef typename Superclass::_TNodes _TNodes; + typedef typename Superclass::_TQueue _TQueue; + + public: + itkTypeMacro( IncrementalRegionGrow, RegionGrow ); + + public: + TGrowingFunction* GetGrowingFunction( unsigned int i ); + const TGrowingFunction* GetGrowingFunction( unsigned int i ) const; + unsigned long GetGrowingFunctionVolume( unsigned int i ) const; + unsigned int GetNumberOfGrowingFunctions( ) const; + void ClearGrowingFunctions( ); + unsigned int AddGrowingFunction( TGrowingFunction* function ); + + protected: + IncrementalRegionGrow( ); + virtual ~IncrementalRegionGrow( ); + + virtual void _BeforeGenerateData( ); + virtual void _AfterLoop( ); + virtual void _Loop( ); + virtual bool _CheckMembership( const TVertex& v ) const; + + private: + // Purposely not implemented. + IncrementalRegionGrow( const Self& ); + void operator=( const Self& ); + + protected: + mutable _TQueue m_AuxiliaryQueue; + + TFunctions m_Functions; + TVolumes m_Volumes; + unsigned int m_ActualFunction; + }; + + } // ecapseman + +} // ecapseman + +#include + +#endif // __FPA__BASE__INCREMENTALREGIONGROW__H__ + +// eof - $RCSfile$ diff --git a/lib/fpa/Base/IncrementalRegionGrow.hxx b/lib/fpa/Base/IncrementalRegionGrow.hxx new file mode 100644 index 0000000..d5d9447 --- /dev/null +++ b/lib/fpa/Base/IncrementalRegionGrow.hxx @@ -0,0 +1,154 @@ +#ifndef __FPA__BASE__INCREMENTALREGIONGROW__HXX__ +#define __FPA__BASE__INCREMENTALREGIONGROW__HXX__ + +// ------------------------------------------------------------------------- +template< class V, class R, class VV, class VC, class B > +typename fpa::Base::IncrementalRegionGrow< V, R, VV, VC, B >:: +TGrowingFunction* fpa::Base::IncrementalRegionGrow< V, R, VV, VC, B >:: +GetGrowingFunction( unsigned int i ) +{ + if( i < this->m_Functions.size( ) ) + return( this->m_Functions[ i ] ); + else + return( NULL ); +} + +// ------------------------------------------------------------------------- +template< class V, class R, class VV, class VC, class B > +const typename fpa::Base::IncrementalRegionGrow< V, R, VV, VC, B >:: +TGrowingFunction* fpa::Base::IncrementalRegionGrow< V, R, VV, VC, B >:: +GetGrowingFunction( unsigned int i ) const +{ + if( i < this->m_Functions.size( ) ) + return( this->m_Functions[ i ] ); + else + return( NULL ); +} + +// ------------------------------------------------------------------------- +template< class V, class R, class VV, class VC, class B > +unsigned long fpa::Base::IncrementalRegionGrow< V, R, VV, VC, B >:: +GetGrowingFunctionVolume( unsigned int i ) const +{ + if( i < this->m_Volumes.size( ) ) + return( this->m_Volumes[ i ] ); + else + return( NULL ); +} + +// ------------------------------------------------------------------------- +template< class V, class R, class VV, class VC, class B > +unsigned int fpa::Base::IncrementalRegionGrow< V, R, VV, VC, B >:: +GetNumberOfGrowingFunctions( ) const +{ + return( this->m_Functions.size( ) ); +} + +// ------------------------------------------------------------------------- +template< class V, class R, class VV, class VC, class B > +void fpa::Base::IncrementalRegionGrow< V, R, VV, VC, B >:: +ClearGrowingFunctions( ) +{ + this->m_Functions.clear( ); + this->m_Volumes.clear( ); + this->Modified( ); +} + +// ------------------------------------------------------------------------- +template< class V, class R, class VV, class VC, class B > +unsigned int fpa::Base::IncrementalRegionGrow< V, R, VV, VC, B >:: +AddGrowingFunction( TGrowingFunction* function ) +{ + this->m_Functions.push_back( function ); + this->m_Volumes.push_back( 0 ); + this->Modified( ); +} + +// ------------------------------------------------------------------------- +template< class V, class R, class VV, class VC, class B > +fpa::Base::IncrementalRegionGrow< V, R, VV, VC, B >:: +IncrementalRegionGrow( ) + : Superclass( ) +{ +} + +// ------------------------------------------------------------------------- +template< class V, class R, class VV, class VC, class B > +fpa::Base::IncrementalRegionGrow< V, R, VV, VC, B >:: +~IncrementalRegionGrow( ) +{ +} + +// ------------------------------------------------------------------------- +template< class V, class R, class VV, class VC, class B > +void fpa::Base::IncrementalRegionGrow< V, R, VV, VC, B >:: +_BeforeGenerateData( ) +{ + this->Superclass::_BeforeGenerateData( ); + this->m_ActualFunction = 0; +} + +// ------------------------------------------------------------------------- +template< class V, class R, class VV, class VC, class B > +void fpa::Base::IncrementalRegionGrow< V, R, VV, VC, B >:: +_AfterLoop( ) +{ + /* TODO + this->Superclass::_AfterLoop( ); + + // Replace queue + this->_QueueClear( ); + while( !( this->m_AuxiliaryQueue.empty( ) ) ) + { + // Get node + _TNode node = this->m_AuxiliaryQueue.front( ); + this->m_AuxiliaryQueue.pop( ); + this->_QueuePush( node ); + + // Unmark it + typename _TMarks::iterator mIt = this->m_Marks.find( node.Vertex ); + if( mIt != this->m_Marks.end( ) ) + this->m_Marks.erase( mIt ); + + } // elihw + + // Move to next function + this->m_ActualFunction++; + */ +} + +// ------------------------------------------------------------------------- +template< class V, class R, class VV, class VC, class B > +void fpa::Base::IncrementalRegionGrow< V, R, VV, VC, B >:: +_Loop( ) +{ + while( this->m_ActualFunction < this->m_Functions.size( ) ) + this->Superclass::_Loop( ); +} + +// ------------------------------------------------------------------------- +template< class V, class R, class VV, class VC, class B > +bool fpa::Base::IncrementalRegionGrow< V, R, VV, VC, B >:: +_CheckMembership( const TVertex& v ) const +{ + /* TODO + + if( this->m_ActualFunction < this->m_Functions.size( ) ) + { + bool ret = + this->m_Functions[ this->m_ActualFunction ]->Evaluate( v ); + if( !ret ) + this->m_AuxiliaryQueue.push( n ); + else + this->m_Volumes[ this->m_ActualFunction ]++; + return( ret ); + } + else + return( false ); +*/ + return( false ); +} + +#endif // __FPA__BASE__INCREMENTALREGIONGROW__HXX__ + +// eof - $RCSfile$ diff --git a/lib/fpa/Base/RegionGrow.h b/lib/fpa/Base/RegionGrow.h index 0b5b797..b5ce46e 100644 --- a/lib/fpa/Base/RegionGrow.h +++ b/lib/fpa/Base/RegionGrow.h @@ -4,6 +4,7 @@ #include #include #include +#include namespace fpa { @@ -15,26 +16,30 @@ namespace fpa * @param V Vertex type. * @param C Vertex value type. * @param R Result value type. + * @param S Space type where vertices are. * @param VC Vertex lexicographical compare. * @param B Base class for this algorithm. It should be any itk-based * filter (itk::ProcessObject). * */ - template< class V, class C, class R, class VC, class B > + template< class V, class C, class R, class S, class VC, class B > class RegionGrow - : public Algorithm< V, C, R, VC, B > + : public Algorithm< V, C, R, S, VC, B > { public: typedef RegionGrow Self; - typedef Algorithm< V, C, R, VC, B > Superclass; + typedef Algorithm< V, C, R, S, VC, B > Superclass; typedef itk::SmartPointer< Self > Pointer; typedef itk::SmartPointer< const Self > ConstPointer; typedef typename Superclass::TVertex TVertex; typedef typename Superclass::TValue TValue; typedef typename Superclass::TResult TResult; + typedef typename Superclass::TSpace TSpace; typedef typename Superclass::TVertexCompare TVertexCompare; + typedef fpa::Base::Functors::TautologyFunction< S, V > TGrowingFunction; + protected: typedef typename Superclass::_TVertices _TVertices; typedef typename Superclass::_TCollision _TCollision; @@ -50,15 +55,18 @@ namespace fpa itkGetConstMacro( InsideValue, TResult ); itkGetConstMacro( OutsideValue, TResult ); + itkGetObjectMacro( GrowingFunction, TGrowingFunction ); + itkGetConstObjectMacro( GrowingFunction, TGrowingFunction ); itkSetMacro( InsideValue, TResult ); itkSetMacro( OutsideValue, TResult ); + itkSetObjectMacro( GrowingFunction, TGrowingFunction ); protected: RegionGrow( ); virtual ~RegionGrow( ); - virtual bool _CheckMembership( const TVertex& v ) const = 0; + virtual bool _CheckMembership( const TVertex& v ) const; // Results-related abstract methods virtual bool _ComputeNeighborResult( @@ -80,6 +88,8 @@ namespace fpa TResult m_InsideValue; TResult m_OutsideValue; _TQueue m_Queue; + + typename TGrowingFunction::Pointer m_GrowingFunction; }; } // ecapseman diff --git a/lib/fpa/Base/RegionGrow.hxx b/lib/fpa/Base/RegionGrow.hxx index f0c4512..1760ac1 100644 --- a/lib/fpa/Base/RegionGrow.hxx +++ b/lib/fpa/Base/RegionGrow.hxx @@ -2,8 +2,8 @@ #define __FPA__BASE__REGIONGROWING__HXX__ // ------------------------------------------------------------------------- -template< class V, class C, class R, class VC, class B > -fpa::Base::RegionGrow< V, C, R, VC, B >:: +template< class V, class C, class R, class S, class VC, class B > +fpa::Base::RegionGrow< V, C, R, S, VC, B >:: RegionGrow( ) : Superclass( ), m_InsideValue( TResult( 1 ) ), @@ -12,15 +12,26 @@ RegionGrow( ) } // ------------------------------------------------------------------------- -template< class V, class C, class R, class VC, class B > -fpa::Base::RegionGrow< V, C, R, VC, B >:: +template< class V, class C, class R, class S, class VC, class B > +fpa::Base::RegionGrow< V, C, R, S, VC, B >:: ~RegionGrow( ) { } // ------------------------------------------------------------------------- -template< class V, class C, class R, class VC, class B > -bool fpa::Base::RegionGrow< V, C, R, VC, B >:: +template< class V, class C, class R, class S, class VC, class B > +bool fpa::Base::RegionGrow< V, C, R, S, VC, B >:: +_CheckMembership( const TVertex& v ) const +{ + if( this->m_GrowingFunction.IsNotNull( ) ) + return( this->m_GrowingFunction->Evaluate( v ) ); + else + return( false ); +} + +// ------------------------------------------------------------------------- +template< class V, class C, class R, class S, class VC, class B > +bool fpa::Base::RegionGrow< V, C, R, S, VC, B >:: _ComputeNeighborResult( TResult& result, const TVertex& neighbor, const TVertex& parent ) const @@ -39,24 +50,24 @@ _ComputeNeighborResult( } // ------------------------------------------------------------------------- -template< class V, class C, class R, class VC, class B > -bool fpa::Base::RegionGrow< V, C, R, VC, B >:: +template< class V, class C, class R, class S, class VC, class B > +bool fpa::Base::RegionGrow< V, C, R, S, VC, B >:: _IsQueueEmpty( ) const { return( this->m_Queue.empty( ) ); } // ------------------------------------------------------------------------- -template< class V, class C, class R, class VC, class B > -void fpa::Base::RegionGrow< V, C, R, VC, B >:: +template< class V, class C, class R, class S, class VC, class B > +void fpa::Base::RegionGrow< V, C, R, S, VC, B >:: _QueuePush( const TVertex& v, const _TNode& n ) { this->m_Queue.push( std::pair< TVertex, _TNode >( v, n ) ); } // ------------------------------------------------------------------------- -template< class V, class C, class R, class VC, class B > -void fpa::Base::RegionGrow< V, C, R, VC, B >:: +template< class V, class C, class R, class S, class VC, class B > +void fpa::Base::RegionGrow< V, C, R, S, VC, B >:: _QueuePop( TVertex& v, _TNode& n ) { v = this->m_Queue.front( ).first; @@ -65,8 +76,8 @@ _QueuePop( TVertex& v, _TNode& n ) } // ------------------------------------------------------------------------- -template< class V, class C, class R, class VC, class B > -void fpa::Base::RegionGrow< V, C, R, VC, B >:: +template< class V, class C, class R, class S, class VC, class B > +void fpa::Base::RegionGrow< V, C, R, S, VC, B >:: _QueueClear( ) { while( this->m_Queue.size( ) > 0 ) diff --git a/lib/fpa/Base/UniqueValuesContainer.h b/lib/fpa/Base/UniqueValuesContainer.h index bc2b17c..eb554bb 100644 --- a/lib/fpa/Base/UniqueValuesContainer.h +++ b/lib/fpa/Base/UniqueValuesContainer.h @@ -49,6 +49,8 @@ namespace fpa { return( this->Get( ).begin( ) ); } ConstIterator End( ) const { return( this->Get( ).end( ) ); } + unsigned long Size( ) const + { return( this->Get( ).size( ) ); } protected: UniqueValuesContainer( ) diff --git a/lib/fpa/Image/Algorithm.h b/lib/fpa/Image/Algorithm.h index efb376b..9a44146 100644 --- a/lib/fpa/Image/Algorithm.h +++ b/lib/fpa/Image/Algorithm.h @@ -32,6 +32,7 @@ namespace fpa typedef typename Superclass::TVertex TVertex; typedef typename Superclass::TValue TValue; typedef typename Superclass::TResult TResult; + typedef typename Superclass::TSpace TSpace; typedef typename Superclass::TVertexCompare TVertexCompare; typedef typename Superclass::TMinimumSpanningTree TMinimumSpanningTree; diff --git a/lib/fpa/Image/Dijkstra.h b/lib/fpa/Image/Dijkstra.h index e38fd0d..45759cb 100644 --- a/lib/fpa/Image/Dijkstra.h +++ b/lib/fpa/Image/Dijkstra.h @@ -15,12 +15,12 @@ namespace fpa * @param I Input image type * @param O Output image type */ - template< class I, class O > + template< class I, class O = I > class Dijkstra - : public Algorithm< I, O, fpa::Base::Dijkstra< typename I::IndexType, typename I::PixelType, typename O::PixelType, itk::Functor::IndexLexicographicCompare< I::ImageDimension >, itk::ImageToImageFilter< I, O > > > + : public Algorithm< I, O, fpa::Base::Dijkstra< typename I::IndexType, typename I::PixelType, typename O::PixelType, I, itk::Functor::IndexLexicographicCompare< I::ImageDimension >, itk::ImageToImageFilter< I, O > > > { public: - typedef fpa::Base::Dijkstra< typename I::IndexType, typename I::PixelType, typename O::PixelType, itk::Functor::IndexLexicographicCompare< I::ImageDimension >, itk::ImageToImageFilter< I, O > > TBaseAlgorithm; + typedef fpa::Base::Dijkstra< typename I::IndexType, typename I::PixelType, typename O::PixelType, I, itk::Functor::IndexLexicographicCompare< I::ImageDimension >, itk::ImageToImageFilter< I, O > > TBaseAlgorithm; typedef Dijkstra Self; typedef Algorithm< I, O, TBaseAlgorithm > Superclass; @@ -32,6 +32,7 @@ namespace fpa typedef typename Superclass::TVertex TVertex; typedef typename Superclass::TValue TValue; typedef typename Superclass::TResult TResult; + typedef typename Superclass::TSpace TSpace; typedef typename Superclass::TMinimumSpanningTree TMinimumSpanningTree; typedef typename Superclass::TStartEvent TStartEvent; diff --git a/lib/fpa/Image/DijkstraWithEndPointDetection.h b/lib/fpa/Image/DijkstraWithEndPointDetection.h index b32d68a..13da729 100644 --- a/lib/fpa/Image/DijkstraWithEndPointDetection.h +++ b/lib/fpa/Image/DijkstraWithEndPointDetection.h @@ -31,6 +31,7 @@ namespace fpa typedef typename Superclass::TVertexCompare TVertexCompare; typedef typename Superclass::TValue TValue; typedef typename Superclass::TResult TResult; + typedef typename Superclass::TSpace TSpace; typedef typename Superclass::TMinimumSpanningTree TMinimumSpanningTree; typedef typename Superclass::TCostFunction TCostFunction; typedef typename Superclass::TConversionFunction TConversionFunction; @@ -54,8 +55,10 @@ namespace fpa typedef unsigned short TLabel; typedef itk::Image< TLabel, I::ImageDimension > TLabelImage; - typedef fpa::Base::UniqueValuesContainer< TVertex, TVertexCompare > TUniqueVertices; - typedef fpa::Base::MatrixValuesContainer< TVertex, TLabel, TVertexCompare > TBranches; + typedef fpa::Base:: + UniqueValuesContainer< TVertex, TVertexCompare > TUniqueVertices; + typedef fpa::Base:: + MatrixValuesContainer< TVertex, TLabel, TVertexCompare > TBranches; protected: typedef typename Superclass::_TVertices _TVertices; diff --git a/lib/fpa/Image/DijkstraWithEndPointDetection.hxx b/lib/fpa/Image/DijkstraWithEndPointDetection.hxx index dc51a64..cb417f0 100644 --- a/lib/fpa/Image/DijkstraWithEndPointDetection.hxx +++ b/lib/fpa/Image/DijkstraWithEndPointDetection.hxx @@ -428,6 +428,7 @@ _LabelAll( ) // Configure and obtain inputs const I* input = this->GetInput( ); const TMinimumSpanningTree* mst = this->GetMinimumSpanningTree( ); + const TUniqueVertices* bifurcations = this->GetBifurcations( ); TBranches* branches = this->GetBranches( ); TLabelImage* label = this->GetLabelImage( ); label->FillBuffer( 0 ); @@ -473,28 +474,26 @@ _LabelAll( ) this->m_NumberOfBranches = actual_label; // Label bifurcations - /* TODO: Is this necessary? - typename TUniqueVertices::const_iterator bifIt = - this->m_Bifurcations.begin( ); - for( ; bifIt != this->m_Bifurcations.end( ); ++bifIt ) - { - actual_label++; - double d = std::sqrt( double( input->GetPixel( *bifIt ) ) ); - _TRegion region = this->_Region( *bifIt, d ); - itk::ImageRegionConstIteratorWithIndex< I > iIt( input, region ); - itk::ImageRegionIteratorWithIndex< TLabelImage > lIt( label, region ); - iIt.GoToBegin( ); - lIt.GoToBegin( ); - for( ; !iIt.IsAtEnd( ); ++iIt, ++lIt ) - { - // Mask real input image - if( !( iIt.Get( ) < ( typename I::PixelType )( 0 ) ) ) - lIt.Set( actual_label ); - - } // rof - - } // rof - */ + typename TUniqueVertices::ConstIterator bifIt = + bifurcations->Begin( ); + for( ; bifIt != bifurcations->End( ); ++bifIt ) + { + actual_label++; + double d = std::sqrt( double( input->GetPixel( *bifIt ) ) ); + _TRegion region = this->_Region( *bifIt, d * 1.5 ); + itk::ImageRegionConstIteratorWithIndex< I > iIt( input, region ); + itk::ImageRegionIteratorWithIndex< TLabelImage > lIt( label, region ); + iIt.GoToBegin( ); + lIt.GoToBegin( ); + for( ; !iIt.IsAtEnd( ); ++iIt, ++lIt ) + { + // Mask real input image + if( !( iIt.Get( ) < ( typename I::PixelType )( 0 ) ) ) + lIt.Set( actual_label ); + + } // rof + + } // rof } // ------------------------------------------------------------------------- diff --git a/lib/fpa/Image/Functors/ImageAbsoluteDifferenceCostFunction.h b/lib/fpa/Image/Functors/ImageAbsoluteDifferenceCostFunction.h new file mode 100644 index 0000000..6171f26 --- /dev/null +++ b/lib/fpa/Image/Functors/ImageAbsoluteDifferenceCostFunction.h @@ -0,0 +1,87 @@ +#ifndef __FPA__IMAGE__FUNCTORS__IMAGEABSOLUTEDIFFERENCECOSTFUNCTION__H__ +#define __FPA__IMAGE__FUNCTORS__IMAGEABSOLUTEDIFFERENCECOSTFUNCTION__H__ + +#include + +namespace fpa +{ + namespace Image + { + namespace Functors + { + /** + */ + template< class I, class R > + class ImageAbsoluteDifferenceCostFunction + : public fpa::Image::Functors::ImageCostFunction< I, R > + { + public: + /// Type-related and pointers + typedef ImageAbsoluteDifferenceCostFunction Self; + typedef fpa::Image::Functors::ImageCostFunction< I, R > Superclass; + typedef itk::SmartPointer< Self > Pointer; + typedef itk::SmartPointer< const Self > ConstPointer; + + typedef typename Superclass::TInputImage TInputImage; + typedef typename Superclass::TResult TResult; + typedef typename Superclass::TIndex TIndex; + + public: + itkNewMacro( Self ); + itkTypeMacro( ImageAbsoluteDifferenceCostFunction, itkObject ); + + public: + virtual R Evaluate( const TIndex& v, const TIndex& p ) const + { + typedef typename I::PixelType _TPixel; + typedef typename itk::NumericTraits< _TPixel > _TTraits; + typedef typename _TTraits::MeasurementVectorType _TVector; + typedef typename _TTraits::ValueType _TValue; + + if( this->m_InputImage.IsNotNull( ) ) + { + _TPixel pix = this->m_InputImage->GetPixel( v ); + pix -= this->m_InputImage->GetPixel( p ); + if( typeid( _TPixel ) != typeid( _TValue ) ) + { + _TVector* a = reinterpret_cast< _TVector* >( &pix ); + unsigned int n = + this->m_InputImage->GetNumberOfComponentsPerPixel( ); + double sum = double( 0 ); + for( unsigned int i = 0; i < n; ++i ) + sum += ( double( ( *a )[ i ] ) * double( ( *a )[ i ] ) ); + return( R( std::sqrt( sum ) ) ); + } + else + { + double pix_val = + double( *( reinterpret_cast< _TValue* >( &pix ) ) ); + return( R( std::fabs( pix_val ) ) ); + } + } + else + return( std::numeric_limits< R >::max( ) ); + } + + protected: + ImageAbsoluteDifferenceCostFunction( ) + : Superclass( ) + { } + virtual ~ImageAbsoluteDifferenceCostFunction( ) + { } + + private: + // Purposely not implemented + ImageAbsoluteDifferenceCostFunction( const Self& ); + void operator=( const Self& ); + }; + + } // ecapseman + + } // ecapseman + +} // ecapseman + +#endif // __FPA__IMAGE__FUNCTORS__IMAGEABSOLUTEDIFFERENCECOSTFUNCTION__H__ + +// eof - $RCSfile$ diff --git a/lib/fpa/Image/Functors/RegionGrowAllBelongsFunction.h b/lib/fpa/Image/Functors/RegionGrowAllBelongsFunction.h index e352f59..362304f 100644 --- a/lib/fpa/Image/Functors/RegionGrowAllBelongsFunction.h +++ b/lib/fpa/Image/Functors/RegionGrowAllBelongsFunction.h @@ -1,7 +1,7 @@ #ifndef __FPA__IMAGE__FUNCTORS__REGIONGROWALLBELONGSFUNCTION__H__ #define __FPA__IMAGE__FUNCTORS__REGIONGROWALLBELONGSFUNCTION__H__ -#include +#include namespace fpa { @@ -13,26 +13,27 @@ namespace fpa */ template< class I > class RegionGrowAllBelongsFunction - : public fpa::Image::Functors::ImageFunction< I, bool > + : public fpa::Base::Functors::TautologyFunction< I, typename I::IndexType > { public: /// Type-related and pointers - typedef RegionGrowAllBelongsFunction Self; - typedef fpa::Image::Functors::ImageFunction< I, bool > Superclass; - typedef itk::SmartPointer< Self > Pointer; - typedef itk::SmartPointer< const Self > ConstPointer; + typedef RegionGrowAllBelongsFunction Self; + typedef itk::SmartPointer< Self > Pointer; + typedef itk::SmartPointer< const Self > ConstPointer; + typedef fpa::Base::Functors:: + TautologyFunction< I, typename I::IndexType > + Superclass; // Superclass' types - typedef typename Superclass::TInputImage TInputImage; - typedef typename Superclass::TOutputValue TOutputValue; - typedef typename Superclass::TIndex TIndex; + typedef I TInputImage; + typedef typename I::IndexType TIndex; public: itkNewMacro( Self ); itkTypeMacro( RegionGrowAllBelongsFunction, itkImageFunction ); public: - virtual TOutputValue Evaluate( const TIndex& idx ) const + virtual bool Evaluate( const TIndex& v ) const { return( true ); } protected: diff --git a/lib/fpa/Image/Functors/RegionGrowThresholdFunction.h b/lib/fpa/Image/Functors/RegionGrowThresholdFunction.h index 739dff4..3d7d5ac 100644 --- a/lib/fpa/Image/Functors/RegionGrowThresholdFunction.h +++ b/lib/fpa/Image/Functors/RegionGrowThresholdFunction.h @@ -24,10 +24,9 @@ namespace fpa typedef itk::SmartPointer< const Self > ConstPointer; // Superclass' types - typedef typename Superclass::TInputImage TInputImage; - typedef typename Superclass::TOutputValue TOutputValue; - typedef typename Superclass::TIndex TIndex; - typedef typename I::PixelType TPixel; + typedef I TInputImage; + typedef typename I::IndexType TIndex; + typedef typename I::PixelType TPixel; public: itkNewMacro( Self ); @@ -43,14 +42,14 @@ namespace fpa itkSetMacro( UpperThreshold, TPixel ); public: - virtual TOutputValue Evaluate( const TIndex& idx ) const + virtual bool Evaluate( const TIndex& idx ) const { - const I* img = this->GetInputImage( ); + const I* img = this->GetSpace( ); if( img != NULL ) { TPixel v = img->GetPixel( idx ); return( - this->m_LowerThreshold <= v && v < this->m_UpperThreshold + !( v < this->m_LowerThreshold || this->m_UpperThreshold < v ) ); } // fi diff --git a/lib/fpa/Image/IncrementalRegionGrow.h b/lib/fpa/Image/IncrementalRegionGrow.h new file mode 100644 index 0000000..a2a1156 --- /dev/null +++ b/lib/fpa/Image/IncrementalRegionGrow.h @@ -0,0 +1,69 @@ +#ifndef __FPA__IMAGE__INCREMENTALREGIONGROW__H__ +#define __FPA__IMAGE__INCREMENTALREGIONGROW__H__ + +#include +#include +#include +#include +#include + +namespace fpa +{ + namespace Image + { + /** + * @param I Input image type + * @param O Output image type + */ + template< class I, class O > + class IncrementalRegionGrow + : public Algorithm< I, O, fpa::Base::IncrementalRegionGrow< typename I::IndexType, typename I::PixelType, typename O::PixelType, itk::Functor::IndexLexicographicCompare< I::ImageDimension >, itk::ImageToImageFilter< I, O > > > + { + public: + typedef fpa::Base::IncrementalRegionGrow< typename I::IndexType, typename I::PixelType, typename O::PixelType, itk::Functor::IndexLexicographicCompare< I::ImageDimension >, itk::ImageToImageFilter< I, O > > TBaseAlgorithm; + + typedef IncrementalRegionGrow Self; + typedef Algorithm< I, O, TBaseAlgorithm > Superclass; + typedef itk::SmartPointer< Self > Pointer; + typedef itk::SmartPointer< const Self > ConstPointer; + + typedef typename Superclass::TInputImage TInputImage; + typedef typename Superclass::TOutputImage TOutputImage; + typedef typename Superclass::TVertex TVertex; + typedef typename Superclass::TValue TValue; + typedef typename Superclass::TResult TResult; + typedef typename Superclass::TGrowingFunction TGrowingFunction; + + protected: + typedef typename Superclass::_TVertices _TVertices; + typedef typename Superclass::_TCollision _TCollision; + typedef typename Superclass::_TCollisionsRow _TCollisionsRow; + typedef typename Superclass::_TCollisions _TCollisions; + typedef typename Superclass::_TNode _TNode; + typedef typename Superclass::_TNodes _TNodes; + + public: + itkNewMacro( Self ); + itkTypeMacro( IncrementalRegionGrow, Algorithm ); + + protected: + IncrementalRegionGrow( ); + virtual ~IncrementalRegionGrow( ); + + virtual void _InitResults( ); + + private: + // Purposely not implemented + IncrementalRegionGrow( const Self& other ); + Self& operator=( const Self& other ); + }; + + } // ecapseman + +} // ecapseman + +#include + +#endif // __FPA__IMAGE__INCREMENTALREGIONGROW__H__ + +// eof - $RCSfile$ diff --git a/lib/fpa/Image/IncrementalRegionGrow.hxx b/lib/fpa/Image/IncrementalRegionGrow.hxx new file mode 100644 index 0000000..740b2f8 --- /dev/null +++ b/lib/fpa/Image/IncrementalRegionGrow.hxx @@ -0,0 +1,30 @@ +#ifndef __FPA__IMAGE__INCREMENTALREGIONGROW__HXX__ +#define __FPA__IMAGE__INCREMENTALREGIONGROW__HXX__ + +// ------------------------------------------------------------------------- +template< class I, class O > +fpa::Image::IncrementalRegionGrow< I, O >:: +IncrementalRegionGrow( ) + : Superclass( ) +{ +} + +// ------------------------------------------------------------------------- +template< class I, class O > +fpa::Image::IncrementalRegionGrow< I, O >:: +~IncrementalRegionGrow( ) +{ +} + +// ------------------------------------------------------------------------- +template< class I, class O > +void fpa::Image::IncrementalRegionGrow< I, O >:: +_InitResults( ) +{ + this->Superclass::_InitResults( ); + this->GetOutput( )->FillBuffer( this->m_OutsideValue ); +} + +#endif // __FPA__IMAGE__INCREMENTALREGIONGROW__HXX__ + +// eof - $RCSfile$ diff --git a/lib/fpa/Image/RegionGrow.h b/lib/fpa/Image/RegionGrow.h index 71db89c..b814798 100644 --- a/lib/fpa/Image/RegionGrow.h +++ b/lib/fpa/Image/RegionGrow.h @@ -15,25 +15,25 @@ namespace fpa * @param I Input image type * @param O Output image type */ - template< class I, class O > + template< class I, class O = I > class RegionGrow - : public Algorithm< I, O, fpa::Base::RegionGrow< typename I::IndexType, typename I::PixelType, typename O::PixelType, itk::Functor::IndexLexicographicCompare< I::ImageDimension >, itk::ImageToImageFilter< I, O > > > + : public Algorithm< I, O, fpa::Base::RegionGrow< typename I::IndexType, typename I::PixelType, typename O::PixelType, I, itk::Functor::IndexLexicographicCompare< I::ImageDimension >, itk::ImageToImageFilter< I, O > > > { public: - typedef fpa::Base::RegionGrow< typename I::IndexType, typename I::PixelType, typename O::PixelType, itk::Functor::IndexLexicographicCompare< I::ImageDimension >, itk::ImageToImageFilter< I, O > > TBaseAlgorithm; + typedef fpa::Base::RegionGrow< typename I::IndexType, typename I::PixelType, typename O::PixelType, I, itk::Functor::IndexLexicographicCompare< I::ImageDimension >, itk::ImageToImageFilter< I, O > > TBaseAlgorithm; typedef RegionGrow Self; typedef Algorithm< I, O, TBaseAlgorithm > Superclass; typedef itk::SmartPointer< Self > Pointer; typedef itk::SmartPointer< const Self > ConstPointer; - typedef typename Superclass::TInputImage TInputImage; - typedef typename Superclass::TOutputImage TOutputImage; - typedef typename Superclass::TVertex TVertex; - typedef typename Superclass::TValue TValue; - typedef typename Superclass::TResult TResult; - - typedef itk::FunctionBase< TValue, bool > TMembershipFunction; + typedef typename Superclass::TInputImage TInputImage; + typedef typename Superclass::TOutputImage TOutputImage; + typedef typename Superclass::TVertex TVertex; + typedef typename Superclass::TValue TValue; + typedef typename Superclass::TResult TResult; + typedef typename Superclass::TSpace TSpace; + typedef typename Superclass::TGrowingFunction TGrowingFunction; protected: typedef typename Superclass::_TVertices _TVertices; @@ -47,24 +47,16 @@ namespace fpa itkNewMacro( Self ); itkTypeMacro( RegionGrow, Algorithm ); - itkGetObjectMacro( MembershipFunction, TMembershipFunction ); - itkGetConstObjectMacro( MembershipFunction, TMembershipFunction ); - itkSetObjectMacro( MembershipFunction, TMembershipFunction ); - protected: RegionGrow( ); virtual ~RegionGrow( ); - virtual bool _CheckMembership( const TVertex& v ) const; virtual void _InitResults( ); private: // Purposely not implemented RegionGrow( const Self& other ); Self& operator=( const Self& other ); - - protected: - typename TMembershipFunction::Pointer m_MembershipFunction; }; } // ecapseman diff --git a/lib/fpa/Image/RegionGrow.hxx b/lib/fpa/Image/RegionGrow.hxx index e8e92c8..9b5b0f7 100644 --- a/lib/fpa/Image/RegionGrow.hxx +++ b/lib/fpa/Image/RegionGrow.hxx @@ -16,23 +16,13 @@ fpa::Image::RegionGrow< I, O >:: { } -// ------------------------------------------------------------------------- -template< class I, class O > -bool fpa::Image::RegionGrow< I, O >:: -_CheckMembership( const TVertex& v ) const -{ - if( this->m_MembershipFunction.IsNotNull( ) ) - return( this->m_MembershipFunction->Evaluate( this->_VertexValue( v ) ) ); - else - return( false ); -} - // ------------------------------------------------------------------------- template< class I, class O > void fpa::Image::RegionGrow< I, O >:: _InitResults( ) { this->Superclass::_InitResults( ); + this->m_GrowingFunction->SetSpace( this->GetInput( ) ); this->GetOutput( )->FillBuffer( this->m_OutsideValue ); } diff --git a/lib/fpa/VTK/Image2DObserver.hxx b/lib/fpa/VTK/Image2DObserver.hxx index fd6247f..49d5577 100644 --- a/lib/fpa/VTK/Image2DObserver.hxx +++ b/lib/fpa/VTK/Image2DObserver.hxx @@ -62,6 +62,10 @@ Execute( const itk::Object* c, const itk::EventObject& e ) typedef typename F::TFrontEvent _TFrontEvent; typedef typename F::TFreezeEvent _TFreezeEvent; + typedef typename F::TStartBacktrackingEvent _TStartBacktrackingEvent; + typedef typename F::TEndBacktrackingEvent _TEndBacktrackingEvent; + typedef typename F::TBacktrackingEvent _TBacktrackingEvent; + static unsigned char Colors[][4] = { { 0, 0, 127, 127 }, @@ -87,7 +91,9 @@ Execute( const itk::Object* c, const itk::EventObject& e ) return; const _TStartEvent* startEvt = dynamic_cast< const _TStartEvent* >( &e ); - if( startEvt != NULL ) + const _TStartBacktrackingEvent* startBackEvt = + dynamic_cast< const _TStartBacktrackingEvent* >( &e ); + if( startEvt != NULL || startBackEvt != NULL ) { const typename F::TInputImage* img = filter->GetInput( ); unsigned int minD = F::TInputImage::ImageDimension; @@ -171,6 +177,29 @@ Execute( const itk::Object* c, const itk::EventObject& e ) return; } // fi + + const _TBacktrackingEvent* backEvt = + dynamic_cast< const _TBacktrackingEvent* >( &e ); + const _TEndBacktrackingEvent* endBackEvt = + dynamic_cast< const _TEndBacktrackingEvent* >( &e ); + if( backEvt != NULL ) + { + this->SetPixel( backEvt->Vertex, 0, 0, 255, 255 ); + return; + + } // fi + + if( endBackEvt != NULL ) + { + this->m_RenderWindow->Render( ); + /* TODO: DEBUG + std::cout << "Press enter: " << std::ends; + int aux; + std::cin >> aux; + */ + return; + + } // fi } // ------------------------------------------------------------------------- diff --git a/lib/fpa/VTK/Image3DObserver.hxx b/lib/fpa/VTK/Image3DObserver.hxx index 721a89d..3baac71 100644 --- a/lib/fpa/VTK/Image3DObserver.hxx +++ b/lib/fpa/VTK/Image3DObserver.hxx @@ -155,7 +155,6 @@ Execute( const itk::Object* c, const itk::EventObject& e ) } // fi - const _TBacktrackingEvent* backEvt = dynamic_cast< const _TBacktrackingEvent* >( &e ); const _TEndBacktrackingEvent* endBackEvt = diff --git a/lib/fpa/VTK/ImageMPR.cxx b/lib/fpa/VTK/ImageMPR.cxx index 1cc4b85..c308453 100644 --- a/lib/fpa/VTK/ImageMPR.cxx +++ b/lib/fpa/VTK/ImageMPR.cxx @@ -221,6 +221,15 @@ SetSize( unsigned int w, unsigned int h ) this->m_Window->SetSize( w, h ); } +// ------------------------------------------------------------------------- +void fpa::VTK::ImageMPR:: +SetWindowLevel( double w, double l ) +{ + this->m_WidgetX->SetWindowLevel( w, l ); + this->m_WidgetY->SetWindowLevel( w, l ); + this->m_WidgetZ->SetWindowLevel( w, l ); +} + // ------------------------------------------------------------------------- void fpa::VTK::ImageMPR:: AddPolyData( vtkPolyData* pd, double opacity ) @@ -235,7 +244,7 @@ AddPolyData( vtkPolyData* pd, double opacity ) this->m_Actors[ i ]->SetMapper( this->m_Mappers[ i ] ); this->m_Actors[ i ]->GetProperty( )->SetOpacity( opacity ); this->m_Actors[ i ]->GetProperty( )->SetLineWidth( 3 ); - this->m_Actors[ i ]->GetProperty( )->SetPointSize( 10 ); + this->m_Actors[ i ]->GetProperty( )->SetPointSize( 5 ); this->m_Renderer->AddActor( this->m_Actors[ i ] ); } @@ -255,7 +264,7 @@ AddPolyData( vtkPolyData* pd, double r, double g, double b, double opacity ) this->m_Actors[ i ]->GetProperty( )->SetColor( r, g, b ); this->m_Actors[ i ]->GetProperty( )->SetOpacity( opacity ); this->m_Actors[ i ]->GetProperty( )->SetLineWidth( 3 ); - this->m_Actors[ i ]->GetProperty( )->SetPointSize( 10 ); + this->m_Actors[ i ]->GetProperty( )->SetPointSize( 5 ); this->m_Renderer->AddActor( this->m_Actors[ i ] ); } @@ -298,6 +307,21 @@ GetSeed( int n, double* s ) const hRep->GetWorldPosition( s ); } +// ------------------------------------------------------------------------- +unsigned int fpa::VTK::ImageMPR:: +AddSeed( const double& x, const double& y, const double& z ) const +{ + double pos[ 3 ] = { x, y, z }; + + int hnd_id = this->m_SeedRepresentation->CreateHandle( pos ); + vtkHandleWidget* hnd = this->m_SeedWidget->CreateNewHandle( ); + vtkHandleWidget::ComputeWorldToDisplay( this->m_Renderer, x, y, z, pos ); + this->m_SeedRepresentation->SetSeedDisplayPosition( hnd_id, pos ); + hnd->SetEnabled( 1 ); + + return( this->GetNumberOfSeeds( ) - 1 ); +} + // ------------------------------------------------------------------------- vtkRenderWindow* fpa::VTK::ImageMPR:: GetWindow( ) const diff --git a/lib/fpa/VTK/ImageMPR.h b/lib/fpa/VTK/ImageMPR.h index e64ff8a..978738a 100644 --- a/lib/fpa/VTK/ImageMPR.h +++ b/lib/fpa/VTK/ImageMPR.h @@ -37,6 +37,7 @@ namespace fpa void SetImage( vtkImageData* image ); void SetBackground( double r, double g, double b ); void SetSize( unsigned int w, unsigned int h ); + void SetWindowLevel( double w, double l ); void AddPolyData( vtkPolyData* pd, double opacity = double( 1 ) ); void AddPolyData( @@ -51,6 +52,9 @@ namespace fpa unsigned int GetNumberOfSeeds( ) const; void GetSeed( int n, double* s ) const; + unsigned int AddSeed( + const double& x, const double& y, const double& z + ) const; vtkRenderWindow* GetWindow( ) const; vtkRenderer* GetRenderer( ) const; diff --git a/lib/fpa/VTK/UniqueVerticesToPolyDataFilter.h b/lib/fpa/VTK/UniqueVerticesToPolyDataFilter.h new file mode 100644 index 0000000..ed9785f --- /dev/null +++ b/lib/fpa/VTK/UniqueVerticesToPolyDataFilter.h @@ -0,0 +1,67 @@ +#ifndef __FPA__VTK__UNIQUEVERTICESTOPOLYDATAFILTER__H__ +#define __FPA__VTK__UNIQUEVERTICESTOPOLYDATAFILTER__H__ + +#include + +namespace fpa +{ + namespace VTK + { + /** + */ + template< class U, class I > + class UniqueVerticesToPolyDataFilter + : public vtkPolyDataAlgorithm + { + public: + typedef UniqueVerticesToPolyDataFilter Self; + + public: + vtkTypeMacro( UniqueVerticesToPolyDataFilter,vtkPolyDataAlgorithm ); + + public: + static Self* New( ); + + const U* GetInput( ) const; + void SetInput( const U* c ); + + const I* GetImage( ) const; + void SetImage( const I* i ); + + virtual unsigned long GetMTime( ); + + protected: + UniqueVerticesToPolyDataFilter( ); + virtual ~UniqueVerticesToPolyDataFilter( ); + + int RequestData( + vtkInformation* information, + vtkInformationVector** input, + vtkInformationVector* output + ); + int RequestInformation( + vtkInformation* information, + vtkInformationVector** input, + vtkInformationVector* output + ); + + private: + // Purposely not implemented + UniqueVerticesToPolyDataFilter( const Self& ); + void operator=( const Self& ); + + protected: + typename U::ConstPointer m_Container; + typename I::ConstPointer m_Image; + unsigned long m_LastContainerModifiedTime; + }; + + } // ecapseman + +} // ecapseman + +#include + +#endif // __FPA__VTK__UNIQUEVERTICESTOPOLYDATAFILTER__H__ + +// eof - $RCSfile$ diff --git a/lib/fpa/VTK/UniqueVerticesToPolyDataFilter.hxx b/lib/fpa/VTK/UniqueVerticesToPolyDataFilter.hxx new file mode 100644 index 0000000..c2d2629 --- /dev/null +++ b/lib/fpa/VTK/UniqueVerticesToPolyDataFilter.hxx @@ -0,0 +1,186 @@ +#ifndef __FPA__VTK__UNIQUEVERTICESTOPOLYDATAFILTER__HXX__ +#define __FPA__VTK__UNIQUEVERTICESTOPOLYDATAFILTER__HXX__ + +#include +#include + +// ------------------------------------------------------------------------- +template< class U, class I > +typename fpa::VTK::UniqueVerticesToPolyDataFilter< U, I >:: +Self* fpa::VTK::UniqueVerticesToPolyDataFilter< U, I >:: +New( ) +{ + return( new Self( ) ); +} + +// ------------------------------------------------------------------------- +template< class U, class I > +const U* fpa::VTK::UniqueVerticesToPolyDataFilter< U, I >:: +GetInput( ) const +{ + return( this->m_Container ); +} + +// ------------------------------------------------------------------------- +template< class U, class I > +void fpa::VTK::UniqueVerticesToPolyDataFilter< U, I >:: +SetInput( const U* c ) +{ + if( this->m_Container.GetPointer( ) != c ) + { + this->m_Container = c; + this->m_LastContainerModifiedTime = this->m_Container->GetMTime( ); + this->Modified( ); + + } // fi +} + +// ------------------------------------------------------------------------- +template< class U, class I > +const I* fpa::VTK::UniqueVerticesToPolyDataFilter< U, I >:: +GetImage( ) const +{ + return( this->m_Image ); +} + +// ------------------------------------------------------------------------- +template< class U, class I > +void fpa::VTK::UniqueVerticesToPolyDataFilter< U, I >:: +SetImage( const I* i ) +{ + if( this->m_Image.GetPointer( ) != i ) + { + this->m_Image = i; + this->Modified( ); + + } // fi +} + +// ------------------------------------------------------------------------- +template< class U, class I > +unsigned long fpa::VTK::UniqueVerticesToPolyDataFilter< U, I >:: +GetMTime( ) +{ + unsigned long ctime = this->m_Container->GetMTime( ); + if( ctime > this->m_LastContainerModifiedTime ) + { + this->m_LastContainerModifiedTime = ctime; + this->Modified( ); + + } // fi + return( this->Superclass::GetMTime( ) ); +} + +// ------------------------------------------------------------------------- +template< class U, class I > +fpa::VTK::UniqueVerticesToPolyDataFilter< U, I >:: +UniqueVerticesToPolyDataFilter( ) + : vtkPolyDataAlgorithm( ) +{ + this->SetNumberOfInputPorts( 0 ); +} + +// ------------------------------------------------------------------------- +template< class U, class I > +fpa::VTK::UniqueVerticesToPolyDataFilter< U, I >:: +~UniqueVerticesToPolyDataFilter( ) +{ +} + +// ------------------------------------------------------------------------- +template< class U, class I > +int fpa::VTK::UniqueVerticesToPolyDataFilter< U, I >:: +RequestData( + vtkInformation* information, + vtkInformationVector** input, + vtkInformationVector* output + ) +{ + if( this->m_Container.IsNull( ) || this->m_Image.IsNull( ) ) + return( 0 ); + + // Get output + vtkInformation* info = output->GetInformationObject( 0 ); + vtkPolyData* out = vtkPolyData::SafeDownCast( + info->Get( vtkDataObject::DATA_OBJECT( ) ) + ); + + // Prepare points + vtkPoints* points = out->GetPoints( ); + if( points == NULL ) + { + points = vtkPoints::New( ); + out->SetPoints( points ); + points->Delete( ); + + } // fi + points->SetNumberOfPoints( this->m_Container->Size( ) ); + + // Prepare cells + vtkSmartPointer< vtkCellArray > cells = + vtkSmartPointer< vtkCellArray >::New( ); + + unsigned int pId = 0; + for( + typename U::ConstIterator it = this->m_Container->Begin( ); + it != this->m_Container->End( ); + ++it, ++pId + ) + { + typename I::PointType pnt; + this->m_Image->TransformIndexToPhysicalPoint( *it, pnt ); + if( I::ImageDimension == 1 ) + points->SetPoint( pId, pnt[ 0 ], 0, 0 ); + else if( I::ImageDimension == 2 ) + points->SetPoint( pId, pnt[ 0 ], pnt[ 1 ], 0 ); + else + points->SetPoint( pId, pnt[ 0 ], pnt[ 1 ], pnt[ 2 ] ); + + cells->InsertNextCell( 1 ); + cells->InsertCellPoint( pId ); + + } // rof + out->SetPoints( points ); + out->SetVerts( cells ); + return( 1 ); +} + +// ------------------------------------------------------------------------- +template< class U, class I > +int fpa::VTK::UniqueVerticesToPolyDataFilter< U, I >:: +RequestInformation( + vtkInformation* information, + vtkInformationVector** input, + vtkInformationVector* output + ) +{ + vtkInformation* info = output->GetInformationObject( 0 ); + /* TODO + info->Set( + vtkStreamingDemandDrivenPipeline::MAXIMUM_NUMBER_OF_PIECES( ), -1 + ); + */ + + if( this->m_Container.IsNotNull( ) && this->m_Image.IsNotNull( ) ) + { + /* TODO + typename C::TScalar len = this->m_RGC->GetTotalLength( ); + typename C::TScalar s0 = this->m_RGC->Gets0( ); + typename C::TPoint p0 = this->m_RGC->Axis( s0 ); + typename C::TPoint p1 = this->m_RGC->Axis( s0 + len ); + + info->Set( + vtkStreamingDemandDrivenPipeline::WHOLE_BOUNDING_BOX( ), + double( p0[ 0 ] ), double( p1[ 0 ] ), + double( p0[ 1 ] ), double( p1[ 1 ] ), + double( p0[ 2 ] ), double( p1[ 2 ] ) + ); + */ + + } // fi + return( 1 ); +} + +#endif // __FPA__VTK__UNIQUEVERTICESTOPOLYDATAFILTER__HXX__ + +// eof - $RCSfile$