]> Creatis software - FrontAlgorithms.git/commitdiff
CMake updated. Some other filters added.
authorLeonardo Florez-Valencia <florez-l@javeriana.edu.co>
Fri, 5 Jun 2015 00:10:06 +0000 (19:10 -0500)
committerLeonardo Florez-Valencia <florez-l@javeriana.edu.co>
Fri, 5 Jun 2015 00:10:06 +0000 (19:10 -0500)
40 files changed:
CMakeLists.txt
appli/examples/CMakeLists.txt
appli/examples/example_CircleOfWillis.cxx [new file with mode: 0644]
appli/examples/example_Image_Dijkstra_AbsoluteDifferenceCost.cxx [new file with mode: 0644]
appli/examples/example_Image_Dijkstra_EndPointDetection.cxx
appli/examples/example_Image_IncrementalRegionGrow_Thresholds.cxx [new file with mode: 0644]
appli/examples/example_Image_RegionGrow_AllPixels.cxx
appli/examples/example_Image_RegionGrow_AllRGBPixels.cxx
appli/examples/example_Image_RegionGrow_ConnectedPixels.cxx [new file with mode: 0644]
appli/examples/example_Image_RegionGrow_ConnectedRGBPixels.cxx [new file with mode: 0644]
appli/examples/example_IncrementalRegionGrow_Thresholds.cxx [new file with mode: 0644]
appli/examples/fpa_Utility.h [new file with mode: 0644]
lib/CMakeLists.txt
lib/fpa/Base/Algorithm.h
lib/fpa/Base/Algorithm.hxx
lib/fpa/Base/Dijkstra.h
lib/fpa/Base/Dijkstra.hxx
lib/fpa/Base/Functors/TautologyFunction.h
lib/fpa/Base/IncrementalRegionGrow.h [new file with mode: 0644]
lib/fpa/Base/IncrementalRegionGrow.hxx [new file with mode: 0644]
lib/fpa/Base/RegionGrow.h
lib/fpa/Base/RegionGrow.hxx
lib/fpa/Base/UniqueValuesContainer.h
lib/fpa/Image/Algorithm.h
lib/fpa/Image/Dijkstra.h
lib/fpa/Image/DijkstraWithEndPointDetection.h
lib/fpa/Image/DijkstraWithEndPointDetection.hxx
lib/fpa/Image/Functors/ImageAbsoluteDifferenceCostFunction.h [new file with mode: 0644]
lib/fpa/Image/Functors/RegionGrowAllBelongsFunction.h
lib/fpa/Image/Functors/RegionGrowThresholdFunction.h
lib/fpa/Image/IncrementalRegionGrow.h [new file with mode: 0644]
lib/fpa/Image/IncrementalRegionGrow.hxx [new file with mode: 0644]
lib/fpa/Image/RegionGrow.h
lib/fpa/Image/RegionGrow.hxx
lib/fpa/VTK/Image2DObserver.hxx
lib/fpa/VTK/Image3DObserver.hxx
lib/fpa/VTK/ImageMPR.cxx
lib/fpa/VTK/ImageMPR.h
lib/fpa/VTK/UniqueVerticesToPolyDataFilter.h [new file with mode: 0644]
lib/fpa/VTK/UniqueVerticesToPolyDataFilter.hxx [new file with mode: 0644]

index 5182771b76c9d578a8a444d86ae29c953e1c6e3f..2ada831c810ec82b4d9a722f1a2e2efb8ea8232a 100644 (file)
@@ -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:
-##
-##   <command-line>:0:0: warning: "vtkRenderingCore_AUTOINIT" redefined
-##   <command-line>: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)
index 122dcee2d899513c435c7c64accecbb1252f55ac..6b3f71c97ba38d9958e4a60bfca2e17c131f942e 100644 (file)
@@ -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 (file)
index 0000000..e00ca3d
--- /dev/null
@@ -0,0 +1,141 @@
+#include <iostream>
+#include <fstream>
+#include <limits>
+#include <string>
+
+#include <itkImage.h>
+#include <itkImageToVTKImageFilter.h>
+#include <itkImageFileReader.h>
+
+#include <vtkCellArray.h>
+#include <vtkFloatArray.h>
+#include <vtkPointData.h>
+#include <vtkPoints.h>
+#include <vtkPolyData.h>
+#include <vtkSmartPointer.h>
+
+#include <fpa/VTK/ImageMPR.h>
+
+// -------------------------------------------------------------------------
+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 (file)
index 0000000..47affc1
--- /dev/null
@@ -0,0 +1,164 @@
+#include <cstdlib>
+#include <iostream>
+#include <fstream>
+#include <limits>
+#include <string>
+#include <vector>
+
+#include <itkImage.h>
+#include <itkImageToVTKImageFilter.h>
+
+#include <itkImageFileReader.h>
+#include <itkImageFileWriter.h>
+
+#include <vtkCamera.h>
+#include <vtkImageActor.h>
+#include <vtkInteractorStyleImage.h>
+#include <vtkPointHandleRepresentation3D.h>
+#include <vtkProperty.h>
+#include <vtkRenderer.h>
+#include <vtkRenderWindow.h>
+#include <vtkRenderWindowInteractor.h>
+#include <vtkSeedRepresentation.h>
+#include <vtkSeedWidget.h>
+#include <vtkSmartPointer.h>
+
+#include <fpa/Image/Dijkstra.h>
+#include <fpa/Image/Functors/ImageAbsoluteDifferenceCostFunction.h>
+#include <fpa/VTK/ImageMPR.h>
+#include <fpa/VTK/Image3DObserver.h>
+
+// -------------------------------------------------------------------------
+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$
index a334de3ae881a372578e7e999cc01d9315695d6f..aea0fe504f203100b5f04ab8123c5af82332133d 100644 (file)
 #include <itkImage.h>
 #include <itkImageToVTKImageFilter.h>
 
-#include <itkImageFileReader.h>
-#include <itkMinimumMaximumImageCalculator.h>
-#include <itkShiftScaleImageFilter.h>
-
 #include <itkSignedMaurerDistanceMapImageFilter.h>
 
-#include <itkImageFileWriter.h>
-
-#include <fpa/Image/DijkstraWithEndPointDetection.h>
 #include <fpa/Base/Functors/InvertCostFunction.h>
-#include <fpa/VTK/ImageMPR.h>
-#include <fpa/VTK/Image3DObserver.h>
-
+#include <fpa/Image/DijkstraWithEndPointDetection.h>
+#include <fpa/VTK/Image2DObserver.h>
 #include <fpa/IO/MinimumSpanningTreeWriter.h>
 #include <fpa/IO/UniqueValuesContainerWriter.h>
 #include <fpa/IO/MatrixValuesContainerWriter.h>
+#include <fpa/VTK/UniqueVerticesToPolyDataFilter.h>
 
-#include <vtkCellArray.h>
-#include <vtkFloatArray.h>
-#include <vtkImageMarchingCubes.h>
-#include <vtkPoints.h>
-#include <vtkPolyData.h>
-#include <vtkSmartPointer.h>
+#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 (file)
index 0000000..3261b60
--- /dev/null
@@ -0,0 +1,235 @@
+#include <cstdlib>
+#include <iostream>
+#include <fstream>
+#include <string>
+#include <vector>
+
+#include <itkImage.h>
+#include <itkImageToVTKImageFilter.h>
+
+#include <itkImageFileReader.h>
+#include <itkImageFileWriter.h>
+
+#include <fpa/VTK/ImageMPR.h>
+#include <fpa/Image/IncrementalRegionGrow.h>
+#include <fpa/Image/Functors/RegionGrowThresholdFunction.h>
+
+/*
+  #include <vtkCamera.h>
+  #include <vtkImageActor.h>
+  #include <vtkInteractorStyleImage.h>
+  #include <vtkPointHandleRepresentation3D.h>
+  #include <vtkProperty.h>
+  #include <vtkRenderer.h>
+  #include <vtkRenderWindow.h>
+  #include <vtkRenderWindowInteractor.h>
+  #include <vtkSeedRepresentation.h>
+  #include <vtkSeedWidget.h>
+  #include <vtkSmartPointer.h>
+
+  #include <fpa/Image/Functors/ImageAbsoluteDifferenceCostFunction.h>
+  #include <fpa/VTK/Image3DObserver.h>
+*/
+
+// -------------------------------------------------------------------------
+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$
index 9484957842d94fdff490c17cd6ace415182c1755..db7db5f9892fe233e8bd6fa2fa1b58d082885b24 100644 (file)
@@ -6,30 +6,16 @@
 #include <itkImage.h>
 #include <itkImageToVTKImageFilter.h>
 
-#include <itkImageFileReader.h>
-
-#include <vtkCamera.h>
-#include <vtkImageActor.h>
-#include <vtkInteractorStyleImage.h>
-#include <vtkPointHandleRepresentation3D.h>
-#include <vtkProperty.h>
-#include <vtkRenderer.h>
-#include <vtkRenderWindow.h>
-#include <vtkRenderWindowInteractor.h>
-#include <vtkSeedRepresentation.h>
-#include <vtkSeedWidget.h>
-#include <vtkSmartPointer.h>
-
 #include <fpa/Image/RegionGrow.h>
-#include <fpa/Base/Functors/TautologyFunction.h>
+#include <fpa/Image/Functors/RegionGrowAllBelongsFunction.h>
 #include <fpa/VTK/Image2DObserver.h>
 
+#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 );
 }
 
index fdb90fa1317f962905964945af01f3ea0e44f86d..c46c75824fafc616bd459a3453da318aba55b541 100644 (file)
@@ -4,34 +4,20 @@
 #include <string>
 
 #include <itkImage.h>
-#include <itkImageToVTKImageFilter.h>
 #include <itkRGBPixel.h>
-
-#include <itkImageFileReader.h>
-
-#include <vtkCamera.h>
-#include <vtkImageActor.h>
-#include <vtkInteractorStyleImage.h>
-#include <vtkPointHandleRepresentation3D.h>
-#include <vtkProperty.h>
-#include <vtkRenderer.h>
-#include <vtkRenderWindow.h>
-#include <vtkRenderWindowInteractor.h>
-#include <vtkSeedRepresentation.h>
-#include <vtkSeedWidget.h>
-#include <vtkSmartPointer.h>
+#include <itkImageToVTKImageFilter.h>
 
 #include <fpa/Image/RegionGrow.h>
-#include <fpa/Base/Functors/TautologyFunction.h>
+#include <fpa/Image/Functors/RegionGrowAllBelongsFunction.h>
 #include <fpa/VTK/Image2DObserver.h>
 
+#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 (file)
index 0000000..4f65ce6
--- /dev/null
@@ -0,0 +1,98 @@
+#include <cstdlib>
+#include <iostream>
+#include <limits>
+#include <string>
+
+#include <itkImage.h>
+#include <itkImageToVTKImageFilter.h>
+
+#include <fpa/Image/RegionGrow.h>
+#include <fpa/Image/Functors/RegionGrowThresholdFunction.h>
+#include <fpa/VTK/Image2DObserver.h>
+
+#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 (file)
index 0000000..0dc0137
--- /dev/null
@@ -0,0 +1,100 @@
+#include <cstdlib>
+#include <iostream>
+#include <limits>
+#include <string>
+
+#include <itkImage.h>
+#include <itkRGBPixel.h>
+#include <itkImageToVTKImageFilter.h>
+
+#include <fpa/Image/RegionGrow.h>
+#include <fpa/Image/Functors/RegionGrowThresholdFunction.h>
+#include <fpa/VTK/Image2DObserver.h>
+
+#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 (file)
index 0000000..47affc1
--- /dev/null
@@ -0,0 +1,164 @@
+#include <cstdlib>
+#include <iostream>
+#include <fstream>
+#include <limits>
+#include <string>
+#include <vector>
+
+#include <itkImage.h>
+#include <itkImageToVTKImageFilter.h>
+
+#include <itkImageFileReader.h>
+#include <itkImageFileWriter.h>
+
+#include <vtkCamera.h>
+#include <vtkImageActor.h>
+#include <vtkInteractorStyleImage.h>
+#include <vtkPointHandleRepresentation3D.h>
+#include <vtkProperty.h>
+#include <vtkRenderer.h>
+#include <vtkRenderWindow.h>
+#include <vtkRenderWindowInteractor.h>
+#include <vtkSeedRepresentation.h>
+#include <vtkSeedWidget.h>
+#include <vtkSmartPointer.h>
+
+#include <fpa/Image/Dijkstra.h>
+#include <fpa/Image/Functors/ImageAbsoluteDifferenceCostFunction.h>
+#include <fpa/VTK/ImageMPR.h>
+#include <fpa/VTK/Image3DObserver.h>
+
+// -------------------------------------------------------------------------
+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 (file)
index 0000000..4cdf521
--- /dev/null
@@ -0,0 +1,157 @@
+#ifndef __FPA__UTILITY__H__
+#define __FPA__UTILITY__H__
+
+#include <sstream>
+
+#include <itkImageFileReader.h>
+#include <itkImageFileWriter.h>
+
+#include <vtkCamera.h>
+#include <vtkImageActor.h>
+#include <vtkImageData.h>
+#include <vtkInteractorStyleImage.h>
+#include <vtkPointHandleRepresentation3D.h>
+#include <vtkProperty.h>
+#include <vtkRenderer.h>
+#include <vtkRenderWindow.h>
+#include <vtkRenderWindowInteractor.h>
+#include <vtkSeedRepresentation.h>
+#include <vtkSeedWidget.h>
+#include <vtkSmartPointer.h>
+
+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$
index 1ddfbb5374b354823894293fc96a1c03b65f48bb..6973e3225283c3c5e5f1d688bf05bde7324b5b15 100644 (file)
@@ -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$
index cc8497d558354409c7389626f36daebd3eeb8710..132c61057c696e47dc18c33e99220a5776757577 100644 (file)
@@ -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 );
index dbcdc608614faeb297e0a8403cf02c97dc1d015c..aa1c283a8864a370fa5c47948dd3256abc16783e 100644 (file)
@@ -5,8 +5,8 @@
 #include <itkProcessObject.h>
 
 // -------------------------------------------------------------------------
-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( );
index 602608eb9973cfbf0849cbd8db594b5b3a2b5d6f..69fe86a798289509fb31557b6927c90dbbd64466 100644 (file)
@@ -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;
     };
 
index 2a2ccf5403d6ecf62b56f583e79e1d3eca807735..25d56504051fbb1b2b1bccd01a9a239487764051 100644 (file)
@@ -4,23 +4,24 @@
 #include <algorithm>
 
 // -------------------------------------------------------------------------
-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( );
index f79666d1d6137129a3a2ff55e0c08fb90599a647..d8eec46b9b5ce1aaa6aeb8456c48cdb7877c9482 100644 (file)
@@ -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 (file)
index 0000000..7385f91
--- /dev/null
@@ -0,0 +1,85 @@
+#ifndef __FPA__BASE__INCREMENTALREGIONGROW__H__
+#define __FPA__BASE__INCREMENTALREGIONGROW__H__
+
+#include <vector>
+#include <itkFunctionBase.h>
+#include <fpa/Base/RegionGrow.h>
+
+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 <fpa/Base/IncrementalRegionGrow.hxx>
+
+#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 (file)
index 0000000..d5d9447
--- /dev/null
@@ -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$
index 0b5b79744c547a1daa588856128c984590344158..b5ce46e3a6449042659d3858c4ca1d288f09da42 100644 (file)
@@ -4,6 +4,7 @@
 #include <queue>
 #include <utility>
 #include <fpa/Base/Algorithm.h>
+#include <fpa/Base/Functors/TautologyFunction.h>
 
 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
index f0c45121eb5b2a5ea5e883c415ec0a7507593646..1760ac1eb9b89d2f5b3937eb1e550b158fb0d434 100644 (file)
@@ -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 )
index bc2b17cbea00c545daa62292451150d701cbf1cd..eb554bbe73740116fc45307a55c3d2cde2e6ec5f 100644 (file)
@@ -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( )
index efb376b974e5d3ef726edea76f7afe490effb7f5..9a44146ddee238464b799a7faa236554273dedd5 100644 (file)
@@ -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;
 
index e38fd0d12cd53b3ed0bcaa20c5aad0576a3d6a10..45759cb9c1fa5b9d0cb880dee10068414b2468f0 100644 (file)
@@ -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;
index b32d68a2bbb5f8dc0cc6db563968a1321f8f654e..13da72994d5e74327595f7d3409721cc7316680c 100644 (file)
@@ -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;
index dc51a6442c0a66f7ed77663c25e8bb3c161923a7..cb417f027092de357d1353ff18b4cd367f860729 100644 (file)
@@ -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 (file)
index 0000000..6171f26
--- /dev/null
@@ -0,0 +1,87 @@
+#ifndef __FPA__IMAGE__FUNCTORS__IMAGEABSOLUTEDIFFERENCECOSTFUNCTION__H__
+#define __FPA__IMAGE__FUNCTORS__IMAGEABSOLUTEDIFFERENCECOSTFUNCTION__H__
+
+#include <fpa/Image/Functors/ImageCostFunction.h>
+
+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$
index e352f59817c934bd6528eb21ac8344b0a6ff09b3..362304fc07233a20c86d0be5db6834fa6e7266a6 100644 (file)
@@ -1,7 +1,7 @@
 #ifndef __FPA__IMAGE__FUNCTORS__REGIONGROWALLBELONGSFUNCTION__H__
 #define __FPA__IMAGE__FUNCTORS__REGIONGROWALLBELONGSFUNCTION__H__
 
-#include <fpa/Image/Functors/ImageFunction.h>
+#include <fpa/Base/Functors/TautologyFunction.h>
 
 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:
index 739dff4c24beb40c6d76c94e3977bef3d02bc588..3d7d5ac8b167ff413ead2f2ac13d18b6057d1e4c 100644 (file)
@@ -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 (file)
index 0000000..a2a1156
--- /dev/null
@@ -0,0 +1,69 @@
+#ifndef __FPA__IMAGE__INCREMENTALREGIONGROW__H__
+#define __FPA__IMAGE__INCREMENTALREGIONGROW__H__
+
+#include <itkFunctionBase.h>
+#include <itkImageToImageFilter.h>
+#include <itkIndex.h>
+#include <fpa/Base/IncrementalRegionGrow.h>
+#include <fpa/Image/Algorithm.h>
+
+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 <fpa/Image/IncrementalRegionGrow.hxx>
+
+#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 (file)
index 0000000..740b2f8
--- /dev/null
@@ -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$
index 71db89cb1eb04e2abb06a5b310ffcfed20512f10..b8147985d53f1fb60c6e99bcd5f28a80d6dc8792 100644 (file)
@@ -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
index e8e92c89c07f152abef9d45551e6c740cf348758..9b5b0f792ba457240aa28ecf7530d697c44b5d06 100644 (file)
@@ -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 );
 }
 
index fd6247ffb6be1d7d881b1fc5b5da048ed67eb2ae..49d5577b98fedf0baf3744c55a75849f73cdc18c 100644 (file)
@@ -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
 }
 
 // -------------------------------------------------------------------------
index 721a89d5309f60c635134b8d6446069a8f263d03..3baac71ad98741f2781a5ce53a4366b28773aa50 100644 (file)
@@ -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 =
index 1cc4b85f6947b1528e8bed346d46e2edba874ad3..c3084535a168884b67b53816337935974c2476a9 100644 (file)
@@ -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
index e64ff8aa799637111d64e98796f685af26d2af21..978738ae16415e25e4f0733c4bdb6e6bd458094c 100644 (file)
@@ -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 (file)
index 0000000..ed9785f
--- /dev/null
@@ -0,0 +1,67 @@
+#ifndef __FPA__VTK__UNIQUEVERTICESTOPOLYDATAFILTER__H__
+#define __FPA__VTK__UNIQUEVERTICESTOPOLYDATAFILTER__H__
+
+#include <vtkPolyDataAlgorithm.h>
+
+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 <fpa/VTK/UniqueVerticesToPolyDataFilter.hxx>
+
+#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 (file)
index 0000000..c2d2629
--- /dev/null
@@ -0,0 +1,186 @@
+#ifndef __FPA__VTK__UNIQUEVERTICESTOPOLYDATAFILTER__HXX__
+#define __FPA__VTK__UNIQUEVERTICESTOPOLYDATAFILTER__HXX__
+
+#include <vtkInformation.h>
+#include <vtkInformationVector.h>
+
+// -------------------------------------------------------------------------
+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$