+#include <iostream>
+#include <limits>
+#include <string>
+
+#include <itkImage.h>
+#include <itkImageFileReader.h>
+#include <itkSignedDanielssonDistanceMapImageFilter.h>
+#include <itkImageToVTKImageFilter.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/Image/Functors/RegionGrowAllBelongsFunction.h>
+#include <fpa/VTK/Image2DObserver.h>
+#include <cpPlugins/Extensions/Algorithms/IterativeGaussianModelEstimator.h>
+
+// -------------------------------------------------------------------------
+const unsigned int Dim = 2;
+typedef unsigned char TChannel;
+typedef itk::RGBPixel< TChannel > TPixel;
+typedef double TScalar;
+typedef itk::Image< TChannel, Dim > TImage;
+typedef itk::Image< TPixel, Dim > TColorImage;
+typedef itk::ImageToVTKImageFilter< TColorImage > TVTKImage;
+
+typedef itk::ImageFileReader< TColorImage > TColorImageReader;
+typedef fpa::Image::RegionGrow< TColorImage, TImage, fpa::Image::Functors::CastVertexValueToConstantCost< TPixel, bool > > TFrontAlgorithm;
+
+typedef
+fpa::VTK::Image2DObserver< TFrontAlgorithm, vtkRenderWindow >
+TObserver;
+
+// -------------------------------------------------------------------------
+template< class I, class S >
+class GaussianFunction
+ : public fpa::Image::Functors::RegionGrowAllBelongsFunction< I >
+{
+public:
+ // Type-related and pointers
+ typedef GaussianFunction Self;
+ typedef fpa::Image::Functors::RegionGrowAllBelongsFunction< I > Superclass;
+ typedef itk::SmartPointer< Self > Pointer;
+ typedef itk::SmartPointer< const Self > ConstPointer;
+
+ // Superclass' types
+ typedef typename Superclass::TInputImage TInputImage;
+ typedef typename Superclass::TOutputValue TOutputValue;
+ typedef typename Superclass::TIndex TIndex;
+
+ typedef cpPlugins::Extensions::Algorithms::IterativeGaussianModelEstimator< S, 3 > TEstimator;
+
+public:
+ itkNewMacro( Self );
+ itkTypeMacro(
+ GaussianFunction,
+ fpa_Image_Functors_RegionGrowAllBelongsFunction
+ );
+
+ itkGetConstMacro( ModelSupport, unsigned long );
+ itkSetMacro( ModelSupport, unsigned long );
+
+ typedef itk::Image< bool, I::ImageDimension > TMarks;
+
+public:
+ virtual void SetInputImage( TInputImage* img )
+ {
+ std::cout << "Set!!!" << std::endl;
+ this->Superclass::SetInputImage( img );
+ this->m_Marks = TMarks::New( );
+ this->m_Marks->SetLargestPossibleRegion( img->GetLargestPossibleRegion( ) );
+ this->m_Marks->SetRequestedRegion( img->GetRequestedRegion( ) );
+ this->m_Marks->SetBufferedRegion( img->GetBufferedRegion( ) );
+ this->m_Marks->SetOrigin( img->GetOrigin( ) );
+ this->m_Marks->SetSpacing( img->GetSpacing( ) );
+ this->m_Marks->SetDirection( img->GetDirection( ) );
+ this->m_Marks->Allocate( );
+ this->m_Marks->FillBuffer( false );
+ }
+
+
+ virtual TOutputValue Evaluate( const TIndex& idx ) const
+ {
+ const TInputImage* img = this->GetInputImage( );
+ typename TInputImage::PixelType rgb = img->GetPixel( idx );
+
+ if( !this->m_Estimating )
+ {
+ if( !( this->m_Marks->GetPixel( idx ) ) )
+ {
+ this->m_Estimator->AddSample(
+ S( rgb.GetRed( ) ),
+ S( rgb.GetGreen( ) ),
+ S( rgb.GetBlue( ) )
+ );
+ 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;
+
+ } // fi
+ return( true );
+ }
+ else
+ return( false );
+ }
+
+protected:
+ GaussianFunction( )
+ : Superclass( ),
+ m_ModelSupport( 10 )
+ {
+ this->m_Estimator = TEstimator::New( );
+ this->m_Estimator->Clear( );
+ this->m_Estimating = false;
+ }
+ virtual ~GaussianFunction( )
+ { }
+
+private:
+ // Purposely not implemented
+ GaussianFunction( const Self& );
+ void operator=( const Self& );
+
+protected:
+ typename TEstimator::Pointer m_Estimator;
+ unsigned long m_ModelSupport;
+ mutable bool m_Estimating;
+ typename TMarks::Pointer m_Marks;
+};
+
+typedef GaussianFunction< TColorImage, TScalar > TMembershipFunction;
+
+// -------------------------------------------------------------------------
+int main( int argc, char* argv[] )
+{
+ if( argc < 3 )
+ {
+ std::cerr
+ << "Usage: " << argv[ 0 ]
+ << " input_image support" << std::endl;
+ return( 1 );
+
+ } // fi
+ std::string input_image_fn = argv[ 1 ];
+ unsigned long support = std::atoi( argv[ 2 ] );
+
+ // Read image
+ TColorImageReader::Pointer input_image_reader = TColorImageReader::New( );
+ input_image_reader->SetFileName( input_image_fn );
+ try
+ {
+ input_image_reader->Update( );
+ }
+ catch( itk::ExceptionObject& err )
+ {
+ std::cerr << "Error caught: " << err << std::endl;
+ return( 1 );
+
+ } // yrt
+ TColorImage::ConstPointer input_image = input_image_reader->GetOutput( );
+
+ TVTKImage::Pointer vtk_image = TVTKImage::New( );
+ vtk_image->SetInput( input_image );
+ vtk_image->Update( );
+
+ // VTK visualization
+ vtkSmartPointer< vtkImageActor > actor =
+ vtkSmartPointer< vtkImageActor >::New( );
+ actor->SetInputData( vtk_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 );
+
+ // VTK interaction
+ vtkSmartPointer< vtkInteractorStyleImage > imageStyle =
+ vtkSmartPointer< vtkInteractorStyleImage >::New( );
+ vtkSmartPointer< vtkRenderWindowInteractor > interactor =
+ vtkSmartPointer< vtkRenderWindowInteractor >::New( );
+ interactor->SetInteractorStyle( imageStyle );
+ window->SetInteractor( interactor );
+ window->Render( );
+
+ // 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( );
+ window->Render( );
+ widget->On( );
+ interactor->Start( );
+
+ // Configure observer
+ TObserver::Pointer obs = TObserver::New( );
+ obs->SetImage( input_image, window );
+
+ // Configure membership function
+ TMembershipFunction::Pointer membership = TMembershipFunction::New( );
+ membership->SetModelSupport( support );
+ membership->SetInputImage( const_cast< TColorImage* >( input_image.GetPointer( ) ) );
+
+ // Configure algorithm
+ TFrontAlgorithm::Pointer algorithm = TFrontAlgorithm::New( );
+ for( unsigned int s = 0; s < rep->GetNumberOfSeeds( ); s++ )
+ {
+ double pos[ 3 ];
+ rep->GetSeedWorldPosition( s, pos );
+
+ TColorImage::PointType pnt;
+ pnt[ 0 ] = TScalar( pos[ 0 ] );
+ pnt[ 1 ] = TScalar( pos[ 1 ] );
+
+ TColorImage::IndexType idx;
+ if( input_image->TransformPhysicalPointToIndex( pnt, idx ) )
+ algorithm->AddSeed( idx, 0 );
+
+ } // rof
+ algorithm->AddObserver( itk::AnyEvent( ), obs );
+ algorithm->ThrowEventsOn( );
+ algorithm->SetInput( input_image );
+ algorithm->SetNeighborhoodOrder( 1 );
+ algorithm->SetMembershipFunction( membership );
+ algorithm->Update( );
+
+ // One last interaction
+ interactor->Start( );
+
+ return( 0 );
+}
+
+// eof - $RCSfile$