+#include <cmath>
#include <iostream>
#include <limits>
#include <string>
#include <itkImage.h>
#include <itkImageFileReader.h>
#include <itkImageToVTKImageFilter.h>
+#include <itkMinimumMaximumImageCalculator.h>
+#include <itkInvertIntensityImageFilter.h>
+#include <itkDanielssonDistanceMapImageFilter.h>
+#include <itkUnaryFunctorImageFilter.h>
#include <vtkImageActor.h>
#include <vtkInteractorStyleImage.h>
typedef unsigned char TPixel;
typedef double TScalar;
typedef itk::Image< TPixel, Dim > TImage;
+typedef itk::Image< TScalar, Dim > TScalarImage;
typedef itk::ImageToVTKImageFilter< TImage > TVTKImage;
typedef itk::ImageFileReader< TImage > TImageReader;
-typedef fpa::Image::Dijkstra< TImage, TScalar > TFrontAlgorithm;
+typedef fpa::Image::Dijkstra< TScalarImage, TScalar > TFrontAlgorithm;
typedef
fpa::VTK::Image2DObserver< TFrontAlgorithm, vtkRenderWindow >
TObserver;
+// -------------------------------------------------------------------------
+class InvertPixelFunctor
+{
+public:
+ InvertPixelFunctor( )
+ { }
+ virtual ~InvertPixelFunctor( )
+ { }
+ bool operator!=( const InvertPixelFunctor& other ) const
+ { return( false ); }
+ bool operator==( const InvertPixelFunctor& other ) const
+ { return( !( *this != other ) ); }
+ inline TScalar operator()( const TScalar& A ) const
+ {
+ return( TScalar( 1 ) / std::pow( TScalar( 1 ) + A, TScalar( 4 ) ) );
+ }
+};
+
// -------------------------------------------------------------------------
int main( int argc, char* argv[] )
{
- if( argc < 2 )
+ if( argc < 3 )
{
std::cerr
<< "Usage: " << argv[ 0 ]
- << " input_image [stop_at_one_front]" << std::endl;
+ << " 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 = false;
- if( 2 < argc )
- stop_at_one_front = ( std::atoi( argv[ 2 ] ) == 1 );
+ if( 3 < argc )
+ stop_at_one_front = ( std::atoi( argv[ 3 ] ) == 1 );
// Read image
TImageReader::Pointer input_image_reader = TImageReader::New( );
widget->On( );
interactor->Start( );
+ // Compute cost map
+ typedef itk::MinimumMaximumImageCalculator< TImage > TMinMax;
+ typedef itk::InvertIntensityImageFilter< TImage > TInvert;
+ typedef itk::DanielssonDistanceMapImageFilter< TImage, TScalarImage > TDanielsson;
+ typedef itk::UnaryFunctorImageFilter< TScalarImage, TScalarImage, InvertPixelFunctor > TInvertFunctor;
+
+ TMinMax::Pointer input_image_min_max = TMinMax::New( );
+ input_image_min_max->SetImage( input_image );
+ input_image_min_max->Compute( );
+
+ TInvert::Pointer invert = TInvert::New( );
+ invert->SetInput( input_image );
+ invert->SetMaximum( input_image_min_max->GetMaximum( ) );
+
+ TDanielsson::Pointer danielsson = TDanielsson::New( );
+ danielsson->SetInput( invert->GetOutput( ) );
+ danielsson->InputIsBinaryOn( );
+ danielsson->SquaredDistanceOff( );
+ danielsson->UseImageSpacingOn( );
+
+ TInvertFunctor::Pointer invert_pixels = TInvertFunctor::New( );
+ invert_pixels->SetInput( danielsson->GetOutput( ) );
+ invert_pixels->Update( );
+
// Configure observer
TObserver::Pointer obs = TObserver::New( );
- obs->SetImage( input_image, window );
+ obs->SetImage( invert_pixels->GetOutput( ), window );
// Configure algorithm
TFrontAlgorithm::Pointer algorithm = TFrontAlgorithm::New( );
} // rof
algorithm->AddObserver( itk::AnyEvent( ), obs );
algorithm->ThrowEventsOn( );
- algorithm->SetInput( input_image );
- algorithm->SetNeighborhoodOrder( 1 );
+ algorithm->SetInput( invert_pixels->GetOutput( ) );
+ algorithm->SetNeighborhoodOrder( neighborhood_order );
algorithm->SetStopAtOneFront( stop_at_one_front );
algorithm->Update( );