]> Creatis software - FrontAlgorithms.git/blobdiff - appli/examples/example_Image_RegionGrow_GaussianModelEstimation.cxx
Refactoring: gaussian model estimator
[FrontAlgorithms.git] / appli / examples / example_Image_RegionGrow_GaussianModelEstimation.cxx
similarity index 50%
rename from appli/examples/example_ImageAlgorithmRegionGrow_GaussianModelEstimator.cxx
rename to appli/examples/example_Image_RegionGrow_GaussianModelEstimation.cxx
index 04fa936b43f9a1a0ca6bd8b95ac6836402ee9094..919409aa948c2838cc253fb39eb7d2f20c392383 100644 (file)
@@ -1,12 +1,15 @@
+#include <cstdlib>
 #include <iostream>
 #include <limits>
 #include <string>
 
 #include <itkImage.h>
-#include <itkImageFileReader.h>
-#include <itkSignedDanielssonDistanceMapImageFilter.h>
 #include <itkImageToVTKImageFilter.h>
+#include <itkRGBPixel.h>
+
+#include <itkImageFileReader.h>
 
+#include <vtkCamera.h>
 #include <vtkImageActor.h>
 #include <vtkInteractorStyleImage.h>
 #include <vtkPointHandleRepresentation3D.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>
 #include <cpPlugins/Extensions/Algorithms/RGBToYPbPrFunction.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 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 unsigned char TPixel;
+typedef float         TScalar;
 
-typedef
-fpa::VTK::Image2DObserver< TFrontAlgorithm, vtkRenderWindow >
-TObserver;
+typedef itk::Image< itk::RGBPixel< TPixel >, Dim > TColorImage;
+typedef itk::Image< TPixel, Dim >                  TImage;
+typedef itk::ImageToVTKImageFilter< TColorImage >  TVTKImage;
 
 // -------------------------------------------------------------------------
 template< class I, class S >
 class GaussianFunction
-  : public fpa::Image::Functors::RegionGrowAllBelongsFunction< I >
+  : public itk::FunctionBase< typename I::PixelType, bool >
 {
 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;
+  typedef GaussianFunction                                 Self;
+  typedef itk::FunctionBase< typename I::PixelType, bool > 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;
   typedef cpPlugins::Extensions::Algorithms::RGBToYPbPrFunction< S > TYPbPrFunction;
 
 public:
   itkNewMacro( Self );
-  itkTypeMacro(
-    GaussianFunction,
-    fpa_Image_Functors_RegionGrowAllBelongsFunction
-    );
+  itkTypeMacro( GaussianFunction, itkFunctionBase );
 
   itkGetConstMacro( ModelSupport, unsigned long );
   itkSetMacro( ModelSupport, unsigned long );
 
-  typedef itk::Image< bool, I::ImageDimension > TMarks;
-
 public:
-  virtual void SetInputImage( TInputImage* img )
+  virtual bool Evaluate( const typename I::PixelType& rgb ) const
     {
-      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 );
-
+      /* TODO
       if( !this->m_Estimating )
       {
-        if( !( this->m_Marks->GetPixel( idx ) ) )
+        this->m_Estimator->AddSample( this->m_YPbPrFunction( rgb ) );
+        if( this->m_Estimator->GetNumberOfSamples( ) == this->m_ModelSupport )
         {
-          this->m_Estimator->AddSample( this->m_YPbPrFunction( rgb ) );
-          this->m_Marks->SetPixel( idx, true );
-          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
+          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
         return( true );
@@ -118,6 +83,8 @@ public:
         return( p > this->m_Estimator->GetMinimumProbability( ) );
 
       } // fi
+      */
+      return( true );
     }
 
 protected:
@@ -143,27 +110,27 @@ protected:
 
   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 )
+  if( argc < 4 )
   {
     std::cerr
       << "Usage: " << argv[ 0 ]
-      << " input_image support" << std::endl;
+      << " input_image neighborhood_order support"
+      << std::endl;
     return( 1 );
 
   } // fi
   std::string input_image_fn = argv[ 1 ];
-  unsigned long support = std::atoi( argv[ 2 ] );
+  unsigned int neighborhood_order = std::atoi( argv[ 2 ] );
+  unsigned long support = std::atoi( argv[ 3 ] );
 
   // Read image
-  TColorImageReader::Pointer input_image_reader = TColorImageReader::New( );
+  itk::ImageFileReader< TColorImage >::Pointer input_image_reader =
+    itk::ImageFileReader< TColorImage >::New( );
   input_image_reader->SetFileName( input_image_fn );
   try
   {
@@ -171,20 +138,21 @@ int main( int argc, char* argv[] )
   }
   catch( itk::ExceptionObject& err )
   {
-    std::cerr << "Error caught: " << err << std::endl;
+    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_image = TVTKImage::New( );
-  vtk_image->SetInput( input_image );
-  vtk_image->Update( );
+  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_image->GetOutput( ) );
+  actor->SetInputData( vtk_input_image->GetOutput( ) );
 
   vtkSmartPointer< vtkRenderer > renderer =
     vtkSmartPointer< vtkRenderer >::New( );
@@ -195,6 +163,12 @@ int main( int argc, char* argv[] )
   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( );
@@ -202,7 +176,6 @@ int main( int argc, char* argv[] )
     vtkSmartPointer< vtkRenderWindowInteractor >::New( );
   interactor->SetInteractorStyle( imageStyle );
   window->SetInteractor( interactor );
-  window->Render( );
 
   // Create the widget and its representation
   vtkSmartPointer< vtkPointHandleRepresentation3D > handle =
@@ -219,44 +192,52 @@ int main( int argc, char* argv[] )
 
   // Let some interaction
   interactor->Initialize( );
+  renderer->ResetCamera( );
   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( );
+  // Prepare region grow function
+  typedef GaussianFunction< TColorImage, TScalar > TFunction;
+  TFunction::Pointer function = TFunction::New( );
+  function->SetModelSupport( support );
+
+  // 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->StopAtOneFrontOff( );
+
+  // Get user-given seeds
   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 ] );
+    TImage::PointType pnt;
+    pnt[ 0 ] = TImage::PointType::ValueType( pos[ 0 ] );
+    pnt[ 1 ] = TImage::PointType::ValueType( pos[ 1 ] );
 
-    TColorImage::IndexType idx;
+    TImage::IndexType idx;
     if( input_image->TransformPhysicalPointToIndex( pnt, idx ) )
-      algorithm->AddSeed( idx, 0 );
+      filter->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( );
+
+  // 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 );
 }