]> Creatis software - FrontAlgorithms.git/commitdiff
Major refactoring
authorLeonardo Florez-Valencia <florez-l@javeriana.edu.co>
Sat, 4 Apr 2015 16:24:17 +0000 (11:24 -0500)
committerLeonardo Florez-Valencia <florez-l@javeriana.edu.co>
Sat, 4 Apr 2015 16:24:17 +0000 (11:24 -0500)
29 files changed:
appli/CMakeLists.txt
appli/examples/CMakeLists.txt
appli/examples/example_ImageAlgorithmRegionGrow_GaussianModelEstimator.cxx
appli/examples/example_Image_Dijkstra_CostFromInput.cxx [new file with mode: 0644]
appli/examples/example_Image_Dijkstra_CostFromRGBInput.cxx [new file with mode: 0644]
appli/examples/example_Image_Dijkstra_DanielssonCost.cxx [new file with mode: 0644]
appli/examples/example_Image_RegionGrow_AllPixels.cxx [new file with mode: 0644]
appli/examples/example_Image_RegionGrow_AllRGBPixels.cxx [new file with mode: 0644]
doc/UML/fpa.dia [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/Events.h
lib/fpa/Base/Functors/InvertCostFunction.h
lib/fpa/Base/Functors/TautologyFunction.h [new file with mode: 0644]
lib/fpa/Base/RegionGrow.h
lib/fpa/Base/RegionGrow.hxx
lib/fpa/Image/Algorithm.h
lib/fpa/Image/Algorithm.hxx
lib/fpa/Image/Dijkstra.h
lib/fpa/Image/Dijkstra.hxx [new file with mode: 0644]
lib/fpa/Image/Functors/ImageCostFunction.h [new file with mode: 0644]
lib/fpa/Image/Functors/ImageFunction.h [deleted file]
lib/fpa/Image/RegionGrow.h
lib/fpa/Image/RegionGrow.hxx [new file with mode: 0644]
lib/fpa/VTK/Image2DObserver.h
lib/fpa/VTK/Image2DObserver.hxx

index 71b459c31e305aa3ba1c6ac99d8b29e7a1ee6dce..61d2cd0328ceeecb594c40e83e1d405a4e6b0c83 100644 (file)
@@ -1,6 +1,7 @@
-
-SUBDIRS(
-  examples
-  )
+IF(BUILD_EXAMPLES)
+  SUBDIRS(
+    examples
+    )
+ENDIF(BUILD_EXAMPLES)
 
 ## eof - $RCSfile$
index ad80e0a91bc753d5a423ab483bef62af05a48d09..985071e16c2f9032570a91adb05acd6070ad9227 100644 (file)
@@ -1,58 +1,73 @@
-IF(BUILD_EXAMPLES)
+IF(USE_VTK)
   SET(
-    APPLIS
-    example_Thinning
-    example_BinaryDistanceMap
-    example_HausdorffDistance
-    example_ImageAlgorithmRegionGrow_00
-    example_ImageAlgorithmDijkstra_00
-    example_ImageAlgorithmFastMarching_00
+    SIMPLE_VTK_EXAMPLES
+    example_Image_RegionGrow_AllPixels
+    example_Image_RegionGrow_AllRGBPixels
+    example_Image_Dijkstra_CostFromInput
+    example_Image_Dijkstra_CostFromRGBInput
+    example_Image_Dijkstra_DanielssonCost
     )
+  FOREACH(EX ${SIMPLE_VTK_EXAMPLES})
+    ADD_EXECUTABLE(${EX} ${EX}.cxx)
+    TARGET_LINK_LIBRARIES(${EX} FrontAlgorithms)
+  ENDFOREACH(EX)
+ENDIF(USE_VTK)
 
-  FOREACH(APP ${APPLIS})
-    ADD_EXECUTABLE(${APP} ${APP}.cxx)
-    TARGET_LINK_LIBRARIES(${APP} FrontAlgorithms)
-  ENDFOREACH(APP)
-
-  IF(USE_VTK)
-    SET(
-      vtk_APPLIS
-      example_ImageAlgorithmRegionGrow_01
-      example_ImageAlgorithmRegionGrow_MultipleThresholds
-      example_ImageAlgorithmDijkstra_01
-      example_ImageAlgorithmDijkstra_02
-      example_ImageAlgorithmDijkstra_03
-      example_ImageAlgorithmFastMarching_01
-      example_ImageAlgorithm_Skeletonization
-      )
-
-    FOREACH(APP ${vtk_APPLIS})
-      ADD_EXECUTABLE(${APP} ${APP}.cxx)
-      TARGET_LINK_LIBRARIES(
-        ${APP}
-        FrontAlgorithms
-        ${VTK_LIBRARIES} vtkIOLegacy
-        )
-    ENDFOREACH(APP)
-
-    IF(USE_cpPlugins)
-      SET(
-        cpPlugins_APPLIS
-        example_ImageAlgorithmRegionGrow_GaussianModelEstimator
-        )
-
-      FOREACH(APP ${cpPlugins_APPLIS})
-        ADD_EXECUTABLE(${APP} ${APP}.cxx)
-        TARGET_LINK_LIBRARIES(
-          ${APP}
-          FrontAlgorithms
-          ${cpPlugins_Extensions_LIBRARY_NAME}
-          )
-      ENDFOREACH(APP)
-
-    ENDIF(USE_cpPlugins)
-
-  ENDIF(USE_VTK)
-ENDIF(BUILD_EXAMPLES)
+#IF(BUILD_EXAMPLES)
+#  SET(
+#    APPLIS
+#    example_Thinning
+#    example_BinaryDistanceMap
+#    example_HausdorffDistance
+#    example_ImageAlgorithmRegionGrow_00
+#    example_ImageAlgorithmDijkstra_00
+#    example_ImageAlgorithmFastMarching_00
+#    )
+
+#  FOREACH(APP ${APPLIS})
+#    ADD_EXECUTABLE(${APP} ${APP}.cxx)
+#    TARGET_LINK_LIBRARIES(${APP} FrontAlgorithms)
+#  ENDFOREACH(APP)
+
+#  IF(USE_VTK)
+#    SET(
+#      vtk_APPLIS
+#      example_ImageAlgorithmRegionGrow_01
+#      example_ImageAlgorithmRegionGrow_MultipleThresholds
+#      example_ImageAlgorithmDijkstra_01
+#      example_ImageAlgorithmDijkstra_02
+#      example_ImageAlgorithmDijkstra_03
+#      example_ImageAlgorithmFastMarching_01
+#      example_ImageAlgorithm_Skeletonization
+#      )
+
+#    FOREACH(APP ${vtk_APPLIS})
+#      ADD_EXECUTABLE(${APP} ${APP}.cxx)
+#      TARGET_LINK_LIBRARIES(
+#        ${APP}
+#        FrontAlgorithms
+#        ${VTK_LIBRARIES} vtkIOLegacy
+#        )
+#    ENDFOREACH(APP)
+
+#    IF(USE_cpPlugins)
+#      SET(
+#        cpPlugins_APPLIS
+#        example_ImageAlgorithmRegionGrow_GaussianModelEstimator
+#        )
+
+#      FOREACH(APP ${cpPlugins_APPLIS})
+#        ADD_EXECUTABLE(${APP} ${APP}.cxx)
+#        TARGET_LINK_LIBRARIES(
+#          ${APP}
+#          FrontAlgorithms
+#          ${cpPlugins_Extensions_LIBRARY_NAME}
+#          )
+#      ENDFOREACH(APP)
+
+#    ENDIF(USE_cpPlugins)
+
+#  ENDIF(USE_VTK)
+#ENDIF(BUILD_EXAMPLES)
 
 ## eof - $RCSfile$
index 850ef5a1eed762744cff64db464d8afe5f8124ba..04fa936b43f9a1a0ca6bd8b95ac6836402ee9094 100644 (file)
@@ -22,6 +22,7 @@
 #include <fpa/Image/Functors/RegionGrowAllBelongsFunction.h>
 #include <fpa/VTK/Image2DObserver.h>
 #include <cpPlugins/Extensions/Algorithms/IterativeGaussianModelEstimator.h>
+#include <cpPlugins/Extensions/Algorithms/RGBToYPbPrFunction.h>
 
 // -------------------------------------------------------------------------
 const unsigned int Dim = 2;
@@ -57,6 +58,7 @@ public:
   typedef typename Superclass::TIndex       TIndex;
 
   typedef cpPlugins::Extensions::Algorithms::IterativeGaussianModelEstimator< S, 3 > TEstimator;
+  typedef cpPlugins::Extensions::Algorithms::RGBToYPbPrFunction< S > TYPbPrFunction;
 
 public:
   itkNewMacro( Self );
@@ -96,22 +98,26 @@ public:
       {
         if( !( this->m_Marks->GetPixel( idx ) ) )
         {
-          this->m_Estimator->AddSample(
-            S( rgb.GetRed( ) ),
-            S( rgb.GetGreen( ) ),
-            S( rgb.GetBlue( ) )
-            );
+          this->m_Estimator->AddSample( this->m_YPbPrFunction( rgb ) );
           this->m_Marks->SetPixel( idx, true );
-#error CONTINUE HERE!!!!
-          std::cout << this->m_Estimator->GetNumberOfSamples( ) << " " << this->m_ModelSupport << std::endl;
           if( this->m_Estimator->GetNumberOfSamples( ) == this->m_ModelSupport )
+          {
             this->m_Estimating = true;
+            this->m_Estimator->UpdateModel( );
+            std::cout << this->m_Estimator->GetMinimumProbability( ) << std::endl;
+            std::cout << this->m_Estimator->GetMaximumProbability( ) << std::endl;
+
+          } // fi
 
         } // fi
         return( true );
       }
       else
-        return( false );
+      {
+        S p = this->m_Estimator->Probability( this->m_YPbPrFunction( rgb ) );
+        return( p > this->m_Estimator->GetMinimumProbability( ) );
+
+      } // fi
     }
 
 protected:
@@ -133,6 +139,8 @@ private:
 
 protected:
   typename TEstimator::Pointer m_Estimator;
+  TYPbPrFunction m_YPbPrFunction;
+
   unsigned long m_ModelSupport;
   mutable bool m_Estimating;
   typename TMarks::Pointer m_Marks;
diff --git a/appli/examples/example_Image_Dijkstra_CostFromInput.cxx b/appli/examples/example_Image_Dijkstra_CostFromInput.cxx
new file mode 100644 (file)
index 0000000..65003e2
--- /dev/null
@@ -0,0 +1,177 @@
+#include <cstdlib>
+#include <iostream>
+#include <limits>
+#include <string>
+
+#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/VTK/Image2DObserver.h>
+
+// -------------------------------------------------------------------------
+const unsigned int Dim = 2;
+typedef unsigned char 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 < 5 )
+  {
+    std::cerr
+      << "Usage: " << argv[ 0 ]
+      << " input_image output_image neighborhood_order stop_at_one_front"
+      << 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 );
+
+  // 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( );
+
+  // 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( );
+
+  // Prepare region grow filter
+  typedef fpa::Image::Dijkstra< TInputImage, TOutputImage > TFilter;
+  TFilter::Pointer filter = TFilter::New( );
+  filter->SetInput( input_image );
+  filter->SetNeighborhoodOrder( neighborhood_order );
+  filter->SetStopAtOneFront( stop_at_one_front );
+
+  // Get user-given seeds
+  for( unsigned int s = 0; s < rep->GetNumberOfSeeds( ); s++ )
+  {
+    double pos[ 3 ];
+    rep->GetSeedWorldPosition( s, pos );
+
+    TInputImage::PointType pnt;
+    pnt[ 0 ] = TInputImage::PointType::ValueType( pos[ 0 ] );
+    pnt[ 1 ] = TInputImage::PointType::ValueType( pos[ 1 ] );
+
+    TInputImage::IndexType idx;
+    if( input_image->TransformPhysicalPointToIndex( pnt, idx ) )
+      filter->AddSeed( idx, 0 );
+
+  } // rof
+
+  // Prepare graphical debugger
+  typedef fpa::VTK::Image2DObserver< TFilter, vtkRenderWindow > TDebugger;
+  TDebugger::Pointer debugger = TDebugger::New( );
+  debugger->SetRenderWindow( window );
+  debugger->SetRenderPercentage( 0.001 );
+  filter->AddObserver( itk::AnyEvent( ), debugger );
+  filter->ThrowEventsOn( );
+
+  // Go!
+  filter->Update( );
+
+  // Save final total cost map
+  itk::ImageFileWriter< TOutputImage >::Pointer output_image_writer =
+    itk::ImageFileWriter< TOutputImage >::New( );
+  output_image_writer->SetFileName( output_image_fn );
+  output_image_writer->SetInput( filter->GetOutput( ) );
+  try
+  {
+    output_image_writer->Update( );
+  }
+  catch( itk::ExceptionObject& err )
+  {
+    std::cerr
+      << "Error while writing image to " << output_image_fn << ": "
+      << err << std::endl;
+    return( 1 );
+
+  } // yrt
+
+  return( 0 );
+}
+
+// eof - $RCSfile$
diff --git a/appli/examples/example_Image_Dijkstra_CostFromRGBInput.cxx b/appli/examples/example_Image_Dijkstra_CostFromRGBInput.cxx
new file mode 100644 (file)
index 0000000..c181359
--- /dev/null
@@ -0,0 +1,178 @@
+#include <cstdlib>
+#include <iostream>
+#include <limits>
+#include <string>
+
+#include <itkImage.h>
+#include <itkImageToVTKImageFilter.h>
+#include <itkRGBPixel.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/VTK/Image2DObserver.h>
+
+// -------------------------------------------------------------------------
+const unsigned int Dim = 2;
+typedef itk::RGBPixel< unsigned char > 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 < 5 )
+  {
+    std::cerr
+      << "Usage: " << argv[ 0 ]
+      << " input_image output_image neighborhood_order stop_at_one_front"
+      << 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 );
+
+  // 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( );
+
+  // 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( );
+
+  // Prepare region grow filter
+  typedef fpa::Image::Dijkstra< TInputImage, TOutputImage > TFilter;
+  TFilter::Pointer filter = TFilter::New( );
+  filter->SetInput( input_image );
+  filter->SetNeighborhoodOrder( neighborhood_order );
+  filter->SetStopAtOneFront( stop_at_one_front );
+
+  // Get user-given seeds
+  for( unsigned int s = 0; s < rep->GetNumberOfSeeds( ); s++ )
+  {
+    double pos[ 3 ];
+    rep->GetSeedWorldPosition( s, pos );
+
+    TInputImage::PointType pnt;
+    pnt[ 0 ] = TInputImage::PointType::ValueType( pos[ 0 ] );
+    pnt[ 1 ] = TInputImage::PointType::ValueType( pos[ 1 ] );
+
+    TInputImage::IndexType idx;
+    if( input_image->TransformPhysicalPointToIndex( pnt, idx ) )
+      filter->AddSeed( idx, 0 );
+
+  } // rof
+
+  // Prepare graphical debugger
+  typedef fpa::VTK::Image2DObserver< TFilter, vtkRenderWindow > TDebugger;
+  TDebugger::Pointer debugger = TDebugger::New( );
+  debugger->SetRenderWindow( window );
+  debugger->SetRenderPercentage( 0.001 );
+  filter->AddObserver( itk::AnyEvent( ), debugger );
+  filter->ThrowEventsOn( );
+
+  // Go!
+  filter->Update( );
+
+  // Save final total cost map
+  itk::ImageFileWriter< TOutputImage >::Pointer output_image_writer =
+    itk::ImageFileWriter< TOutputImage >::New( );
+  output_image_writer->SetFileName( output_image_fn );
+  output_image_writer->SetInput( filter->GetOutput( ) );
+  try
+  {
+    output_image_writer->Update( );
+  }
+  catch( itk::ExceptionObject& err )
+  {
+    std::cerr
+      << "Error while writing image to " << output_image_fn << ": "
+      << err << std::endl;
+    return( 1 );
+
+  } // yrt
+
+  return( 0 );
+}
+
+// eof - $RCSfile$
diff --git a/appli/examples/example_Image_Dijkstra_DanielssonCost.cxx b/appli/examples/example_Image_Dijkstra_DanielssonCost.cxx
new file mode 100644 (file)
index 0000000..3eb387f
--- /dev/null
@@ -0,0 +1,204 @@
+#include <cstdlib>
+#include <iostream>
+#include <limits>
+#include <string>
+
+#include <itkImage.h>
+#include <itkImageToVTKImageFilter.h>
+
+#include <itkImageFileReader.h>
+#include <itkMinimumMaximumImageCalculator.h>
+#include <itkInvertIntensityImageFilter.h>
+#include <itkDanielssonDistanceMapImageFilter.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/Base/Functors/InvertCostFunction.h>
+#include <fpa/VTK/Image2DObserver.h>
+
+// -------------------------------------------------------------------------
+const unsigned int Dim = 2;
+typedef unsigned char 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 < 5 )
+  {
+    std::cerr
+      << "Usage: " << argv[ 0 ]
+      << " input_image output_image neighborhood_order stop_at_one_front"
+      << 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 );
+
+  // 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( );
+
+  // 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( );
+
+  // Invert input image
+  itk::MinimumMaximumImageCalculator< TInputImage >::Pointer minmax =
+    itk::MinimumMaximumImageCalculator< TInputImage >::New( );
+  minmax->SetImage( input_image );
+  minmax->Compute( );
+
+  itk::InvertIntensityImageFilter< TInputImage >::Pointer invert =
+    itk::InvertIntensityImageFilter< TInputImage >::New( );
+  invert->SetInput( input_image );
+  invert->SetMaximum( minmax->GetMaximum( ) );
+
+  itk::DanielssonDistanceMapImageFilter< TInputImage, TOutputImage >::Pointer dmap =
+    itk::DanielssonDistanceMapImageFilter< TInputImage, TOutputImage >::New( );
+  dmap->SetInput( invert->GetOutput( ) );
+  dmap->InputIsBinaryOn( );
+  dmap->SquaredDistanceOn( );
+  dmap->UseImageSpacingOn( );
+  dmap->Update( );
+
+  typedef fpa::Base::Functors::InvertCostFunction< TOutputPixel > TFunction;
+  TFunction::Pointer function = TFunction::New( );
+
+  // Prepare region grow filter
+  typedef fpa::Image::Dijkstra< TOutputImage, TOutputImage > TFilter;
+  TFilter::Pointer filter = TFilter::New( );
+  filter->SetInput( dmap->GetOutput( ) );
+  filter->SetConversionFunction( function );
+  filter->SetNeighborhoodOrder( neighborhood_order );
+  filter->SetStopAtOneFront( stop_at_one_front );
+
+  // Get user-given seeds
+  for( unsigned int s = 0; s < rep->GetNumberOfSeeds( ); s++ )
+  {
+    double pos[ 3 ];
+    rep->GetSeedWorldPosition( s, pos );
+
+    TInputImage::PointType pnt;
+    pnt[ 0 ] = TInputImage::PointType::ValueType( pos[ 0 ] );
+    pnt[ 1 ] = TInputImage::PointType::ValueType( pos[ 1 ] );
+
+    TInputImage::IndexType idx;
+    if( input_image->TransformPhysicalPointToIndex( pnt, idx ) )
+      filter->AddSeed( idx, 0 );
+
+  } // rof
+
+  // Prepare graphical debugger
+  typedef fpa::VTK::Image2DObserver< TFilter, vtkRenderWindow > TDebugger;
+  TDebugger::Pointer debugger = TDebugger::New( );
+  debugger->SetRenderWindow( window );
+  debugger->SetRenderPercentage( 0.001 );
+  filter->AddObserver( itk::AnyEvent( ), debugger );
+  filter->ThrowEventsOn( );
+
+  // Go!
+  filter->Update( );
+
+  // Save final total cost map
+  itk::ImageFileWriter< TOutputImage >::Pointer output_image_writer =
+    itk::ImageFileWriter< TOutputImage >::New( );
+  output_image_writer->SetFileName( output_image_fn );
+  output_image_writer->SetInput( filter->GetOutput( ) );
+  try
+  {
+    output_image_writer->Update( );
+  }
+  catch( itk::ExceptionObject& err )
+  {
+    std::cerr
+      << "Error while writing image to " << output_image_fn << ": "
+      << err << std::endl;
+    return( 1 );
+
+  } // yrt
+
+  return( 0 );
+}
+
+// eof - $RCSfile$
diff --git a/appli/examples/example_Image_RegionGrow_AllPixels.cxx b/appli/examples/example_Image_RegionGrow_AllPixels.cxx
new file mode 100644 (file)
index 0000000..fffb58a
--- /dev/null
@@ -0,0 +1,163 @@
+#include <cstdlib>
+#include <iostream>
+#include <limits>
+#include <string>
+
+#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/VTK/Image2DObserver.h>
+
+// -------------------------------------------------------------------------
+const unsigned int Dim = 2;
+typedef unsigned char TPixel;
+
+typedef itk::Image< TPixel, Dim >            TImage;
+typedef itk::ImageToVTKImageFilter< TImage > TVTKImage;
+
+// -------------------------------------------------------------------------
+int main( int argc, char* argv[] )
+{
+  if( argc < 4 )
+  {
+    std::cerr
+      << "Usage: " << argv[ 0 ]
+      << " input_image neighborhood_order stop_at_one_front"
+      << std::endl;
+    return( 1 );
+
+  } // fi
+  std::string input_image_fn = argv[ 1 ];
+  unsigned int neighborhood_order = std::atoi( argv[ 2 ] );
+  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
+  {
+    input_image_reader->Update( );
+  }
+  catch( itk::ExceptionObject& err )
+  {
+    std::cerr
+      << "Error while reading image from " << input_image_fn << ": "
+      << err << std::endl;
+    return( 1 );
+
+  } // yrt
+  TImage::ConstPointer input_image = input_image_reader->GetOutput( );
+  TVTKImage::Pointer vtk_input_image = TVTKImage::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( );
+
+  // 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->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++ )
+  {
+    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;
+    if( input_image->TransformPhysicalPointToIndex( pnt, idx ) )
+      filter->AddSeed( idx, 0 );
+
+  } // rof
+
+  // Prepare graphical debugger
+  typedef fpa::VTK::Image2DObserver< TFilter, vtkRenderWindow > TDebugger;
+  TDebugger::Pointer debugger = TDebugger::New( );
+  debugger->SetRenderWindow( window );
+  debugger->SetRenderPercentage( 0.001 );
+  filter->AddObserver( itk::AnyEvent( ), debugger );
+  filter->ThrowEventsOn( );
+
+  // Go!
+  filter->Update( );
+
+  return( 0 );
+}
+
+// eof - $RCSfile$
diff --git a/appli/examples/example_Image_RegionGrow_AllRGBPixels.cxx b/appli/examples/example_Image_RegionGrow_AllRGBPixels.cxx
new file mode 100644 (file)
index 0000000..fdb90fa
--- /dev/null
@@ -0,0 +1,165 @@
+#include <cstdlib>
+#include <iostream>
+#include <limits>
+#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 <fpa/Image/RegionGrow.h>
+#include <fpa/Base/Functors/TautologyFunction.h>
+#include <fpa/VTK/Image2DObserver.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[] )
+{
+  if( argc < 4 )
+  {
+    std::cerr
+      << "Usage: " << argv[ 0 ]
+      << " input_image neighborhood_order stop_at_one_front"
+      << std::endl;
+    return( 1 );
+
+  } // fi
+  std::string input_image_fn = argv[ 1 ];
+  unsigned int neighborhood_order = std::atoi( argv[ 2 ] );
+  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
+  {
+    input_image_reader->Update( );
+  }
+  catch( itk::ExceptionObject& err )
+  {
+    std::cerr
+      << "Error while reading image from " << input_image_fn << ": "
+      << err << std::endl;
+    return( 1 );
+
+  } // yrt
+  TColorImage::ConstPointer input_image = input_image_reader->GetOutput( );
+  TVTKImage::Pointer vtk_input_image = TVTKImage::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( );
+
+  // 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->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++ )
+  {
+    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;
+    if( input_image->TransformPhysicalPointToIndex( pnt, idx ) )
+      filter->AddSeed( idx, 0 );
+
+  } // rof
+
+  // Prepare graphical debugger
+  typedef fpa::VTK::Image2DObserver< TFilter, vtkRenderWindow > TDebugger;
+  TDebugger::Pointer debugger = TDebugger::New( );
+  debugger->SetRenderWindow( window );
+  debugger->SetRenderPercentage( 0.001 );
+  filter->AddObserver( itk::AnyEvent( ), debugger );
+  filter->ThrowEventsOn( );
+
+  // Go!
+  filter->Update( );
+
+  return( 0 );
+}
+
+// eof - $RCSfile$
diff --git a/doc/UML/fpa.dia b/doc/UML/fpa.dia
new file mode 100644 (file)
index 0000000..8ed637d
Binary files /dev/null and b/doc/UML/fpa.dia differ
index ebff1036a33df818926f78fe467a1572bf2af885..28c4df364af77e1e7457775f37b86a4c416b5d73 100644 (file)
@@ -57,11 +57,19 @@ GENERATE_EXPORT_HEADER(
   EXPORT_FILE_NAME ${PROJECT_BINARY_DIR}/lib/fpa/${LIB_NAME}_Export.h
   STATIC_DEFINE ${LIB_NAME}_BUILT_AS_STATIC
   )
-TARGET_LINK_LIBRARIES(
-  ${LIB_NAME}
-  ${${LIB_NAME}_LINK_LIBRARIES}
-  ${ITK_LIBRARIES}
-  vtkInteractionWidgets
-  )
+IF(USE_VTK)
+  TARGET_LINK_LIBRARIES(
+    ${LIB_NAME}
+    ${${LIB_NAME}_LINK_LIBRARIES}
+    ${ITK_LIBRARIES}
+    vtkInteractionWidgets
+    )
+ELSE(USE_VTK)
+  TARGET_LINK_LIBRARIES(
+    ${LIB_NAME}
+    ${${LIB_NAME}_LINK_LIBRARIES}
+    ${ITK_LIBRARIES}
+    )
+ENDIF(USE_VTK)
 
 ## eof - $RCSfile$
index c9b2e1aff5fb564306ab6369a3a905c6b7b98b69..35c6a378d09d3ede36655be646d39abfa616659b 100644 (file)
@@ -1,9 +1,8 @@
 #ifndef __FPA__BASE__ALGORITHM__H__
 #define __FPA__BASE__ALGORITHM__H__
 
-#include <map>
-#include <vector>
 #include <utility>
+#include <vector>
 #include <fpa/Base/Events.h>
 
 namespace fpa
@@ -16,67 +15,85 @@ namespace fpa
      * vertex could be marked as "visited", "in the front", "not yet there"
      * or "freezed".
      *
-     * @param T Traits used for this algorithm
+     * @param V Vertex type.
+     * @param C Vertex value type.
+     * @param R Result value type.
+     * @param B Base class for this algorithm. It should be any itk-based
+     *          filter (itk::ProcessObject).
+     *
      */
-    template< class T, class B >
+    template< class V, class C, class R, class B >
     class Algorithm
       : public B
     {
     public:
-      // Standard class typdedefs
       typedef Algorithm                       Self;
       typedef B                               Superclass;
       typedef itk::SmartPointer< Self >       Pointer;
       typedef itk::SmartPointer< const Self > ConstPointer;
 
-      /// Templated types
-      typedef T TTraits;
-      typedef B TBaseFilter;
-      typedef typename T::TCost        TCost;
-      typedef typename T::TResult      TResult;
-      typedef typename T::TVertex      TVertex;
-      typedef typename T::TVertexValue TVertexValue;
-
-    protected:
-      typedef typename T::TFrontId   _TFrontId;
-      typedef typename T::TNode      _TNode;
-      typedef typename T::TNodes     _TNodes;
-      typedef typename T::TVertexCmp _TVertexCmp;
-
-      typedef std::map< TVertex, _TNode, _TVertexCmp >   _TMarks;
+      typedef V TVertex;
+      typedef C TValue;
+      typedef R TResult;
 
-      typedef std::pair< TVertex, bool >         _TCollision;
-      typedef std::vector< _TCollision >         _TCollisionSitesRow;
-      typedef std::vector< _TCollisionSitesRow > _TCollisionSites;
+      fpa_Base_NewEvent( TStartEvent );
+      fpa_Base_NewEvent( TStartLoopEvent );
+      fpa_Base_NewEvent( TEndEvent );
+      fpa_Base_NewEvent( TEndLoopEvent );
+      fpa_Base_NewEventWithVertex( TAliveEvent, TVertex );
+      fpa_Base_NewEventWithVertex( TFrontEvent, TVertex );
+      fpa_Base_NewEventWithVertex( TFreezeEvent, TVertex );
 
-    public:
-      typedef BaseEvent< _TNode >             TEvent;
-      typedef FrontEvent< _TNode >            TFrontEvent;
-      typedef MarkEvent< _TNode >             TMarkEvent;
-      typedef CollisionEvent< _TNode >        TCollisionEvent;
-      typedef EndEvent< _TNode >              TEndEvent;
-      typedef BacktrackingEvent< TVertex >    TBacktrackingEvent;
-      typedef EndBacktrackingEvent< TVertex > TEndBacktrackingEvent;
+    protected:
+      typedef std::vector< TVertex >         _TVertices;
+      typedef std::pair< TVertex, bool >     _TCollision;
+      typedef std::vector< _TCollision >     _TCollisionsRow;
+      typedef std::vector< _TCollisionsRow > _TCollisions;
+
+      /**
+       */
+      enum _TNodeLabel
+      {
+        FarLabel = 0,
+        FrontLabel,
+        AliveLabel
+      };
+
+      /**
+       */
+      class _TNode
+      {
+      public:
+        _TNode( );
+        virtual ~_TNode( );
+
+      public:
+        TVertex     Vertex;
+        TVertex     Parent;
+        TResult     Result;
+        long        FrontId;
+        _TNodeLabel Label;
+      };
+      typedef std::vector< _TNode > _TNodes;
 
     public:
-      itkTypeMacro( Algorithm, itkProcessObject );
+      itkTypeMacro( Algorithm, B );
 
-      itkBooleanMacro( StopAtOneFront );
       itkBooleanMacro( ThrowEvents );
+      itkBooleanMacro( StopAtOneFront );
 
-      itkGetConstMacro( StopAtOneFront, bool );
       itkGetConstMacro( ThrowEvents, bool );
+      itkGetConstMacro( StopAtOneFront, bool );
 
-      itkSetMacro( StopAtOneFront, bool );
       itkSetMacro( ThrowEvents, bool );
+      itkSetMacro( StopAtOneFront, bool );
 
     public:
       virtual void InvokeEvent( const itk::EventObject& e );
       virtual void InvokeEvent( const itk::EventObject& e ) const;
 
-      /// Seeds manipulation
-      void AddSeed( const TVertex& s, const TResult& v );
-      const TVertex& GetSeed( const unsigned long& i ) const;
+      void AddSeed( const TVertex& s, const TResult& r );
+      const TVertex& GetSeed( const unsigned int& id ) const;
       void ClearSeeds( );
       unsigned long GetNumberOfSeeds( ) const;
 
@@ -84,66 +101,63 @@ namespace fpa
       Algorithm( );
       virtual ~Algorithm( );
 
-      /// itk::ProcessObject
+      // Connection with itk's pipeline
       virtual void GenerateData( );
 
-      /// Base interface
-      virtual void _BeforeMainLoop     ( );
-      virtual void _AfterMainLoop      ( );
-      virtual void _BeforeLoop         ( );
-      virtual void _AfterLoop          ( );
-      virtual void _Loop               ( );
-      virtual bool _CheckCollisions    ( const _TNode& a, const _TNode& b );
-      virtual bool _CheckStopCondition ( );
-      virtual bool _UpdateResult       ( _TNode& n );
-
-      /// Marks management
-      virtual      void _InitializeMarks ( );
-      virtual      bool _IsMarked        ( const TVertex& v ) const;
-      virtual _TFrontId _FrontId         ( const TVertex& v ) const;
-      virtual   TVertex _Parent          ( const TVertex& v ) const;
-      virtual      void _Mark            ( const _TNode& n );
-
-      /// Pure virtual interface: vertices
-      virtual unsigned long _NumberOfVertices ( ) const = 0;
-      virtual  TVertexValue _Value            ( const TVertex& v ) const = 0;
-      virtual       TResult _Result           ( const TVertex& v ) const = 0;
-
-      /// Pure virtual interface: edges
-      virtual double _Norm ( const TVertex& a, const TVertex& b ) const = 0;
-      virtual   bool _Edge ( const TVertex& a, const TVertex& b ) const = 0;
-      virtual  TCost _Cost ( const TVertex& a, const TVertex& b ) const = 0;
-
-      /// Pure virtual interface: neighborhood
-      virtual void _Neighs      ( const _TNode& n, _TNodes& N ) const = 0;
-      virtual bool _UpdateNeigh ( _TNode& nn, const _TNode& n ) = 0;
-      virtual void _NeighsInDim ( const _TNode& n,
-                                  const unsigned int& d,
-                                  _TNodes& N ) = 0;
-
-      /// Pure virtual interface: queue
-      virtual   void _InitializeQueue ( ) = 0;
-      virtual   bool _IsQueueEmpty    ( ) const = 0;
-      virtual   void _QueuePush       ( const _TNode& n ) = 0;
-      virtual _TNode _QueuePop        ( ) = 0;
-      virtual   void _QueueClear      ( ) = 0;
-
-      /// Pure virtual interface: results
-      virtual void _InitializeResults ( ) = 0;
+      // Main loop algorithm
+      virtual void _Loop( );
+
+      // Supporting methods for loop
+      virtual void _BeforeGenerateData( );
+      virtual void _AfterGenerateData( );
+      virtual void _BeforeLoop( );
+      virtual void _AfterLoop( );
+
+      // Methods to control forced stops
+      virtual bool _UpdateCollisions( const TVertex& a, const TVertex& b );
+      virtual bool _NeedToStop( ) const;
+
+      // Graph-related abstract methods
+      virtual unsigned long _NumberOfVertices( ) const = 0;
+      virtual const TValue& _VertexValue( const TVertex& v ) const = 0;
+      virtual double _Distance(
+        const TVertex& a, const TVertex& b
+        ) const = 0;
+      virtual bool _HasEdge( const TVertex& a, const TVertex& b ) const = 0;
+      virtual void _Neighborhood(
+        _TVertices& neighborhood, const TVertex& v
+        ) const = 0;
+
+      // Results-related abstract methods
+      virtual bool _ComputeNeighborResult(
+        TResult& result, const TVertex& neighbor, const TVertex& parent
+        ) const = 0;
+      virtual void _InitResults( ) = 0;
+      virtual const TResult& _Result( const TVertex& v ) const = 0;
+      virtual void _SetResult( const TVertex& v, const TResult& r ) = 0;
+
+      // Marks-related abstract methods
+      virtual const _TNode& _Node( const TVertex& v ) const = 0;
+      virtual void _InitMarks( ) = 0;
+      virtual void _Mark( const _TNode& node ) = 0;
+
+      // Queue-related abstract methods
+      virtual void _InitQueue( );
+      virtual bool _IsQueueEmpty( ) const = 0;
+      virtual void _QueuePush( const _TNode& n ) = 0;
+      virtual _TNode _QueuePop( ) = 0;
+      virtual void _QueueClear( ) = 0;
 
     private:
       // Purposely not implemented
-      Algorithm( const Self& );
-      void operator=( const Self& );
+      Algorithm( const Self& other );
+      Self& operator=( const Self& other );
 
     protected:
-      bool m_StopAtOneFront;
-      bool m_ThrowEvents;
-
-      _TNodes m_Seeds;
-      _TMarks m_Marks;
-
-      _TCollisionSites m_CollisionSites;
+      bool         m_ThrowEvents;
+      bool         m_StopAtOneFront;
+      _TNodes      m_Seeds;
+      _TCollisions m_Collisions;
     };
 
   } // ecapseman
index a58f2a6a047366e2896a302109a6eb887095711d..21670ef7396522c40c2a918432182d7d96037b34 100644 (file)
@@ -1,13 +1,28 @@
 #ifndef __FPA__BASE__ALGORITHM__HXX__
 #define __FPA__BASE__ALGORITHM__HXX__
 
-#include <algorithm>
-#include <limits>
 #include <queue>
 
 // -------------------------------------------------------------------------
-template< class T, class B >
-void fpa::Base::Algorithm< T, B >::
+template< class V, class C, class R, class B >
+fpa::Base::Algorithm< V, C, R, B >::_TNode::
+_TNode( )
+  : Result( TResult( 0 ) ),
+    FrontId( -1 ),
+    Label( Self::FarLabel )
+{
+}
+
+// -------------------------------------------------------------------------
+template< class V, class C, class R, class B >
+fpa::Base::Algorithm< V, C, R, B >::_TNode::
+~_TNode( )
+{
+}
+
+// -------------------------------------------------------------------------
+template< class V, class C, class R, class B >
+void fpa::Base::Algorithm< V, C, R, B >::
 InvokeEvent( const itk::EventObject& e )
 {
   if( this->m_ThrowEvents )
@@ -15,8 +30,8 @@ InvokeEvent( const itk::EventObject& e )
 }
 
 // -------------------------------------------------------------------------
-template< class T, class B >
-void fpa::Base::Algorithm< T, B >::
+template< class V, class C, class R, class B >
+void fpa::Base::Algorithm< V, C, R, B >::
 InvokeEvent( const itk::EventObject& e ) const
 {
   if( this->m_ThrowEvents )
@@ -24,26 +39,32 @@ InvokeEvent( const itk::EventObject& e ) const
 }
 
 // -------------------------------------------------------------------------
-template< class T, class B >
-void fpa::Base::Algorithm< T, B >::
-AddSeed( const TVertex& s, const TResult& v )
+template< class V, class C, class R, class B >
+void fpa::Base::Algorithm< V, C, R, B >::
+AddSeed( const TVertex& s, const TResult& r )
 {
-  this->m_Seeds.push_back( _TNode( s, v, this->m_Seeds.size( ) ) );
+  _TNode ns;
+  ns.Vertex = s;
+  ns.Parent = s;
+  ns.Result = r;
+  ns.FrontId = this->m_Seeds.size( );
+  ns.Label = Self::FrontLabel;
+  this->m_Seeds.push_back( ns );
   this->Modified( );
 }
 
 // -------------------------------------------------------------------------
-template< class T, class B >
-const typename fpa::Base::Algorithm< T, B >::
-TVertex& fpa::Base::Algorithm< T, B >::
-GetSeed( const unsigned long& i ) const
+template< class V, class C, class R, class B >
+const typename fpa::Base::Algorithm< V, C, R, B >::
+TVertex& fpa::Base::Algorithm< V, C, R, B >::
+GetSeed( const unsigned int& id ) const
 {
-  return( this->m_Seeds[ i ].Vertex );
+  return( this->m_Seeds[ id ].Vertex );
 }
 
 // -------------------------------------------------------------------------
-template< class T, class B >
-void fpa::Base::Algorithm< T, B >::
+template< class V, class C, class R, class B >
+void fpa::Base::Algorithm< V, C, R, B >::
 ClearSeeds( )
 {
   this->m_Seeds.clear( );
@@ -51,170 +72,184 @@ ClearSeeds( )
 }
 
 // -------------------------------------------------------------------------
-template< class T, class B >
-unsigned long fpa::Base::Algorithm< T, B >::
+template< class V, class C, class R, class B >
+unsigned long fpa::Base::Algorithm< V, C, R, B >::
 GetNumberOfSeeds( ) const
 {
   return( this->m_Seeds.size( ) );
 }
 
 // -------------------------------------------------------------------------
-template< class T, class B >
-fpa::Base::Algorithm< T, B >::
+template< class V, class C, class R, class B >
+fpa::Base::Algorithm< V, C, R, B >::
 Algorithm( )
   : Superclass( ),
-    m_StopAtOneFront( false ),
-    m_ThrowEvents( false )
+    m_ThrowEvents( false ),
+    m_StopAtOneFront( false )
 {
 }
 
 // -------------------------------------------------------------------------
-template< class T, class B >
-fpa::Base::Algorithm< T, B >::
+template< class V, class C, class R, class B >
+fpa::Base::Algorithm< V, C, R, B >::
 ~Algorithm( )
 {
 }
 
 // -------------------------------------------------------------------------
-template< class T, class B >
-void fpa::Base::Algorithm< T, B >::
+template< class V, class C, class R, class B >
+void fpa::Base::Algorithm< V, C, R, B >::
 GenerateData( )
 {
-  this->AllocateOutputs( );
-
   unsigned long N = this->m_Seeds.size( );
   if( N == 0 )
     return;
-  this->m_CollisionSites.clear( );
-  this->m_CollisionSites.
-    resize( N, _TCollisionSitesRow( N, _TCollision( TVertex( ), false ) ) );
-
-  this->_BeforeMainLoop( );
-  this->_InitializeMarks( );
-  this->_InitializeResults( );
-  this->_InitializeQueue( );
-  this->_Loop( );
-  this->_AfterMainLoop( );
-  this->InvokeEvent( TEndEvent( ) );
-}
-
-// -------------------------------------------------------------------------
-template< class T, class B >
-void fpa::Base::Algorithm< T, B >::
-_BeforeMainLoop( )
-{
-}
 
-// -------------------------------------------------------------------------
-template< class T, class B >
-void fpa::Base::Algorithm< T, B >::
-_AfterMainLoop( )
-{
-}
+  this->InvokeEvent( TStartEvent( ) );
+  this->_BeforeGenerateData( );
 
-// -------------------------------------------------------------------------
-template< class T, class B >
-void fpa::Base::Algorithm< T, B >::
-_BeforeLoop( )
-{
-}
-
-// -------------------------------------------------------------------------
-template< class T, class B >
-void fpa::Base::Algorithm< T, B >::
-_AfterLoop( )
-{
+  this->m_Collisions.clear( );
+  this->m_Collisions.
+    resize( N, _TCollisionsRow( N, _TCollision( TVertex( ), false ) ) );
+  this->_InitResults( );
+  this->_InitMarks( );
+  this->_InitQueue( );
+  this->_Loop( );
+  this->_AfterGenerateData( );
+  this->InvokeEvent( TEndEvent( ) );
 }
 
 // -------------------------------------------------------------------------
-template< class T, class B >
-void fpa::Base::Algorithm< T, B >::
+template< class V, class C, class R, class B >
+void fpa::Base::Algorithm< V, C, R, B >::
 _Loop( )
 {
+  this->InvokeEvent( TStartLoopEvent( ) );
   this->_BeforeLoop( );
   while( !( this->_IsQueueEmpty( ) ) )
   {
-    _TNode n = this->_QueuePop( );
-    if( this->_IsMarked( n.Vertex ) )
+    // Get next candidate
+    _TNode candidate = this->_QueuePop( );
+    if( this->_Node( candidate.Vertex ).Label == Self::AliveLabel )
       continue;
 
-    this->_Mark( n );
-    this->InvokeEvent( TMarkEvent( n ) );
-    if( this->_UpdateResult( n ) )
+    // Mark it as "Alive" and update final result
+    candidate.Label = Self::AliveLabel;
+    this->_Mark( candidate );
+    this->_SetResult( candidate.Vertex, candidate.Result );
+    this->InvokeEvent( TAliveEvent( candidate.Vertex, candidate.FrontId ) );
+
+    // Check if a forced stop condition arises
+    if( !( this->_NeedToStop( ) ) )
     {
-      if( !( this->_CheckStopCondition( ) ) )
+      // Compute neighborhood
+      _TVertices neighborhood;
+      this->_Neighborhood( neighborhood, candidate.Vertex );
+
+      // Iterate over neighbors
+      typename _TVertices::iterator nIt = neighborhood.begin( );
+      for( ; nIt != neighborhood.end( ); ++nIt )
       {
-        _TNodes N;
-        this->_Neighs( n, N );
-        typename _TNodes::iterator nnIt = N.begin( );
-        while( nnIt != N.end( ) )
+        _TNode neighbor = this->_Node( *nIt );
+        neighbor.Vertex = *nIt;
+        if( neighbor.Label == Self::AliveLabel )
         {
-          if( this->_IsMarked( nnIt->Vertex ) )
+          // Update collisions
+          if( this->_UpdateCollisions( candidate.Vertex, *nIt ) )
           {
-            // Update real front identifier
-            nnIt->FrontId = this->_FrontId( nnIt->Vertex );
+            this->_QueueClear( );
+            nIt = neighborhood.end( );
 
-            // Update collisions
-            if( this->_CheckCollisions( n, *nnIt ) )
-            {
-              if( this->m_StopAtOneFront )
-              {
-                this->_QueueClear( );
-                nnIt = N.end( );
-
-              } // fi
-
-            } // fi
+          } // fi
+        }
+        else
+        {
+          // Add new candidate to queue
+          if(
+            this->_ComputeNeighborResult(
+              neighbor.Result, *nIt, candidate.Vertex
+              )
+            )
+          {
+            neighbor.FrontId = candidate.FrontId;
+            neighbor.Parent = candidate.Vertex;
+            neighbor.Label = Self::FrontLabel;
+            this->_QueuePush( neighbor );
+            this->_Mark( neighbor );
+            this->InvokeEvent( TFrontEvent( *nIt, candidate.FrontId ) );
           }
           else
-          {
-            if( this->_UpdateNeigh( *nnIt, n ) )
-            {
-              nnIt->Parent = n.Vertex;
-              this->_QueuePush( *nnIt );
-              this->InvokeEvent( TFrontEvent( *nnIt ) );
+            this->InvokeEvent( TFreezeEvent( *nIt, candidate.FrontId ) );
 
-            } // fi
+        } // fi
 
-          } // fi
-          if( nnIt != N.end( ) )
-            nnIt++;
-
-        } // elihw
-      }
-      else
-        this->_QueueClear( );
-
-    } // fi
+      } // rof
+    }
+    else
+      this->_QueueClear( );
 
   } // elihw
   this->_AfterLoop( );
+  this->InvokeEvent( TEndLoopEvent( ) );
+}
+
+// -------------------------------------------------------------------------
+template< class V, class C, class R, class B >
+void fpa::Base::Algorithm< V, C, R, B >::
+_BeforeGenerateData( )
+{
+}
+
+// -------------------------------------------------------------------------
+template< class V, class C, class R, class B >
+void fpa::Base::Algorithm< V, C, R, B >::
+_AfterGenerateData( )
+{
+}
+
+// -------------------------------------------------------------------------
+template< class V, class C, class R, class B >
+void fpa::Base::Algorithm< V, C, R, B >::
+_BeforeLoop( )
+{
+}
+
+// -------------------------------------------------------------------------
+template< class V, class C, class R, class B >
+void fpa::Base::Algorithm< V, C, R, B >::
+_AfterLoop( )
+{
 }
 
 // -------------------------------------------------------------------------
-template< class T, class B >
-bool fpa::Base::Algorithm< T, B >::
-_CheckCollisions( const _TNode& a, const _TNode& b )
+template< class V, class C, class R, class B >
+bool fpa::Base::Algorithm< V, C, R, B >::
+_UpdateCollisions( const TVertex& a, const TVertex& b )
 {
   bool ret = false;
-  if( a.FrontId != b.FrontId )
+  _TNode na = this->_Node( a );
+  _TNode nb = this->_Node( b );
+  long fa = na.FrontId;
+  long fb = na.FrontId;
+
+  if( fa != fb )
   {
     // Mark collision, if it is new
-    bool exists = this->m_CollisionSites[ a.FrontId ][ b.FrontId ].second;
-    exists     &= this->m_CollisionSites[ b.FrontId ][ a.FrontId ].second;
+    bool exists = this->m_Collisions[ fa ][ fb ].second;
+    exists     &= this->m_Collisions[ fb ][ fa ].second;
     if( !exists )
     {
-      this->m_CollisionSites[ a.FrontId ][ b.FrontId ].first = a.Vertex;
-      this->m_CollisionSites[ a.FrontId ][ b.FrontId ].second = true;
-      this->m_CollisionSites[ b.FrontId ][ a.FrontId ].first = b.Vertex;
-      this->m_CollisionSites[ b.FrontId ][ a.FrontId ].second = true;
+      this->m_Collisions[ fa ][ fb ].first = na.Vertex;
+      this->m_Collisions[ fa ][ fb ].second = true;
+      this->m_Collisions[ fb ][ fa ].first = nb.Vertex;
+      this->m_Collisions[ fb ][ fa ].second = true;
 
       // Stop if one front is desired
       if( this->m_StopAtOneFront )
       {
         // Perform a depth-first iteration on front graph
         unsigned long N = this->GetNumberOfSeeds( );
-        unsigned long C = 0;
+        unsigned long count = 0;
         std::vector< bool > m( N, false );
         std::queue< unsigned long > q;
         q.push( 0 );
@@ -226,14 +261,14 @@ _CheckCollisions( const _TNode& a, const _TNode& b )
           if( m[ f ] )
             continue;
           m[ f ] = true;
-          C++;
+          count++;
 
           for( unsigned int n = 0; n < N; ++n )
-            if( this->m_CollisionSites[ f ][ n ].second && !m[ n ] )
+            if( this->m_Collisions[ f ][ n ].second && !m[ n ] )
               q.push( n );
 
         } // elihw
-        ret = ( C == N );
+        ret = ( count == N );
 
       } // fi
 
@@ -244,69 +279,29 @@ _CheckCollisions( const _TNode& a, const _TNode& b )
 }
 
 // -------------------------------------------------------------------------
-template< class T, class B >
-bool fpa::Base::Algorithm< T, B >::
-_CheckStopCondition( )
+template< class V, class C, class R, class B >
+bool fpa::Base::Algorithm< V, C, R, B >::
+_NeedToStop( ) const
 {
   return( false );
 }
 
 // -------------------------------------------------------------------------
-template< class T, class B >
-bool fpa::Base::Algorithm< T, B >::
-_UpdateResult( _TNode& n )
+template< class V, class C, class R, class B >
+void fpa::Base::Algorithm< V, C, R, B >::
+_InitQueue( )
 {
-  return( true );
-}
-
-// -------------------------------------------------------------------------
-template< class T, class B >
-void fpa::Base::Algorithm< T, B >::
-_InitializeMarks( )
-{
-  this->m_Marks.clear( );
-}
-
-// -------------------------------------------------------------------------
-template< class T, class B >
-bool  fpa::Base::Algorithm< T, B >::
-_IsMarked( const TVertex& v ) const
-{
-  return( this->m_Marks.find( v ) != this->m_Marks.end( ) );
-}
-
-// -------------------------------------------------------------------------
-template< class T, class B >
-typename fpa::Base::Algorithm< T, B >::
-_TFrontId fpa::Base::Algorithm< T, B >::
-_FrontId( const TVertex& v ) const
-{
-  typename _TMarks::const_iterator mIt = this->m_Marks.find( v );
-  if( mIt != this->m_Marks.end( ) )
-    return( mIt->second.FrontId );
-  else
-    return( std::numeric_limits< _TFrontId >::max( ) );
-}
-
-// -------------------------------------------------------------------------
-template< class T, class B >
-typename fpa::Base::Algorithm< T, B >::
-TVertex fpa::Base::Algorithm< T, B >::
-_Parent( const TVertex& v ) const
-{
-  typename _TMarks::const_iterator mIt = this->m_Marks.find( v );
-  if( mIt == this->m_Marks.end( ) )
-    return( TVertex( ) );
-  else
-    return( mIt->second.Parent );
-}
+  this->_QueueClear( );
+  for(
+    typename _TNodes::const_iterator sIt = this->m_Seeds.begin( );
+    sIt != this->m_Seeds.end( );
+    sIt++
+    )
+  {
+    this->_QueuePush( *sIt );
+    this->_Mark( *sIt );
 
-// -------------------------------------------------------------------------
-template< class T, class B >
-void  fpa::Base::Algorithm< T, B >::
-_Mark( const _TNode& n )
-{
-  this->m_Marks[ n.Vertex ] = n;
+  } // rof
 }
 
 #endif // __FPA__BASE__ALGORITHM__HXX__
index a6212cf9b770fe178605f0d241fdfd3430dfd0d6..3831526a553e5a85bd4c9ccd77d9367e0a735b07 100644 (file)
@@ -8,105 +8,74 @@ namespace fpa
 {
   namespace Base
   {
-    /**
-     */
-    template< class V, class C, class VV, class VC >
-    class DijkstraTraits
-    {
-    public:
-      typedef V TVertex;
-      typedef C TResult;
-      typedef C TCost;
-      typedef VV TVertexValue;
-      typedef VC TVertexCmp;
-      typedef long TFrontId;
-
-      class TNode
-      {
-      public:
-        TNode( )
-          : Cost( 0 )
-          { }
-        TNode( const TVertex& v, const TFrontId& f )
-          : Vertex( v ),
-            Parent( v ),
-            Result( TResult( 0 ) ),
-            FrontId( f ),
-            Cost( TCost( 0 ) )
-          { }
-        TNode( const TVertex& v, const TResult& r, const TFrontId& f )
-          : Vertex( v ),
-            Parent( v ),
-            Result( r ),
-            FrontId( f ),
-            Cost( TCost( 0 ) )
-          { }
-        virtual ~TNode( )
-          { }
-
-        // NOTE: stl::heaps work as maximum priority queues
-        bool operator<( const TNode& other ) const
-          { return( other.Cost < this->Cost ); }
-
-        TVertex Vertex;
-        TVertex Parent;
-        TResult Result;
-        TFrontId FrontId;
-        TCost Cost;
-      };
-
-      typedef std::vector< TNode > TNodes;
-    };
-
     /**
      * Dijkstra is a front propagation algorithm that minimizes costs
+     *
+     * @param V Vertex type.
+     * @param C Vertex value type.
+     * @param R Result value type.
+     * @param B Base class for this algorithm. It should be any itk-based
+     *          filter (itk::ProcessObject).
+     *
      */
-    template< class V, class C, class VV, class VC, class B >
+    template< class V, class C, class R, class B >
     class Dijkstra
-      : public Algorithm< DijkstraTraits< V, C, VV, VC >, B >
+      : public Algorithm< V, C, R, B >
     {
     public:
-      // Templated types
-      typedef V TVertex;
-      typedef C TCost;
-      typedef VV TVertexValue;
-      typedef B  TBaseFilter;
-      typedef DijkstraTraits< V, C, VV, VC > TTraits;
-
-      // Standard class typdedefs
-      typedef Dijkstra                        Self;
-      typedef Algorithm< TTraits, B >         Superclass;
-      typedef itk::SmartPointer< Self >       Pointer;
-      typedef itk::SmartPointer< const Self > ConstPointer;
+      typedef Dijkstra                         Self;
+      typedef Algorithm< V, C, R, 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;
 
     protected:
-      typedef typename TTraits::TFrontId  _TFrontId;
-      typedef typename TTraits::TNode     _TNode;
-      typedef typename TTraits::TNodes    _TNodes;
+      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 std::vector< _TNode > _TQueue;
+      struct _TNodeCompare
+      {
+        // Make the min-heap behave as a max-heap
+        bool operator()( const _TNode& a, const _TNode& b ) const
+          { return( b.Result < a.Result ); }
+      };
 
     public:
-      itkTypeMacro( Dijkstra, Base );
+      itkTypeMacro( Dijkstra, Algorithm );
 
     protected:
       Dijkstra( );
       virtual ~Dijkstra( );
 
-      virtual   void _InitializeQueue ( );
-      virtual   bool _IsQueueEmpty    ( ) const;
-      virtual   void _QueuePush       ( const _TNode& n );
-      virtual _TNode _QueuePop        ( );
-      virtual   void _QueueClear      ( );
-      virtual   bool _UpdateNeigh     ( _TNode& nn, const _TNode& n );
+      virtual TResult _Cost( const TVertex& v, const TVertex& p ) const = 0;
+
+      // Results-related abstract methods
+      virtual bool _ComputeNeighborResult(
+        TResult& result, const TVertex& neighbor, const TVertex& parent
+        ) const;
+
+      // Queue-related abstract methods
+      virtual bool _IsQueueEmpty( ) const;
+      virtual void _QueuePush( const _TNode& n );
+      virtual _TNode _QueuePop( );
+      virtual void _QueueClear( );
 
     private:
       // Purposely not implemented
-      Dijkstra( const Self& );
-      void operator=( const Self& );
+      Dijkstra( const Self& other );
+      Self& operator=( const Self& other );
 
-    private:
+    protected:
       _TQueue m_Queue;
+      static _TNodeCompare m_NodeCompare;
     };
 
   } // ecapseman
index 4920ab551628489db9f03d42660ba408e40b31df..7d652372e1a9adbadf6171fb438967fe339f8aa0 100644 (file)
@@ -4,92 +4,78 @@
 #include <algorithm>
 
 // -------------------------------------------------------------------------
-template< class V, class C, class VV, class VC, class B >
-fpa::Base::Dijkstra< V, C, VV, VC, B >::
+template< class V, class C, class R, class B >
+fpa::Base::Dijkstra< V, C, R, B >::
 Dijkstra( )
   : Superclass( )
 {
 }
 
 // -------------------------------------------------------------------------
-template< class V, class C, class VV, class VC, class B >
-fpa::Base::Dijkstra< V, C, VV, VC, B >::
+template< class V, class C, class R, class B >
+fpa::Base::Dijkstra< V, C, R, B >::
 ~Dijkstra( )
 {
 }
 
 // -------------------------------------------------------------------------
-template< class V, class C, class VV, class VC, class B >
-void fpa::Base::Dijkstra< V, C, VV, VC, B >::
-_InitializeQueue( )
+template< class V, class C, class R, class B >
+bool fpa::Base::Dijkstra< V, C, R, B >::
+_ComputeNeighborResult(
+  TResult& result, const TVertex& neighbor, const TVertex& parent
+  ) const
 {
-  for(
-    typename _TNodes::const_iterator vIt = this->m_Seeds.begin( );
-    vIt != this->m_Seeds.end( );
-    vIt++
-    )
-    this->_QueuePush( *vIt );
+  result  = this->_Cost( neighbor, parent );
+  result *= TResult( this->_Distance( neighbor, parent ) );
+
+  _TNode pn = this->_Node( parent );
+  if( pn.Label == Self::AliveLabel )
+    result += pn.Result;
+
+  return( true );
 }
 
 // -------------------------------------------------------------------------
-template< class V, class C, class VV, class VC, class B >
-bool fpa::Base::Dijkstra< V, C, VV, VC, B >::
+template< class V, class C, class R, class B >
+bool fpa::Base::Dijkstra< V, C, R, B >::
 _IsQueueEmpty( ) const
 {
   return( this->m_Queue.empty( ) );
 }
 
 // -------------------------------------------------------------------------
-template< class V, class C, class VV, class VC, class B >
-void fpa::Base::Dijkstra< V, C, VV, VC, B >::
+template< class V, class C, class R, class B >
+void fpa::Base::Dijkstra< V, C, R, B >::
 _QueuePush( const _TNode& n )
 {
   this->m_Queue.push_back( n );
-  std::push_heap( this->m_Queue.begin( ), this->m_Queue.end( ) );
+  std::push_heap(
+    this->m_Queue.begin( ), this->m_Queue.end( ), Self::m_NodeCompare
+    );
 }
 
 // -------------------------------------------------------------------------
-template< class V, class C, class VV, class VC, class B >
-typename fpa::Base::Dijkstra< V, C, VV, VC, B >::
-_TNode fpa::Base::Dijkstra< V, C, VV, VC, B >::
+template< class V, class C, class R, class B >
+typename fpa::Base::Dijkstra< V, C, R, B >::
+_TNode fpa::Base::Dijkstra< V, C, R, B >::
 _QueuePop( )
 {
-  _TNode n;
-  if( !( this->m_Queue.empty( ) ) )
-  {
-    // n = *( this->m_Queue.begin( ) );
-    n = this->m_Queue.front( );
-    std::pop_heap( this->m_Queue.begin( ), this->m_Queue.end( ) );
-    this->m_Queue.pop_back( );
-
-  } // fi
+  _TNode n = this->m_Queue.front( );
+  std::pop_heap(
+    this->m_Queue.begin( ), this->m_Queue.end( ), Self::m_NodeCompare
+    );
+  this->m_Queue.pop_back( );
   return( n );
 }
 
 // -------------------------------------------------------------------------
-template< class V, class C, class VV, class VC, class B >
-void fpa::Base::Dijkstra< V, C, VV, VC, B >::
+template< class V, class C, class R, class B >
+void fpa::Base::Dijkstra< V, C, R, B >::
 _QueueClear( )
 {
   this->m_Queue.clear( );
 }
 
-// -------------------------------------------------------------------------
-template< class V, class C, class VV, class VC, class B >
-bool fpa::Base::Dijkstra< V, C, VV, VC, B >::
-_UpdateNeigh( _TNode& nn, const _TNode& n )
-{
-  TCost nc = this->_Cost( nn.Vertex, n.Vertex );
-  if( C( 0 ) <= nc )
-  {
-    nn.Cost = n.Cost + nc;
-    nn.Result = nn.Cost;
-    return( true );
-  }
-  else
-    return( false );
-}
-
 #endif // __FPA__BASE__DIJKSTRA__HXX__
 
 // eof - $RCSfile$
index c92c4dbc3051593f8e27cd15759510b110f6c40a..09f0637da4731445aff3c2304363aa18963529f4 100644 (file)
@@ -4,15 +4,46 @@
 #include <vector>
 #include <itkProcessObject.h>
 
+// -------------------------------------------------------------------------
+#define fpa_Base_NewEvent( name )                               \
+  class name                                                    \
+    : public BaseEvent                                          \
+  {                                                             \
+  public:                                                       \
+    name( ) : BaseEvent( ) { }                                  \
+    virtual ~name( ) { }                                        \
+    const char* GetEventName( ) const                           \
+    { return( "fpa::Base::##name" ); }                          \
+    bool CheckEvent( const itk::EventObject* e ) const          \
+    { return( dynamic_cast< const name* >( e ) != NULL ); }     \
+    itk::EventObject* MakeObject( ) const                       \
+    { return( new name( ) ); }                                  \
+  };
+
+// -------------------------------------------------------------------------
+#define fpa_Base_NewEventWithVertex( name, type )               \
+  class name                                                    \
+    : public BaseEventWithVertex< type >                        \
+  {                                                             \
+  public:                                                       \
+    name( ) : BaseEventWithVertex< type >( ) { }                \
+    name( const type& v, long fid )                             \
+        : BaseEventWithVertex< type >( v, fid ) { }             \
+    virtual ~name( ) { }                                        \
+    const char* GetEventName( ) const                           \
+    { return( "fpa::Base::##name" ); }                          \
+    bool CheckEvent( const itk::EventObject* e ) const          \
+    { return( dynamic_cast< const name* >( e ) != NULL ); }     \
+    itk::EventObject* MakeObject( ) const                       \
+    { return( new name( ) ); }                                  \
+  };
+
 namespace fpa
 {
   namespace Base
   {
     /**
-     * Evolution event. An event is generated when a vertex changes its
-     * state.
      */
-    template< class N >
     class BaseEvent
       : public itk::AnyEvent
     {
@@ -20,171 +51,47 @@ namespace fpa
       BaseEvent( )
         : itk::AnyEvent( )
         { }
-      BaseEvent( const N& n )
-        : itk::AnyEvent( ),
-          Node( n )
-        { }
       virtual ~BaseEvent( )
         { }
-
       const char* GetEventName( ) const
         { return( "fpa::Base::BaseEvent" ); }
       bool CheckEvent( const itk::EventObject* e ) const
-        { return( dynamic_cast< const BaseEvent< N >* >( e ) != NULL ); }
-      itk::EventObject* MakeObject( ) const
-        { return( new BaseEvent< N >( ) ); }
-
-    public:
-      N Node;
-    };
-
-    /**
-     */
-    template< class N >
-    class FrontEvent
-      : public BaseEvent< N >
-    {
-    public:
-      FrontEvent( )
-        : BaseEvent< N >( )
-        { }
-      FrontEvent( const N& n )
-        : BaseEvent< N >( n )
-        { }
-      virtual ~FrontEvent( )
-        { }
-      const char* GetEventName( ) const
-        { return( "fpa::Base::FrontEvent" ); }
-      bool CheckEvent( const itk::EventObject* e ) const
-        { return( dynamic_cast< const FrontEvent< N >* >( e ) != NULL ); }
-      itk::EventObject* MakeObject( ) const
-        { return( new FrontEvent< N >( ) ); }
-    };
-
-    /**
-     */
-    template< class N >
-    class MarkEvent
-      : public BaseEvent< N >
-    {
-    public:
-      MarkEvent( )
-        : BaseEvent< N >( )
-        { }
-      MarkEvent( const N& n )
-        : BaseEvent< N >( n )
-        { }
-      virtual ~MarkEvent( )
-        { }
-      const char* GetEventName( ) const
-        { return( "fpa::Base::MarkEvent" ); }
-      bool CheckEvent( const itk::EventObject* e ) const
-        { return( dynamic_cast< const MarkEvent< N >* >( e ) != NULL ); }
-      itk::EventObject* MakeObject( ) const
-        { return( new MarkEvent< N >( ) ); }
-    };
-
-    /**
-     */
-    template< class N >
-    class CollisionEvent
-      : public BaseEvent< N >
-    {
-    public:
-      CollisionEvent( )
-        : BaseEvent< N >( )
-        { }
-      CollisionEvent( const N& n )
-        : BaseEvent< N >( n )
-        { }
-      virtual ~CollisionEvent( )
-        { }
-      const char* GetEventName( ) const
-        { return( "fpa::Base::CollisionEvent" ); }
-      bool CheckEvent( const itk::EventObject* e ) const
-        { return( dynamic_cast< const CollisionEvent< N >* >( e ) != NULL ); }
-      itk::EventObject* MakeObject( ) const
-        { return( new CollisionEvent< N >( ) ); }
-    };
-
-    /**
-     */
-    template< class N >
-    class EndEvent
-      : public BaseEvent< N >
-    {
-    public:
-      EndEvent( )
-        : BaseEvent< N >( )
-        { }
-      virtual ~EndEvent( )
-        { }
-      const char* GetEventName( ) const
-        { return( "fpa::Base::EndEvent" ); }
-      bool CheckEvent( const itk::EventObject* e ) const
-        { return( dynamic_cast< const EndEvent< N >* >( e ) != NULL ); }
+        { return( dynamic_cast< const BaseEvent* >( e ) != NULL ); }
       itk::EventObject* MakeObject( ) const
-        { return( new EndEvent< N >( ) ); }
+        { return( new BaseEvent( ) ); }
     };
 
     /**
      */
-    template< class N >
-    class BacktrackingEvent
-      : public BaseEvent< N >
+    template< class V >
+    class BaseEventWithVertex
+      : public BaseEvent
     {
     public:
-      BacktrackingEvent( )
-        : BaseEvent< N >( )
+      BaseEventWithVertex( )
+        : BaseEvent( )
         { }
-      BacktrackingEvent( const N& n, const unsigned long& id )
-        : BaseEvent< N >( n ),
-        BackId( id )
+      BaseEventWithVertex( const V& v, long fid )
+        : BaseEvent( ),
+          Vertex( v ),
+          FrontId( fid )
         { }
-      virtual ~BacktrackingEvent( )
+      virtual ~BaseEventWithVertex( )
         { }
       const char* GetEventName( ) const
-        { return( "fpa::Base::BacktrackingEvent" ); }
+        { return( "fpa::Base::BaseEventWithVertex" ); }
       bool CheckEvent( const itk::EventObject* e ) const
         {
           return(
-            dynamic_cast< const BacktrackingEvent< N >* >( e ) != NULL
+            dynamic_cast< const BaseEventWithVertex< V >* >( e ) != NULL
             );
         }
       itk::EventObject* MakeObject( ) const
-        { return( new BacktrackingEvent< N >( ) ); }
-
-      unsigned long BackId;
-    };
+        { return( new BaseEventWithVertex< V >( ) ); }
 
-    /**
-     */
-    template< class N >
-    class EndBacktrackingEvent
-      : public BaseEvent< N >
-    {
     public:
-      EndBacktrackingEvent( )
-        : BaseEvent< N >( )
-        { }
-      EndBacktrackingEvent( const unsigned long& id )
-        : BaseEvent< N >( ),
-        BackId( id )
-        { }
-      virtual ~EndBacktrackingEvent( )
-        { }
-      const char* GetEventName( ) const
-        { return( "fpa::Base::EndBacktrackingEvent" ); }
-      bool CheckEvent( const itk::EventObject* e ) const
-        {
-          return(
-            dynamic_cast< const EndBacktrackingEvent< N >* >( e ) != NULL
-            );
-        }
-      itk::EventObject* MakeObject( ) const
-        { return( new EndBacktrackingEvent< N >( ) ); }
-
-      unsigned long BackId;
+      V Vertex;
+      long FrontId;
     };
 
   } // ecapseman
index 278ae557ed7dd9374d09bfae1dc5f9e7ecb7d15d..faf4fb2dbea2027c58874f75d77f9ff2df8fbb73 100644 (file)
@@ -29,7 +29,7 @@ namespace fpa
       public:
         virtual C Evaluate( const C& input ) const
           {
-            return( C( 1 ) / ( C( 0 ) + C( input ) ) );
+            return( C( 1 ) / ( C( 1 ) + C( input ) ) );
           }
 
       protected:
diff --git a/lib/fpa/Base/Functors/TautologyFunction.h b/lib/fpa/Base/Functors/TautologyFunction.h
new file mode 100644 (file)
index 0000000..f79666d
--- /dev/null
@@ -0,0 +1,53 @@
+#ifndef __FPA__BASE__FUNCTORS__TAUTOLOGYFUNCTION__H__
+#define __FPA__BASE__FUNCTORS__TAUTOLOGYFUNCTION__H__
+
+#include <itkFunctionBase.h>
+
+namespace fpa
+{
+  namespace Base
+  {
+    namespace Functors
+    {
+      /**
+       */
+      template< class V >
+      class TautologyFunction
+        : public itk::FunctionBase< V, bool >
+      {
+      public:
+        typedef TautologyFunction               Self;
+        typedef itk::FunctionBase< V, bool >    Superclass;
+        typedef itk::SmartPointer< Self >       Pointer;
+        typedef itk::SmartPointer< const Self > ConstPointer;
+
+      public:
+        itkNewMacro( Self );
+        itkTypeMacro( TautologyFunction, itkFunctionBase );
+
+      public:
+        virtual bool Evaluate( const V& input ) const
+          { return( true ); }
+
+      protected:
+        TautologyFunction( )
+          : Superclass( )
+          { }
+        virtual ~TautologyFunction( )
+          { }
+
+      private:
+        // Purposely not implemented
+        TautologyFunction( const Self& );
+        void operator=( const Self& );
+      };
+
+    } // ecapseman
+
+  } // ecapseman
+
+} // ecapseman
+
+#endif // __FPA__BASE__FUNCTORS__TAUTOLOGYFUNCTION__H__
+
+// eof - $RCSfile$
index f7f15625415ae6ef3772b71748e113782e6423fe..6028b754622fb5f91c9413cf92b79cca0da7a9bc 100644 (file)
 #define __FPA__BASE__REGIONGROW__H__
 
 #include <queue>
-#include <vector>
 #include <fpa/Base/Algorithm.h>
 
 namespace fpa
 {
   namespace Base
   {
-    /**
-     */
-    template< class V, class R, class VV, class VC >
-    class RegionGrowTraits
-    {
-    public:
-      typedef R  TResult;
-      typedef V  TVertex;
-      typedef VV TVertexValue;
-      typedef VC TVertexCmp;
-
-      typedef bool TCost;
-      typedef long TFrontId;
-
-      class TNode
-      {
-      public:
-        TNode( )
-          { }
-        TNode( const TVertex& v, const TFrontId& f )
-          : Vertex( v ),
-            Parent( v ),
-            FrontId( f )
-          { }
-        TNode( const TVertex& v, const TResult& r, const TFrontId& f )
-          : Vertex( v ),
-            Parent( v ),
-            Result( r ),
-            FrontId( f )
-          { }
-        virtual ~TNode( )
-          { }
-
-        TVertex Vertex;
-        TVertex Parent;
-        TResult Result;
-        TFrontId FrontId;
-      };
-
-      typedef std::vector< TNode > TNodes;
-    };
-
     /**
      * Region grow is a front propagation with no costs.
+     *
+     * @param V Vertex type.
+     * @param C Vertex value type.
+     * @param R Result value type.
+     * @param B Base class for this algorithm. It should be any itk-based
+     *          filter (itk::ProcessObject).
+     *
      */
-    template< class V, class R, class VV, class VC, class B >
+    template< class V, class C, class R, class B >
     class RegionGrow
-      : public Algorithm< RegionGrowTraits< V, R, VV, VC >, B >
+      : public Algorithm< V, C, R, B >
     {
     public:
-      typedef V  TVertex;
-      typedef R  TResult;
-      typedef VV TVertexValue;
-      typedef B  TBaseFilter;
-
-      /// Standard class typdedefs
-      typedef RegionGrowTraits< V, R, VV, VC > TTraits;
       typedef RegionGrow                       Self;
-      typedef Algorithm< TTraits, B >          Superclass;
+      typedef Algorithm< V, C, R, B >          Superclass;
       typedef itk::SmartPointer< Self >        Pointer;
       typedef itk::SmartPointer< const Self >  ConstPointer;
 
-      typedef typename TTraits::TCost TCost;
+      typedef typename Superclass::TVertex TVertex;
+      typedef typename Superclass::TValue  TValue;
+      typedef typename Superclass::TResult TResult;
 
     protected:
-      typedef typename TTraits::TFrontId  _TFrontId;
-      typedef typename TTraits::TNode     _TNode;
-      typedef typename TTraits::TNodes    _TNodes;
-      typedef std::queue< _TNode >        _TQueue;
+      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 std::queue< _TNode > _TQueue;
 
     public:
       itkTypeMacro( RegionGrow, Algorithm );
 
+      itkGetConstMacro( InsideValue, TResult );
+      itkGetConstMacro( OutsideValue, TResult );
+
+      itkSetMacro( InsideValue, TResult );
+      itkSetMacro( OutsideValue, TResult );
+
     protected:
       RegionGrow( );
       virtual ~RegionGrow( );
 
-      virtual   bool _UpdateResult    ( _TNode& n );
-      virtual   void _InitializeQueue ( );
-      virtual   bool _IsQueueEmpty    ( ) const;
-      virtual   void _QueuePush       ( const _TNode& n );
-      virtual _TNode _QueuePop        ( );
-      virtual   void _QueueClear      ( );
-      virtual   bool _UpdateNeigh     ( _TNode& nn, const _TNode& n );
+      virtual bool _CheckMembership( const TVertex& v ) const = 0;
+
+      // Results-related abstract methods
+      virtual bool _ComputeNeighborResult(
+        TResult& result, const TVertex& neighbor, const TVertex& parent
+        ) const;
 
-      virtual bool _CheckMembership( const _TNode& n ) const = 0;
+      // Queue-related abstract methods
+      virtual bool _IsQueueEmpty( ) const;
+      virtual void _QueuePush( const _TNode& n );
+      virtual _TNode _QueuePop( );
+      virtual void _QueueClear( );
 
     private:
-      RegionGrow( const Self& );     // Not impl.
-      void operator=( const Self& ); // Not impl.
+      // Purposely not implemented
+      RegionGrow( const Self& other );
+      Self& operator=( const Self& other );
 
     protected:
+      TResult m_InsideValue;
+      TResult m_OutsideValue;
       _TQueue m_Queue;
     };
 
index bdc1ed34c7818bb162480615ab83749cd107b345..2d554c26beb3e010c1d69d43c2341867891df0a8 100644 (file)
@@ -2,62 +2,62 @@
 #define __FPA__BASE__REGIONGROWING__HXX__
 
 // -------------------------------------------------------------------------
-template< class V, class R, class VV, class VC, class B >
-fpa::Base::RegionGrow< V, R, VV, VC, B >::
+template< class V, class C, class R, class B >
+fpa::Base::RegionGrow< V, C, R, B >::
 RegionGrow( )
-  : Superclass( )
+  : Superclass( ),
+    m_InsideValue( TResult( 1 ) ),
+    m_OutsideValue( TResult( 0 ) )
 {
 }
 
 // -------------------------------------------------------------------------
-template< class V, class R, class VV, class VC, class B >
-fpa::Base::RegionGrow< V, R, VV, VC, B >::
+template< class V, class C, class R, class B >
+fpa::Base::RegionGrow< V, C, R, B >::
 ~RegionGrow( )
 {
 }
 
 // -------------------------------------------------------------------------
-template< class V, class R, class VV, class VC, class B >
-bool fpa::Base::RegionGrow< V, R, VV, VC, B >::
-_UpdateResult( _TNode& n )
+template< class V, class C, class R, class B >
+bool fpa::Base::RegionGrow< V, C, R, B >::
+_ComputeNeighborResult(
+  TResult& result, const TVertex& neighbor, const TVertex& parent
+  ) const
 {
-  n.Result = R( this->_CheckMembership( n ) );
-  return( n.Result );
-}
+  if( this->_CheckMembership( neighbor ) )
+  {
+    result = this->m_InsideValue;
+    return( true );
+  }
+  else
+  {
+    result = this->m_OutsideValue;
+    return( false );
 
-// -------------------------------------------------------------------------
-template< class V, class R, class VV, class VC, class B >
-void fpa::Base::RegionGrow< V, R, VV, VC, B >::
-_InitializeQueue( )
-{
-  for(
-    typename _TNodes::const_iterator vIt = this->m_Seeds.begin( );
-    vIt != this->m_Seeds.end( );
-    vIt++
-    )
-    this->_QueuePush( *vIt );
+  } // fi
 }
 
 // -------------------------------------------------------------------------
-template< class V, class R, class VV, class VC, class B >
-bool fpa::Base::RegionGrow< V, R, VV, VC, B >::
+template< class V, class C, class R, class B >
+bool fpa::Base::RegionGrow< V, C, R, B >::
 _IsQueueEmpty( ) const
 {
   return( this->m_Queue.empty( ) );
 }
 
 // -------------------------------------------------------------------------
-template< class V, class R, class VV, class VC, class B >
-void fpa::Base::RegionGrow< V, R, VV, VC, B >::
+template< class V, class C, class R, class B >
+void fpa::Base::RegionGrow< V, C, R, B >::
 _QueuePush( const _TNode& n )
 {
   this->m_Queue.push( n );
 }
 
 // -------------------------------------------------------------------------
-template< class V, class R, class VV, class VC, class B >
-typename fpa::Base::RegionGrow< V, R, VV, VC, B >::
-_TNode fpa::Base::RegionGrow< V, R, VV, VC, B >::
+template< class V, class C, class R, class B >
+typename fpa::Base::RegionGrow< V, C, R, B >::
+_TNode fpa::Base::RegionGrow< V, C, R, B >::
 _QueuePop( )
 {
   _TNode n = this->m_Queue.front( );
@@ -66,22 +66,14 @@ _QueuePop( )
 }
 
 // -------------------------------------------------------------------------
-template< class V, class R, class VV, class VC, class B >
-void fpa::Base::RegionGrow< V, R, VV, VC, B >::
+template< class V, class C, class R, class B >
+void fpa::Base::RegionGrow< V, C, R, B >::
 _QueueClear( )
 {
   while( this->m_Queue.size( ) > 0 )
     this->m_Queue.pop( );
 }
 
-// -------------------------------------------------------------------------
-template< class V, class R, class VV, class VC, class B >
-bool fpa::Base::RegionGrow< V, R, VV, VC, B >::
-_UpdateNeigh( _TNode& nn, const _TNode& n )
-{
-  return( true );
-}
-
 #endif // __FPA__BASE__REGIONGROWING__HXX__
 
 // eof - $RCSfile$
index e23a1084c3a585826adb7f9e54ac44bf233f6767..cd218a6ff0d9ef1eaae6694206a27a37d126237b 100644 (file)
@@ -2,91 +2,19 @@
 #define __FPA__IMAGE__ALGORITHM__H__
 
 #include <itkImage.h>
-#include <itkFunctionBase.h>
 
 namespace fpa
 {
   namespace Image
   {
-    namespace Functors
-    {
-      /**
-       */
-      template< class VV, class C >
-      class CastVertexValueToCost
-        : public itk::FunctionBase< VV, C >
-      {
-      public:
-        // Type-related and pointers
-        typedef CastVertexValueToCost           Self;
-        typedef itk::FunctionBase< VV, C >      Superclass;
-        typedef itk::SmartPointer< Self >       Pointer;
-        typedef itk::SmartPointer< const Self > ConstPointer;
-
-      public:
-        itkNewMacro( Self );
-        itkTypeMacro( CastVertexValueToCost, itkFunctionBase );
-
-      public:
-        virtual C Evaluate( const VV& v ) const
-          { return( C( v ) ); }
-
-      protected:
-        CastVertexValueToCost( )
-          : Superclass( )
-          { }
-        virtual ~CastVertexValueToCost( )
-          { }
-
-      private:
-        // Purposely not implemented
-        CastVertexValueToCost( const Self& );
-        void operator=( const Self& );
-      };
-
-      /**
-       */
-      template< class VV, class C >
-      class CastVertexValueToConstantCost
-        : public itk::FunctionBase< VV, C >
-      {
-      public:
-        // Type-related and pointers
-        typedef CastVertexValueToConstantCost   Self;
-        typedef itk::FunctionBase< VV, C >      Superclass;
-        typedef itk::SmartPointer< Self >       Pointer;
-        typedef itk::SmartPointer< const Self > ConstPointer;
-
-      public:
-        itkNewMacro( Self );
-        itkTypeMacro( CastVertexValueToConstantCost, itkFunctionBase );
-
-      public:
-        virtual C Evaluate( const VV& v ) const
-          { return( C( 1 ) ); }
-
-      protected:
-        CastVertexValueToConstantCost( )
-          : Superclass( )
-          { }
-        virtual ~CastVertexValueToConstantCost( )
-          { }
-
-      private:
-        // Purposely not implemented
-        CastVertexValueToConstantCost( const Self& );
-        void operator=( const Self& );
-      };
-
-    } // ecapseman
-
     /**
      * A generic front propagation algorithm were vertices are image pixels.
      *
-     * @param I    Input image type
-     * @param A    Base algorithm (RegionGrow, Dijkstra or FastMarching)
+     * @param I Input image type
+     * @param O Output image type
+     * @param A Base algorithm (RegionGrow, Dijkstra or FastMarching)
      */
-    template< class I, class A, class CC >
+    template< class I, class O, class A >
     class Algorithm
       : public A
     {
@@ -98,72 +26,65 @@ namespace fpa
       typedef itk::SmartPointer< const Self > ConstPointer;
 
       /// Template input values
-      typedef I  TInputImage;
-      typedef A  TBaseAlgorithm;
-      typedef CC TCostConversionFunction;
-
-      typedef typename A::TTraits            TTraits;
-      typedef typename TTraits::TCost        TCost;
-      typedef typename TTraits::TResult      TResult;
-      typedef typename TTraits::TVertex      TVertex;
-      typedef typename TTraits::TVertexValue TVertexValue;
+      typedef I TInputImage;
+      typedef O TOutputImage;
 
-      typedef itk::Image< TResult, I::ImageDimension > TOutputImage;
+      typedef typename Superclass::TVertex TVertex;
+      typedef typename Superclass::TValue  TValue;
+      typedef typename Superclass::TResult TResult;
 
     protected:
-      typedef typename TTraits::TFrontId _TFrontId;
-      typedef typename TTraits::TNode    _TNode;
-      typedef typename TTraits::TNodes   _TNodes;
+      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;
 
-    private:
-      typedef itk::Image< bool, I::ImageDimension >      _TMarks;
-      typedef itk::Image< _TFrontId, I::ImageDimension > _TFrontsIds;
-      typedef itk::Image< TVertex, I::ImageDimension >   _TParents;
+      typedef itk::Image< _TNode, I::ImageDimension > _TMarks;
 
     public:
       itkTypeMacro( Algorithm, TAlgorithm );
 
       /// Set/Get
       itkGetConstMacro( NeighborhoodOrder, unsigned int );
-      itkGetConstObjectMacro( CostConversion, TCostConversionFunction );
-      itkGetObjectMacro( CostConversion, TCostConversionFunction );
-
       itkSetMacro( NeighborhoodOrder, unsigned int );
-      itkSetObjectMacro( CostConversion, TCostConversionFunction );
 
     protected:
       Algorithm( );
       virtual ~Algorithm( );
 
-      /// Base interface
-      virtual bool _UpdateResult( _TNode& n );
-
-      /// Pure virtual interface: vertices
-      virtual unsigned long _NumberOfVertices ( ) const;
-      virtual  TVertexValue _Value            ( const TVertex& v ) const;
-      virtual       TResult _Result           ( const TVertex& v ) const;
-
-      /// Pure virtual interface: edges
-      virtual double _Norm ( const TVertex& a, const TVertex& b ) const;
-      virtual   bool _Edge ( const TVertex& a, const TVertex& b ) const;
-      virtual  TCost _Cost ( const TVertex& a, const TVertex& b ) const;
-
-      /// Pure virtual interface: neighborhood
-      virtual void _Neighs      ( const _TNode& n, _TNodes& N ) const;
-      virtual void _NeighsInDim ( const _TNode& n,
-                                  const unsigned int& d,
-                                  _TNodes& N );
-
-      /// Pure virtual interface: results
-      virtual void _InitializeResults ( );
+      virtual void _BeforeGenerateData( );
+
+      // Graph-related abstract methods
+      virtual unsigned long _NumberOfVertices( ) const;
+      virtual const TValue& _VertexValue( const TVertex& v ) const;
+      virtual double _Distance(
+        const TVertex& a, const TVertex& b
+        ) const;
+      virtual bool _HasEdge( const TVertex& a, const TVertex& b ) const;
+      virtual void _Neighborhood(
+        _TVertices& neighborhood, const TVertex& v
+        ) const;
+
+      // Results-related abstract methods
+      virtual void _InitResults( );
+      virtual const TResult& _Result( const TVertex& v ) const;
+      virtual void _SetResult( const TVertex& v, const TResult& r );
+
+      // Marks-related abstract methods
+      virtual const _TNode& _Node( const TVertex& v ) const;
+      virtual void _InitMarks( );
+      virtual void _Mark( const _TNode& node );
 
     private:
-      Algorithm( const Self& );      // Not impl.
-      void operator=( const Self& ); // Not impl.
+      // Purposely not implemented
+      Algorithm( const Self& other );
+      Self& operator=( const Self& other );
 
     protected:
-      unsigned int                              m_NeighborhoodOrder;
-      typename TCostConversionFunction::Pointer m_CostConversion;
+      unsigned int m_NeighborhoodOrder;
+      typename _TMarks::Pointer m_Marks;
     };
 
   } // ecapseman
index 4a57bddef02b9f60eb44d604c3f4a14cc74d4478..0d83b035e6f821ccb52fe9d3bc0a843f0c72ebe7 100644 (file)
@@ -2,68 +2,54 @@
 #define __FPA__IMAGE__ALGORITHM__HXX__
 
 #include <cmath>
-#include <limits>
 #include <itkConstNeighborhoodIterator.h>
 
 // -------------------------------------------------------------------------
-template< class I, class A, class CC >
-fpa::Image::Algorithm< I, A, CC >::
+template< class I, class O, class A >
+fpa::Image::Algorithm< I, O, A >::
 Algorithm( )
   : Superclass( ),
     m_NeighborhoodOrder( 1 )
 {
-  this->m_CostConversion = TCostConversionFunction::New( );
 }
 
 // -------------------------------------------------------------------------
-template< class I, class A, class CC >
-fpa::Image::Algorithm< I, A, CC >::
+template< class I, class O, class A >
+fpa::Image::Algorithm< I, O, A >::
 ~Algorithm( )
 {
 }
 
 // -------------------------------------------------------------------------
-template< class I, class A, class CC >
-bool fpa::Image::Algorithm< I, A, CC >::
-_UpdateResult( _TNode& n )
+template< class I, class O, class A >
+void fpa::Image::Algorithm< I, O, A >::
+_BeforeGenerateData( )
 {
-  bool ret = this->Superclass::_UpdateResult( n );
-  this->GetOutput( )->SetPixel( n.Vertex, n.Result );
-  return( ret );
+  this->Superclass::_BeforeGenerateData( );
+  this->AllocateOutputs( );
 }
 
 // -------------------------------------------------------------------------
-template< class I, class A, class CC >
-unsigned long fpa::Image::Algorithm< I, A, CC >::
+template< class I, class O, class A >
+unsigned long fpa::Image::Algorithm< I, O, A >::
 _NumberOfVertices( ) const
 {
-  return(
-    this->GetInput( )->GetLargestPossibleRegion( ).GetNumberOfPixels( )
-    );
+  return( this->GetInput( )->GetRequestedRegion( ).GetNumberOfPixels( ) );
 }
 
 // -------------------------------------------------------------------------
-template< class I, class A, class CC >
-typename fpa::Image::Algorithm< I, A, CC >::
-TVertexValue fpa::Image::Algorithm< I, A, CC >::
-_Value( const TVertex& v ) const
+template< class I, class O, class A >
+const typename fpa::Image::Algorithm< I, O, A >::
+TValue& fpa::Image::Algorithm< I, O, A >::
+_VertexValue( const TVertex& v ) const
 {
   return( this->GetInput( )->GetPixel( v ) );
 }
 
 // -------------------------------------------------------------------------
-template< class I, class A, class CC >
-typename fpa::Image::Algorithm< I, A, CC >::
-TResult fpa::Image::Algorithm< I, A, CC >::
-_Result( const TVertex& v ) const
-{
-  return( this->GetOutput( )->GetPixel( v ) );
-}
-
-// -------------------------------------------------------------------------
-template< class I, class A, class CC >
-double fpa::Image::Algorithm< I, A, CC >::
-_Norm( const TVertex& a, const TVertex& b ) const
+template< class I, class O, class A >
+double fpa::Image::Algorithm< I, O, A >::
+_Distance( const TVertex& a, const TVertex& b ) const
 {
   typename I::PointType pa, pb;
   this->GetInput( )->TransformIndexToPhysicalPoint( a, pa );
@@ -72,9 +58,9 @@ _Norm( const TVertex& a, const TVertex& b ) const
 }
 
 // -------------------------------------------------------------------------
-template< class I, class A, class CC >
-bool fpa::Image::Algorithm< I, A, CC >::
-_Edge( const TVertex& a, const TVertex& b ) const
+template< class I, class O, class A >
+bool fpa::Image::Algorithm< I, O, A >::
+_HasEdge( const TVertex& a, const TVertex& b ) const
 {
   unsigned long dist = 0;
   for( unsigned int d = 0; d < I::ImageDimension; d++ )
@@ -86,42 +72,23 @@ _Edge( const TVertex& a, const TVertex& b ) const
 }
 
 // -------------------------------------------------------------------------
-template< class I, class A, class CC >
-typename fpa::Image::Algorithm< I, A, CC >::
-TCost fpa::Image::Algorithm< I, A, CC >::
-_Cost( const TVertex& a, const TVertex& b ) const
-{
-  static const TCost INF_COST = std::numeric_limits< TCost >::max( );
-  if( this->_Edge( a, b ) )
-  {
-    return(
-      this->m_CostConversion->Evaluate( this->GetInput( )->GetPixel( b ) )
-      );
-  }
-  else
-    return( INF_COST );
-}
-
-// -------------------------------------------------------------------------
-template< class I, class A, class CC >
-void fpa::Image::Algorithm< I, A, CC >::
-_Neighs( const _TNode& n, _TNodes& N ) const
+template< class I, class O, class A >
+void fpa::Image::Algorithm< I, O, A >::
+_Neighborhood( _TVertices& neighborhood, const TVertex& v ) const
 {
   typename I::RegionType reg = this->GetInput( )->GetRequestedRegion( );
 
-  N.clear( );
+  neighborhood.clear( );
   if( this->m_NeighborhoodOrder == 1 )
   {
     for( unsigned int d = 0; d < I::ImageDimension; d++ )
     {
       for( int i = -1; i <= 1; i += 2 )
       {
-        TVertex v = n.Vertex;
-        v[ d ] += i;
-        if( reg.IsInside( v ) )
-          N.push_back( _TNode( v, n.FrontId ) );
-        else
-          N.push_back( n );
+        TVertex n = v;
+        n[ d ] += i;
+        if( reg.IsInside( n ) )
+          neighborhood.push_back( n );
 
       } // rof
 
@@ -134,15 +101,14 @@ _Neighs( const _TNode& n, _TNodes& N ) const
     nSize.Fill( 1 );
 
     TNeighIt nIt( nSize, this->GetInput( ), reg );
-    nIt.SetLocation( n.Vertex );
+    nIt.SetLocation( v );
     for( unsigned int i = 0; i < nIt.Size( ); i++ )
     {
-      TVertex idxN = nIt.GetIndex( i );
-      if( idxN == n.Vertex )
-        continue;
-      if( !reg.IsInside( idxN ) )
+      TVertex n = nIt.GetIndex( i );
+      if( n == v )
         continue;
-      N.push_back( _TNode( idxN, n.FrontId ) );
+      if( reg.IsInside( n ) )
+        neighborhood.push_back( n );
 
     } // rof
 
@@ -150,28 +116,65 @@ _Neighs( const _TNode& n, _TNodes& N ) const
 }
 
 // -------------------------------------------------------------------------
-template< class I, class A, class CC >
-void fpa::Image::Algorithm< I, A, CC >::
-_NeighsInDim( const _TNode& n, const unsigned int& d, _TNodes& N )
+template< class I, class O, class A >
+void fpa::Image::Algorithm< I, O, A >::
+_InitResults( )
 {
-  typename I::RegionType reg = this->GetInput( )->GetRequestedRegion( );
+}
 
-  N.clear( );
-  for( int i = -1; i <= 1; i += 2 )
-  {
-    TVertex v = n.Vertex;
-    v[ d ] += i;
-    if( reg.IsInside( v ) )
-      N.push_back( _TNode( v, n.FrontId ) );
+// -------------------------------------------------------------------------
+template< class I, class O, class A >
+const typename fpa::Image::Algorithm< I, O, A >::
+TResult& fpa::Image::Algorithm< I, O, A >::
+_Result( const TVertex& v ) const
+{
+  return( this->GetOutput( )->GetPixel( v ) );
+}
+
+// -------------------------------------------------------------------------
+template< class I, class O, class A >
+void fpa::Image::Algorithm< I, O, A >::
+_SetResult( const TVertex& v, const TResult& r )
+{
+  this->GetOutput( )->SetPixel( v, r );
+}
+
+// -------------------------------------------------------------------------
+template< class I, class O, class A >
+const typename fpa::Image::Algorithm< I, O, A >::
+_TNode& fpa::Image::Algorithm< I, O, A >::
+_Node( const TVertex& v ) const
+{
+  return( this->m_Marks->GetPixel( v ) );
+}
 
-  } // rof
+// -------------------------------------------------------------------------
+template< class I, class O, class A >
+void fpa::Image::Algorithm< I, O, A >::
+_InitMarks( )
+{
+  const I* in = this->GetInput( );
+
+  this->m_Marks = _TMarks::New( );
+  this->m_Marks->SetLargestPossibleRegion( in->GetLargestPossibleRegion( ) );
+  this->m_Marks->SetRequestedRegion( in->GetRequestedRegion( ) );
+  this->m_Marks->SetBufferedRegion( in->GetBufferedRegion( ) );
+  this->m_Marks->SetOrigin( in->GetOrigin( ) );
+  this->m_Marks->SetSpacing( in->GetSpacing( ) );
+  this->m_Marks->SetDirection( in->GetDirection( ) );
+  this->m_Marks->Allocate( );
+
+  _TNode far_node;
+  far_node.Label = Self::FarLabel;
+  this->m_Marks->FillBuffer( far_node );
 }
 
 // -------------------------------------------------------------------------
-template< class I, class A, class CC >
-void fpa::Image::Algorithm< I, A, CC >::
-_InitializeResults( )
+template< class I, class O, class A >
+void fpa::Image::Algorithm< I, O, A >::
+_Mark( const _TNode& node )
 {
+  this->m_Marks->SetPixel( node.Vertex, node );
 }
 
 #endif // __FPA__IMAGE__ALGORITHM__HXX__
index 1464d3cfd2953d01bfa2c0714437bba3ce42ad12..4e5105ca90b65b99dfb2747813af60dae0bfdedd 100644 (file)
@@ -1,12 +1,11 @@
 #ifndef __FPA__IMAGE__DIJKSTRA__H__
 #define __FPA__IMAGE__DIJKSTRA__H__
 
-#include <itkImage.h>
-#include <itkImageFunction.h>
+#include <itkFunctionBase.h>
 #include <itkImageToImageFilter.h>
-#include <itkIndex.h>
 #include <fpa/Base/Dijkstra.h>
 #include <fpa/Image/Algorithm.h>
+#include <fpa/Image/Functors/ImageCostFunction.h>
 
 namespace fpa
 {
@@ -14,45 +13,75 @@ namespace fpa
   {
     /**
      * @param I Input image type
+     * @param O Output image type
      */
-    template< class I, class C >
+    template< class I, class O >
     class Dijkstra
-      : public Algorithm< I, fpa::Base::Dijkstra< typename I::IndexType, C, typename I::PixelType, itk::Functor::IndexLexicographicCompare< I::ImageDimension >, itk::ImageToImageFilter< I, itk::Image< C, I::ImageDimension > > > >
+      : public Algorithm< I, O, fpa::Base::Dijkstra< typename I::IndexType, typename I::PixelType, typename O::PixelType, itk::ImageToImageFilter< I, O > > >
     {
     public:
-      // Standard class typdedefs
-      typedef typename I::IndexType TVertex;
-      typedef typename I::PixelType TVertexValue;
-      typedef itk::Image< C, I::ImageDimension > TCostImage;
-      typedef itk::ImageToImageFilter< I, TCostImage > TBaseFilter;
-      typedef fpa::Base::Dijkstra< TVertex, C, TVertexValue, itk::Functor::IndexLexicographicCompare< I::ImageDimension >, TBaseFilter > TBaseAlgorithm;
-
-      typedef Dijkstra                        Self;
-      typedef Algorithm< I, TBaseAlgorithm >  Superclass;
-      typedef itk::SmartPointer< Self >       Pointer;
-      typedef itk::SmartPointer< const Self > ConstPointer;
+      typedef fpa::Base::Dijkstra< typename I::IndexType, typename I::PixelType, typename O::PixelType, itk::ImageToImageFilter< I, O > > TBaseAlgorithm;
+
+      typedef Dijkstra                          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 fpa::Image::Functors::ImageCostFunction< TInputImage, TResult > TCostFunction;
+      typedef itk::FunctionBase< TResult, TResult > TConversionFunction;
+
+    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( Dijkstra, fpaBaseDijkstra );
+      itkTypeMacro( Dijkstra, Algorithm );
+
+      itkGetObjectMacro( CostFunction, TCostFunction );
+      itkGetObjectMacro( ConversionFunction, TConversionFunction );
+
+      itkGetConstObjectMacro( CostFunction, TCostFunction );
+      itkGetConstObjectMacro( ConversionFunction, TConversionFunction );
+
+      itkSetObjectMacro( CostFunction, TCostFunction );
+      itkSetObjectMacro( ConversionFunction, TConversionFunction );
 
     protected:
-      Dijkstra( )
-        : Superclass( )
-        { }
-      virtual ~Dijkstra( )
-        { }
+      Dijkstra( );
+      virtual ~Dijkstra( );
+
+      virtual TResult _Cost( const TVertex& v, const TVertex& p ) const;
+
+      virtual void _BeforeGenerateData( );
+      virtual void _InitResults( );
 
     private:
       // Purposely not implemented
-      Dijkstra( const Self& );
-      void operator=( const Self& );
+      Dijkstra( const Self& other );
+      Self& operator=( const Self& other );
+
+    protected:
+      typename TCostFunction::Pointer m_CostFunction;
+      typename TConversionFunction::Pointer m_ConversionFunction;
     };
 
   } // ecapseman
 
 } // ecapseman
 
+#include <fpa/Image/Dijkstra.hxx>
+
 #endif // __FPA__IMAGE__DIJKSTRA__H__
 
 // eof - $RCSfile$
diff --git a/lib/fpa/Image/Dijkstra.hxx b/lib/fpa/Image/Dijkstra.hxx
new file mode 100644 (file)
index 0000000..eca6ce3
--- /dev/null
@@ -0,0 +1,59 @@
+#ifndef __FPA__IMAGE__DIJKSTRA__HXX__
+#define __FPA__IMAGE__DIJKSTRA__HXX__
+
+#include <limits>
+
+// -------------------------------------------------------------------------
+template< class I, class O >
+fpa::Image::Dijkstra< I, O >::
+Dijkstra( )
+  : Superclass( )
+{
+  this->m_CostFunction = TCostFunction::New( );
+}
+
+// -------------------------------------------------------------------------
+template< class I, class O >
+fpa::Image::Dijkstra< I, O >::
+~Dijkstra( )
+{
+}
+
+// -------------------------------------------------------------------------
+template< class I, class O >
+typename fpa::Image::Dijkstra< I, O >::
+TResult fpa::Image::Dijkstra< I, O >::
+_Cost( const TVertex& v, const TVertex& p ) const
+{
+  if( this->_HasEdge( v, p ) )
+  {
+    TResult c = this->m_CostFunction->Evaluate( v, p );
+    if( this->m_ConversionFunction.IsNotNull( ) )
+      c = this->m_ConversionFunction->Evaluate( c );
+    return( c );
+  }
+  else
+    return( std::numeric_limits< TResult >::max( ) );
+}
+
+// -------------------------------------------------------------------------
+template< class I, class O >
+void fpa::Image::Dijkstra< I, O >::
+_BeforeGenerateData( )
+{
+  this->Superclass::_BeforeGenerateData( );
+  this->m_CostFunction->SetInputImage( this->GetInput( ) );
+}
+
+// -------------------------------------------------------------------------
+template< class I, class O >
+void fpa::Image::Dijkstra< I, O >::
+_InitResults( )
+{
+  this->Superclass::_InitResults( );
+  this->GetOutput( )->FillBuffer( std::numeric_limits< TResult >::max( ) );
+}
+
+#endif // __FPA__IMAGE__DIJKSTRA__HXX__
+
+// eof - $RCSfile$
diff --git a/lib/fpa/Image/Functors/ImageCostFunction.h b/lib/fpa/Image/Functors/ImageCostFunction.h
new file mode 100644 (file)
index 0000000..533b64b
--- /dev/null
@@ -0,0 +1,90 @@
+#ifndef __FPA__IMAGE__FUNCTORS__IMAGECOSTFUNCTION__H__
+#define __FPA__IMAGE__FUNCTORS__IMAGECOSTFUNCTION__H__
+
+#include <limits>
+#include <itkNumericTraits.h>
+#include <itkObject.h>
+
+namespace fpa
+{
+  namespace Image
+  {
+    namespace Functors
+    {
+      /**
+       */
+      template< class I, class R >
+      class ImageCostFunction
+        : public itk::Object
+      {
+      public:
+        /// Type-related and pointers
+        typedef ImageCostFunction               Self;
+        typedef itk::Object                     Superclass;
+        typedef itk::SmartPointer< Self >       Pointer;
+        typedef itk::SmartPointer< const Self > ConstPointer;
+
+        typedef I TInputImage;
+        typedef R TResult;
+        typedef typename I::IndexType TIndex;
+
+      public:
+        itkNewMacro( Self );
+        itkTypeMacro( ImageCostFunction, itkObject );
+
+        itkGetConstObjectMacro( InputImage, I );
+        itkSetConstObjectMacro( InputImage, I );
+
+      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 );
+              if( typeid( _TPixel ) != typeid( _TValue ) )
+              {
+                _TVector* array = reinterpret_cast< _TVector* >( &pix );
+                unsigned int n =
+                  this->m_InputImage->GetNumberOfComponentsPerPixel( );
+                R sum = R( 0 );
+                for( unsigned int i = 0; i < n; ++i )
+                  sum += R( ( *array )[ i ] );
+                return( sum / R( n ) );
+              }
+              else
+                return( R( *( reinterpret_cast< _TValue* >( &pix ) ) ) );
+            }
+            else
+              return( std::numeric_limits< R >::max( ) );
+          }
+
+      protected:
+        ImageCostFunction( )
+          : Superclass( )
+          { }
+        virtual ~ImageCostFunction( )
+          { }
+
+      private:
+        // Purposely not implemented
+        ImageCostFunction( const Self& );
+        void operator=( const Self& );
+
+      protected:
+        typename I::ConstPointer m_InputImage;
+      };
+
+    } // ecapseman
+
+  } // ecapseman
+
+} // ecapseman
+
+#endif // __FPA__IMAGE__FUNCTORS__IMAGECOSTFUNCTION__H__
+
+// eof - $RCSfile$
diff --git a/lib/fpa/Image/Functors/ImageFunction.h b/lib/fpa/Image/Functors/ImageFunction.h
deleted file mode 100644 (file)
index a1cc9ec..0000000
+++ /dev/null
@@ -1,62 +0,0 @@
-#ifndef __FPA__IMAGE__FUNCTORS__IMAGEFUNCTION__H__
-#define __FPA__IMAGE__FUNCTORS__IMAGEFUNCTION__H__
-
-#include <itkFunctionBase.h>
-
-namespace fpa
-{
-  namespace Image
-  {
-    namespace Functors
-    {
-      /**
-       */
-      template< class I, class O >
-      class ImageFunction
-        : public itk::FunctionBase< typename I::IndexType, O >
-      {
-      public:
-        /// Type-related and pointers
-        typedef ImageFunction                                 Self;
-        typedef itk::FunctionBase< typename I::IndexType, O > Superclass;
-        typedef itk::SmartPointer< Self >                     Pointer;
-        typedef itk::SmartPointer< const Self >               ConstPointer;
-
-        typedef I TInputImage;
-        typedef O TOutputValue;
-        typedef typename I::IndexType TIndex;
-
-      public:
-        itkTypeMacro( ImageFunction, itkFunctionBase );
-
-        itkGetConstObjectMacro( InputImage, I );
-        itkSetConstObjectMacro( InputImage, I );
-
-      public:
-        virtual O Evaluate( const TIndex& idx ) const = 0;
-
-      protected:
-        ImageFunction( )
-          : Superclass( )
-          { }
-        virtual ~ImageFunction( )
-          { }
-
-      private:
-        // Purposely not implemented
-        ImageFunction( const Self& );
-        void operator=( const Self& );
-
-      protected:
-        typename I::ConstPointer m_InputImage;
-      };
-
-    } // ecapseman
-
-  } // ecapseman
-
-} // ecapseman
-
-#endif // __FPA__IMAGE__FUNCTORS__IMAGEFUNCTION__H__
-
-// eof - $RCSfile$
index b12a869d87ccdca57610f351da531a9b71e30bc0..e20f062e07cf6c2563da1533437ed969bb2f4207 100644 (file)
@@ -1,11 +1,10 @@
 #ifndef __FPA__IMAGE__REGIONGROW__H__
 #define __FPA__IMAGE__REGIONGROW__H__
 
+#include <itkFunctionBase.h>
 #include <itkImageToImageFilter.h>
-#include <itkIndex.h>
 #include <fpa/Base/RegionGrow.h>
 #include <fpa/Image/Algorithm.h>
-#include <fpa/Image/Functors/ImageFunction.h>
 
 namespace fpa
 {
@@ -13,64 +12,55 @@ namespace fpa
   {
     /**
      * @param I Input image type
+     * @param O Output image type
      */
-    template< class I, class O = I, class CC = fpa::Image::Functors::CastVertexValueToCost< typename I::PixelType, typename O::PixelType > >
+    template< class I, class O >
     class RegionGrow
-      : public Algorithm< I, fpa::Base::RegionGrow< typename I::IndexType, typename O::PixelType, typename I::PixelType, itk::Functor::IndexLexicographicCompare< I::ImageDimension >, itk::ImageToImageFilter< I, O > >, CC >
+      : public Algorithm< I, O, fpa::Base::RegionGrow< typename I::IndexType, typename I::PixelType, typename O::PixelType, itk::ImageToImageFilter< I, O > > >
     {
     public:
-      // Standard class typdedefs
-      typedef typename I::IndexType TVertex;
-      typedef typename O::PixelType TResult;
-      typedef typename I::PixelType TVertexValue;
-      typedef itk::ImageToImageFilter< I, O > TBaseFilter;
-      typedef fpa::Base::RegionGrow< TVertex, TResult, TVertexValue, itk::Functor::IndexLexicographicCompare< I::ImageDimension >, TBaseFilter > TBaseAlgorithm;
-
-      typedef RegionGrow                         Self;
-      typedef Algorithm< I, TBaseAlgorithm, CC > Superclass;
-      typedef itk::SmartPointer< Self >          Pointer;
-      typedef itk::SmartPointer< const Self >    ConstPointer;
-
-      typedef
-      fpa::Image::Functors::ImageFunction< I, bool >
-      TMembershipFunction;
+      typedef fpa::Base::RegionGrow< typename I::IndexType, typename I::PixelType, typename O::PixelType, 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;
+
+    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( RegionGrow, fpaBaseRegionGrow );
+      itkTypeMacro( RegionGrow, Algorithm );
 
       itkGetObjectMacro( MembershipFunction, TMembershipFunction );
+      itkGetConstObjectMacro( MembershipFunction, TMembershipFunction );
       itkSetObjectMacro( MembershipFunction, TMembershipFunction );
 
     protected:
-      RegionGrow( )
-        : Superclass( ),
-          m_MembershipFunction( NULL )
-        { }
-      virtual ~RegionGrow( )
-        { }
-
-      virtual bool _CheckMembership(
-        const typename Superclass::_TNode& n
-        ) const
-        {
-          if( this->m_MembershipFunction.IsNotNull( ) )
-          {
-            if(
-              this->m_MembershipFunction->GetInputImage( ) !=
-              this->GetInput( )
-              )
-              this->m_MembershipFunction->SetInputImage( this->GetInput( ) );
-            return( this->m_MembershipFunction->Evaluate( n.Vertex ) );
-          }
-          else
-            return( false );
-        }
+      RegionGrow( );
+      virtual ~RegionGrow( );
+
+      virtual bool _CheckMembership( const TVertex& v ) const;
+      virtual void _InitResults( );
 
     private:
       // Purposely not implemented
-      RegionGrow( const Self& );
-      void operator=( const Self& );
+      RegionGrow( const Self& other );
+      Self& operator=( const Self& other );
 
     protected:
       typename TMembershipFunction::Pointer m_MembershipFunction;
@@ -80,6 +70,8 @@ namespace fpa
 
 } // ecapseman
 
+#include <fpa/Image/RegionGrow.hxx>
+
 #endif // __FPA__IMAGE__REGIONGROW__H__
 
 // eof - $RCSfile$
diff --git a/lib/fpa/Image/RegionGrow.hxx b/lib/fpa/Image/RegionGrow.hxx
new file mode 100644 (file)
index 0000000..e8e92c8
--- /dev/null
@@ -0,0 +1,41 @@
+#ifndef __FPA__IMAGE__REGIONGROW__HXX__
+#define __FPA__IMAGE__REGIONGROW__HXX__
+
+// -------------------------------------------------------------------------
+template< class I, class O >
+fpa::Image::RegionGrow< I, O >::
+RegionGrow( )
+  : Superclass( )
+{
+}
+
+// -------------------------------------------------------------------------
+template< class I, class O >
+fpa::Image::RegionGrow< I, O >::
+~RegionGrow( )
+{
+}
+
+// -------------------------------------------------------------------------
+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->GetOutput( )->FillBuffer( this->m_OutsideValue );
+}
+
+#endif // __FPA__IMAGE__REGIONGROW__HXX__
+
+// eof - $RCSfile$
index 68dcae0fe0efcc39a29c5f43b252b6fce5aafd7d..c61af4dc4aa315277446526e8250b1a943aaa639 100644 (file)
@@ -36,8 +36,11 @@ namespace fpa
       itkNewMacro( Self );
       itkTypeMacro( Image2DObserver, itkCommand );
 
+      itkGetConstMacro( RenderPercentage, double );
+      itkSetMacro( RenderPercentage, double );
+
     public:
-      void SetImage( const TImage* img, R* rw );
+      void SetRenderWindow( R* rw );
       void SetPixel(
         typename TImage::IndexType idx,
         unsigned char red,
@@ -51,33 +54,21 @@ namespace fpa
       void Execute( const itk::Object* c, const itk::EventObject& e );
 
     protected:
-      Image2DObserver( )
-        : Superclass( ),
-          m_RenderWindow( NULL ),
-          m_Number( 0 ),
-          m_Percentage( 0 )
-        {
-          this->m_Stencil = TImageData::New( );
-          this->m_StencilActor = TImageActor::New( );
-        }
-      virtual ~Image2DObserver( )
-        { }
+      Image2DObserver( );
+      virtual ~Image2DObserver( );
 
     private:
       Image2DObserver( const Self& ); // Not impl.
       void operator=( const Self& );  // Not impl.
 
     protected:
-      typedef vtkSmartPointer< vtkImageActor > TImageActor;
-      typedef vtkSmartPointer< vtkImageData >  TImageData;
-
-      typename TImage::ConstPointer m_Image;
+      vtkSmartPointer< vtkImageData >  m_Stencil;
+      vtkSmartPointer< vtkImageActor > m_StencilActor;
 
       R*            m_RenderWindow;
-      TImageData    m_Stencil;
-      TImageActor   m_StencilActor;
-      unsigned long m_Number;
-      unsigned long m_Percentage;
+      unsigned long m_Count;
+      unsigned long m_RenderCount;
+      double        m_RenderPercentage;
     };
 
   } // ecapseman
index 7ebe52613e6b85e78fc85c25c4d8171fe1a64635..74e5f4c02052ab89d22891e6958beb05762d662d 100644 (file)
 // -------------------------------------------------------------------------
 template< class F, class R >
 void fpa::VTK::Image2DObserver< F, R >::
-SetImage( const TImage* img, R* rw )
+SetRenderWindow( R* rw )
 {
-  this->m_Image = img;
   this->m_RenderWindow = rw;
 
-  unsigned int minD = TImage::ImageDimension;
-  minD = ( minD < 3 )? minD: 3;
-
-  int e[ 6 ] = { 0 };
-  typename TImage::RegionType reg = this->m_Image->GetRequestedRegion( );
-  for( unsigned int i = 0; i < minD; i++ )
-  {
-    e[ ( i << 1 ) + 0 ] = reg.GetIndex( )[ i ];
-    e[ ( i << 1 ) + 1 ] = reg.GetIndex( )[ i ] + reg.GetSize( )[ i ] - 1;
-
-  } // rof
-
-  typename TImage::SpacingType spac = this->m_Image->GetSpacing( );
-  double s[ 3 ] = { 1, 1, 1 };
-  for( unsigned int i = 0; i < minD; i++ )
-    s[ i ] = double( spac[ i ] );
-
-  typename TImage::PointType orig = this->m_Image->GetOrigin( );
-  double o[ 3 ] = { 0 };
-  for( unsigned int i = 0; i < minD; i++ )
-    o[ i ] = double( orig[ i ] );
-
-  this->m_Stencil->SetExtent( e );
-  this->m_Stencil->SetSpacing( s );
-  this->m_Stencil->SetOrigin( o );
-  this->m_Stencil->AllocateScalars( VTK_UNSIGNED_CHAR, 4 );
-  for( unsigned int i = 0; i < 3; i++ )
-    this->m_Stencil->GetPointData( )->
-      GetScalars( )->FillComponent( i, 255 );
-  this->m_Stencil->GetPointData( )->GetScalars( )->FillComponent( 3, 0 );
-
-  this->m_StencilActor->SetInputData( this->m_Stencil );
-  this->m_StencilActor->InterpolateOff( );
-
-  double nPix =
-    double( this->m_Image->GetRequestedRegion( ).GetNumberOfPixels( ) );
-  this->m_Percentage = ( unsigned long )( nPix * 0.01 );
-  this->m_Number = 0;
-
-  if( this->m_RenderWindow != NULL )
-  {
-    vtkRenderer* ren =
-      this->m_RenderWindow->GetRenderers( )->GetFirstRenderer( );
-    ren->AddActor( this->m_StencilActor );
-    this->Render( );
-
-  } // fi
+  /* TODO
+     this->m_Image = img;
+     unsigned int minD = TImage::ImageDimension;
+     minD = ( minD < 3 )? minD: 3;
+
+     int e[ 6 ] = { 0 };
+     typename TImage::RegionType reg = this->m_Image->GetRequestedRegion( );
+     for( unsigned int i = 0; i < minD; i++ )
+     {
+     e[ ( i << 1 ) + 0 ] = reg.GetIndex( )[ i ];
+     e[ ( i << 1 ) + 1 ] = reg.GetIndex( )[ i ] + reg.GetSize( )[ i ] - 1;
+
+     } // rof
+
+     typename TImage::SpacingType spac = this->m_Image->GetSpacing( );
+     double s[ 3 ] = { 1, 1, 1 };
+     for( unsigned int i = 0; i < minD; i++ )
+     s[ i ] = double( spac[ i ] );
+
+     typename TImage::PointType orig = this->m_Image->GetOrigin( );
+     double o[ 3 ] = { 0 };
+     for( unsigned int i = 0; i < minD; i++ )
+     o[ i ] = double( orig[ i ] );
+
+     this->m_Stencil->SetExtent( e );
+     this->m_Stencil->SetSpacing( s );
+     this->m_Stencil->SetOrigin( o );
+     this->m_Stencil->AllocateScalars( VTK_UNSIGNED_CHAR, 4 );
+     for( unsigned int i = 0; i < 3; i++ )
+     this->m_Stencil->GetPointData( )->
+     GetScalars( )->FillComponent( i, 255 );
+     this->m_Stencil->GetPointData( )->GetScalars( )->FillComponent( 3, 0 );
+
+     this->m_StencilActor->SetInputData( this->m_Stencil );
+     this->m_StencilActor->InterpolateOff( );
+
+     double nPix =
+     double( this->m_Image->GetRequestedRegion( ).GetNumberOfPixels( ) );
+     this->m_Percentage = ( unsigned long )( nPix * 0.01 );
+     this->m_Number = 0;
+
+     if( this->m_RenderWindow != NULL )
+     {
+     vtkRenderer* ren =
+     this->m_RenderWindow->GetRenderers( )->GetFirstRenderer( );
+     ren->AddActor( this->m_StencilActor );
+     this->Render( );
+
+     } // fi
+  */
 }
 
 // -------------------------------------------------------------------------
@@ -103,13 +105,13 @@ template< class F, class R >
 void fpa::VTK::Image2DObserver< F, R >::
 Execute( const itk::Object* c, const itk::EventObject& e )
 {
-  typedef typename TImage::IndexType        TIndex;
-  typedef typename TImage::PointType        TPoint;
-  typedef typename TFilter::TEvent          TEvent;
-  typedef typename TFilter::TFrontEvent     TFrontEvent;
-  typedef typename TFilter::TMarkEvent      TMarkEvent;
-  typedef typename TFilter::TCollisionEvent TCollisionEvent;
-  typedef typename TFilter::TEndEvent       TEndEvent;
+  typedef typename F::TStartEvent     TStartEvent;
+  typedef typename F::TStartLoopEvent TStartLoopEvent;
+  typedef typename F::TEndEvent       TEndEvent;
+  typedef typename F::TEndLoopEvent   TEndLoopEvent;
+  typedef typename F::TAliveEvent     TAliveEvent;
+  typedef typename F::TFrontEvent     TFrontEvent;
+  typedef typename F::TFreezeEvent    TFreezeEvent;
 
   static unsigned char Colors[][4] =
     {
@@ -131,58 +133,116 @@ Execute( const itk::Object* c, const itk::EventObject& e )
       {  63,  63, 127, 127 }
     };
 
-  if( this->m_RenderWindow == NULL )
+  const F* filter = dynamic_cast< const F* >( c );
+  if( this->m_RenderWindow == NULL || filter == NULL )
+    return;
+
+  const TStartEvent* startEvt = dynamic_cast< const TStartEvent* >( &e );
+  if( startEvt != NULL )
+  {
+    const typename F::TInputImage* img = filter->GetInput( );
+    unsigned int minD = F::TInputImage::ImageDimension;
+    minD = ( minD < 3 )? minD: 3;
+
+    int e[ 6 ] = { 0 };
+    typename F::TInputImage::RegionType reg = img->GetRequestedRegion( );
+    for( unsigned int i = 0; i < minD; i++ )
+    {
+      e[ ( i << 1 ) + 0 ] = reg.GetIndex( )[ i ];
+      e[ ( i << 1 ) + 1 ] = reg.GetIndex( )[ i ] + reg.GetSize( )[ i ] - 1;
+
+    } // rof
+
+    typename F::TInputImage::SpacingType spac = img->GetSpacing( );
+    double s[ 3 ] = { 1, 1, 1 };
+    for( unsigned int i = 0; i < minD; i++ )
+      s[ i ] = double( spac[ i ] );
+
+    typename F::TInputImage::PointType orig = img->GetOrigin( );
+    double o[ 3 ] = { 0 };
+    for( unsigned int i = 0; i < minD; i++ )
+      o[ i ] = double( orig[ i ] );
+
+    this->m_Stencil->SetExtent( e );
+    this->m_Stencil->SetSpacing( s );
+    this->m_Stencil->SetOrigin( o );
+    this->m_Stencil->AllocateScalars( VTK_UNSIGNED_CHAR, 4 );
+    for( unsigned int i = 0; i < 3; i++ )
+      this->m_Stencil->GetPointData( )->
+        GetScalars( )->FillComponent( i, 255 );
+    this->m_Stencil->GetPointData( )->GetScalars( )->FillComponent( 3, 0 );
+
+    this->m_StencilActor->SetInputData( this->m_Stencil );
+    this->m_StencilActor->InterpolateOff( );
+
+    this->m_Count = 0;
+    this->m_RenderCount = reg.GetNumberOfPixels( );
+
+    vtkRenderer* ren =
+      this->m_RenderWindow->GetRenderers( )->GetFirstRenderer( );
+    ren->AddActor( this->m_StencilActor );
     return;
 
-  const TEvent* evt = dynamic_cast< const TEvent* >( &e );
-  TFrontEvent fevt;
-  TMarkEvent mevt;
-  TCollisionEvent cevt;
-  TEndEvent eevt;
-  if( evt != NULL )
+  } // fi
+
+  const TAliveEvent* aliveEvt = dynamic_cast< const TAliveEvent* >( &e );
+  const TFrontEvent* frontEvt = dynamic_cast< const TFrontEvent* >( &e );
+  if( aliveEvt != NULL || frontEvt != NULL )
   {
-    if( mevt.CheckEvent( evt ) )
+    if( aliveEvt != NULL )
       this->SetPixel(
-        evt->Node.Vertex,
-        Colors[ evt->Node.FrontId ][ 0 ],
-        Colors[ evt->Node.FrontId ][ 1 ],
-        Colors[ evt->Node.FrontId ][ 2 ],
-        Colors[ evt->Node.FrontId ][ 3 ]
+        aliveEvt->Vertex,
+        Colors[ aliveEvt->FrontId ][ 0 ],
+        Colors[ aliveEvt->FrontId ][ 1 ],
+        Colors[ aliveEvt->FrontId ][ 2 ],
+        Colors[ aliveEvt->FrontId ][ 3 ]
         );
-    else if( fevt.CheckEvent( evt ) )
-      this->SetPixel( evt->Node.Vertex, 255, 0, 0, 255 );
-    if( cevt.CheckEvent( evt ) )
-      this->SetPixel( evt->Node.Vertex, 100, 50, 25, 255 );
+    else if( frontEvt != NULL )
+      this->SetPixel( frontEvt->Vertex, 255, 0, 0, 255 );
+    this->m_Count++;
 
-    // Update visualization
-    if( this->m_Number == 0 || this->m_Percentage < 0 )
+    // Render visual debug
+    double per = double( this->m_RenderCount ) * this->m_RenderPercentage;
+    if( double( this->m_Count ) >= per )
       this->Render( );
-    this->m_Number++;
-    this->m_Number %= this->m_Percentage;
+    if( double( this->m_Count ) >= per )
+      this->m_Count = 0;
 
-    if( eevt.CheckEvent( evt ) )
-    {
-      if( this->m_RenderWindow != NULL )
-      {
-        /* TODO
-           vtkRenderer* ren =
-           this->m_RenderWindow->GetRenderers( )->GetFirstRenderer( );
-           ren->RemoveActor( this->m_StencilActor );
-        */
-        this->Render( );
-
-      } // fi
-
-    } // fi
-  }
-  else
+    return;
+
+  } // fi
+
+  const TEndEvent* endEvt = dynamic_cast< const TEndEvent* >( &e );
+  if( endEvt != NULL )
   {
-    // TODO: Remove all!
+    vtkRenderer* ren =
+      this->m_RenderWindow->GetRenderers( )->GetFirstRenderer( );
+    ren->RemoveActor( this->m_StencilActor );
     this->Render( );
+    return;
 
   } // fi
 }
 
+// -------------------------------------------------------------------------
+template< class F, class R >
+fpa::VTK::Image2DObserver< F, R >::
+Image2DObserver( )
+  : Superclass( ),
+    m_RenderWindow( NULL ),
+    m_RenderPercentage( double( 0.01 ) )
+{
+  this->m_Stencil = vtkSmartPointer< vtkImageData >::New( );
+  this->m_StencilActor = vtkSmartPointer< vtkImageActor >::New( );
+}
+
+// -------------------------------------------------------------------------
+template< class F, class R >
+fpa::VTK::Image2DObserver< F, R >::
+~Image2DObserver( )
+{
+}
+
 #endif // __FPA__VTK__IMAGE2DOBSERVER__HXX__
 
 // eof - $RCSfile$