OPTION(BUILD_EXAMPLES "Build examples" OFF)
OPTION(BUILD_SHARED_LIBS "Build shared libs" OFF)
-OPTION(USE_VTK "Build using VTK" OFF)
+OPTION(USE_VTK "Build using VTK" ON)
IF(BUILD_SHARED_LIBS)
SET(LIB_TYPE SHARED)
${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)
--- /dev/null
+#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$
{
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)
*/
- template< class I, class A >
+ template< class I, class A, class CC >
class Algorithm
: public A
{
typedef itk::SmartPointer< const Self > ConstPointer;
/// Template input values
- typedef I TInputImage;
- typedef A TBaseAlgorithm;
+ typedef I TInputImage;
+ typedef A TBaseAlgorithm;
+ typedef CC TCostConversionFunction;
typedef typename A::TTraits TTraits;
typedef typename TTraits::TCost TCost;
typedef typename TTraits::TVertexValue TVertexValue;
typedef itk::Image< TResult, I::ImageDimension > TOutputImage;
- typedef itk::FunctionBase< TCost, TCost > TCostConversionFunction;
protected:
typedef typename TTraits::TFrontId _TFrontId;
#include <itkConstNeighborhoodIterator.h>
// -------------------------------------------------------------------------
-template< class I, class A >
-fpa::Image::Algorithm< I, A >::
+template< class I, class A, class CC >
+fpa::Image::Algorithm< I, A, CC >::
Algorithm( )
: Superclass( ),
m_NeighborhoodOrder( 1 )
{
+ this->m_CostConversion = TCostConversionFunction::New( );
}
// -------------------------------------------------------------------------
-template< class I, class A >
-fpa::Image::Algorithm< I, A >::
+template< class I, class A, class CC >
+fpa::Image::Algorithm< I, A, CC >::
~Algorithm( )
{
}
// -------------------------------------------------------------------------
-template< class I, class A >
-bool fpa::Image::Algorithm< I, A >::
+template< class I, class A, class CC >
+bool fpa::Image::Algorithm< I, A, CC >::
_UpdateResult( _TNode& n )
{
bool ret = this->Superclass::_UpdateResult( n );
}
// -------------------------------------------------------------------------
-template< class I, class A >
-unsigned long fpa::Image::Algorithm< I, A >::
+template< class I, class A, class CC >
+unsigned long fpa::Image::Algorithm< I, A, CC >::
_NumberOfVertices( ) const
{
return(
}
// -------------------------------------------------------------------------
-template< class I, class A >
-typename fpa::Image::Algorithm< I, A >::
-TVertexValue fpa::Image::Algorithm< I, A >::
+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
{
return( this->GetInput( )->GetPixel( v ) );
}
// -------------------------------------------------------------------------
-template< class I, class A >
-typename fpa::Image::Algorithm< I, A >::
-TResult fpa::Image::Algorithm< I, A >::
+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 >
-double fpa::Image::Algorithm< I, A >::
+template< class I, class A, class CC >
+double fpa::Image::Algorithm< I, A, CC >::
_Norm( const TVertex& a, const TVertex& b ) const
{
typename I::PointType pa, pb;
}
// -------------------------------------------------------------------------
-template< class I, class A >
-bool fpa::Image::Algorithm< I, A >::
+template< class I, class A, class CC >
+bool fpa::Image::Algorithm< I, A, CC >::
_Edge( const TVertex& a, const TVertex& b ) const
{
unsigned long dist = 0;
}
// -------------------------------------------------------------------------
-template< class I, class A >
-typename fpa::Image::Algorithm< I, A >::
-TCost fpa::Image::Algorithm< I, A >::
+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 ) )
{
- TCost c = TCost( this->GetInput( )->GetPixel( b ) );
- if( this->m_CostConversion.IsNotNull( ) )
- return( this->m_CostConversion->Evaluate( c ) );
- else
- return( c );
+ return(
+ this->m_CostConversion->Evaluate( this->GetInput( )->GetPixel( b ) )
+ );
}
else
return( INF_COST );
}
// -------------------------------------------------------------------------
-template< class I, class A >
-void fpa::Image::Algorithm< I, A >::
+template< class I, class A, class CC >
+void fpa::Image::Algorithm< I, A, CC >::
_Neighs( const _TNode& n, _TNodes& N ) const
{
typename I::RegionType reg = this->GetInput( )->GetRequestedRegion( );
}
// -------------------------------------------------------------------------
-template< class I, class A >
-void fpa::Image::Algorithm< I, A >::
+template< class I, class A, class CC >
+void fpa::Image::Algorithm< I, A, CC >::
_NeighsInDim( const _TNode& n, const unsigned int& d, _TNodes& N )
{
typename I::RegionType reg = this->GetInput( )->GetRequestedRegion( );
}
// -------------------------------------------------------------------------
-template< class I, class A >
-void fpa::Image::Algorithm< I, A >::
+template< class I, class A, class CC >
+void fpa::Image::Algorithm< I, A, CC >::
_InitializeResults( )
{
}
/**
* @param I Input image type
*/
- template< class I >
+ template< class I, class O = I, class CC = fpa::Image::Functors::CastVertexValueToCost< typename I::PixelType, typename O::PixelType > >
class RegionGrow
- : public Algorithm< I, fpa::Base::RegionGrow< typename I::IndexType, typename I::PixelType, typename I::PixelType, itk::Functor::IndexLexicographicCompare< I::ImageDimension >, itk::ImageToImageFilter< I, I > > >
+ : 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:
// Standard class typdedefs
typedef typename I::IndexType TVertex;
- typedef typename I::PixelType TResult;
+ typedef typename O::PixelType TResult;
typedef typename I::PixelType TVertexValue;
- typedef itk::ImageToImageFilter< I, I > TBaseFilter;
+ 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 > Superclass;
- typedef itk::SmartPointer< Self > Pointer;
- typedef itk::SmartPointer< const Self > ConstPointer;
+ 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 >