-
-SUBDIRS(
- examples
- )
+IF(BUILD_EXAMPLES)
+ SUBDIRS(
+ examples
+ )
+ENDIF(BUILD_EXAMPLES)
## eof - $RCSfile$
-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$
#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;
typedef typename Superclass::TIndex TIndex;
typedef cpPlugins::Extensions::Algorithms::IterativeGaussianModelEstimator< S, 3 > TEstimator;
+ typedef cpPlugins::Extensions::Algorithms::RGBToYPbPrFunction< S > TYPbPrFunction;
public:
itkNewMacro( Self );
{
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:
protected:
typename TEstimator::Pointer m_Estimator;
+ TYPbPrFunction m_YPbPrFunction;
+
unsigned long m_ModelSupport;
mutable bool m_Estimating;
typename TMarks::Pointer m_Marks;
--- /dev/null
+#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$
--- /dev/null
+#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$
--- /dev/null
+#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$
--- /dev/null
+#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$
--- /dev/null
+#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$
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$
#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
* 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;
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
#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 )
}
// -------------------------------------------------------------------------
-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 )
}
// -------------------------------------------------------------------------
-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( );
}
// -------------------------------------------------------------------------
-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 );
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
}
// -------------------------------------------------------------------------
-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__
{
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
#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$
#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
{
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
public:
virtual C Evaluate( const C& input ) const
{
- return( C( 1 ) / ( C( 0 ) + C( input ) ) );
+ return( C( 1 ) / ( C( 1 ) + C( input ) ) );
}
protected:
--- /dev/null
+#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$
#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;
};
#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( );
}
// -------------------------------------------------------------------------
-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$
#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
{
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
#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 );
}
// -------------------------------------------------------------------------
-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++ )
}
// -------------------------------------------------------------------------
-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
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
}
// -------------------------------------------------------------------------
-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__
#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
{
{
/**
* @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$
--- /dev/null
+#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$
--- /dev/null
+#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$
+++ /dev/null
-#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$
#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
{
{
/**
* @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;
} // ecapseman
+#include <fpa/Image/RegionGrow.hxx>
+
#endif // __FPA__IMAGE__REGIONGROW__H__
// eof - $RCSfile$
--- /dev/null
+#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$
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,
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
// -------------------------------------------------------------------------
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
+ */
}
// -------------------------------------------------------------------------
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] =
{
{ 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$