--- /dev/null
+// -------------------------------------------------------------------------
+// @author Leonardo Florez-Valencia (florez-l@javeriana.edu.co)
+// -------------------------------------------------------------------------
+
+#ifndef __CPEXTENSIONS__ALGORITHMS__CPRFILTER__H__
+#define __CPEXTENSIONS__ALGORITHMS__CPRFILTER__H__
+
+#include <vector>
+
+#include <itkImageToImageFilter.h>
+#include <itkInterpolateImageFunction.h>
+#include <itkJoinSeriesImageFilter.h>
+#include <itkPolyLineParametricPath.h>
+#include <cpExtensions/Algorithms/IsoImageSlicer.h>
+
+namespace cpExtensions
+{
+ namespace Algorithms
+ {
+ /**
+ */
+ template< class I, class S = float >
+ class CPRFilter
+ : public itk::ImageToImageFilter< I, I >
+ {
+ public:
+ // Standard ITK typedefs.
+ typedef CPRFilter Self;
+ typedef itk::ImageToImageFilter< I, I > Superclass;
+ typedef itk::SmartPointer< Self > Pointer;
+ typedef itk::SmartPointer< const Self > ConstPointer;
+ itkStaticConstMacro( VDimension, unsigned int, I::ImageDimension );
+
+ typedef I TImage;
+ typedef S TScalar;
+
+ typedef itk::InterpolateImageFunction< I, S > TInterpolator;
+ typedef itk::PolyLineParametricPath< VDimension > TAxis;
+ typedef cpExtensions::Algorithms::IsoImageSlicer< I, S > TSlicer;
+ typedef typename TSlicer::TSliceImage TSlice;
+ typedef itk::JoinSeriesImageFilter< TSlice, I > TJoin;
+
+ public:
+ itkNewMacro( Self );
+ itkTypeMacro( CPRFilter, itk::ImageToImageFilter );
+
+ itkGetConstMacro( SliceRadius, double );
+ itkGetConstMacro( NumberOfSlices, unsigned int );
+ itkGetObjectMacro( Interpolator, TInterpolator );
+
+ itkSetMacro( SliceRadius, double );
+ itkSetMacro( NumberOfSlices, unsigned int );
+ itkSetObjectMacro( Interpolator, TInterpolator );
+
+ public:
+ const TAxis* GetAxis( ) const;
+ void SetAxis( const TAxis* axis );
+
+ protected:
+ CPRFilter( );
+ virtual ~CPRFilter( );
+
+ private:
+ virtual void GenerateData( );
+
+ protected:
+ double m_SliceRadius;
+ unsigned int m_NumberOfSlices;
+
+ typename TInterpolator::Pointer m_Interpolator;
+ typename TJoin::Pointer m_Join;
+ std::vector< typename TSlicer::Pointer > m_Slices;
+ };
+
+ } // ecapseman
+
+} // ecapseman
+
+#ifndef ITK_MANUAL_INSTANTIATION
+#include <cpExtensions/Algorithms/CPRFilter.hxx>
+#endif // ITK_MANUAL_INSTANTIATION
+
+#endif // __CPEXTENSIONS__ALGORITHMS__CPRFILTER__H__
+
+// eof - $RCSfile$
--- /dev/null
+// -------------------------------------------------------------------------
+// @author Leonardo Florez-Valencia (florez-l@javeriana.edu.co)
+// -------------------------------------------------------------------------
+
+#ifndef __CPEXTENSIONS__ALGORITHMS__CPRFILTER__HXX__
+#define __CPEXTENSIONS__ALGORITHMS__CPRFILTER__HXX__
+
+#include <itkPoint.h>
+#include <itkMinimumMaximumImageCalculator.h>
+#include <itkNearestNeighborInterpolateImageFunction.h>
+#include <cpExtensions/Algorithms/BezierCurveFunction.h>
+
+// -------------------------------------------------------------------------
+template< class I, class S >
+const typename cpExtensions::Algorithms::CPRFilter< I, S >::
+TAxis* cpExtensions::Algorithms::CPRFilter< I, S >::
+GetAxis( ) const
+{
+}
+
+// -------------------------------------------------------------------------
+template< class I, class S >
+void cpExtensions::Algorithms::CPRFilter< I, S >::
+SetAxis( const TAxis* axis )
+{
+}
+
+// -------------------------------------------------------------------------
+template< class I, class S >
+cpExtensions::Algorithms::CPRFilter< I, S >::
+CPRFilter( )
+ : Superclass( )
+{
+ this->m_Interpolator =
+ itk::NearestNeighborInterpolateImageFunction< I, S >::New( );
+}
+
+// -------------------------------------------------------------------------
+template< class I, class S >
+cpExtensions::Algorithms::CPRFilter< I, S >::
+~CPRFilter( )
+{
+}
+
+// -------------------------------------------------------------------------
+template< class I, class S >
+void cpExtensions::Algorithms::CPRFilter< I, S >::
+GenerateData( )
+{
+ typedef itk::Point< S, VDimension > _P;
+ typedef typename _P::VectorType _V;
+ typedef cpExtensions::Algorithms::BezierCurveFunction< _V > _Bezier;
+ typedef typename _Bezier::TFrame _M;
+ typedef itk::MinimumMaximumImageCalculator< I > _MinMax;
+
+ auto image = this->GetInput( );
+ auto axis = this->GetAxis( );
+
+ // 0. Get image properties
+ typename _MinMax::Pointer minmax = _MinMax::New( );
+ minmax->SetImage( image );
+ minmax->Compute( );
+ auto background = minmax->GetMinimum( );
+
+ // 1. Construct Bezier curve
+ typename _Bezier::Pointer bezier = _Bezier::New( );
+ auto vertices = axis->GetVertexList( );
+ for( unsigned int i = 0; i < vertices->Size( ); ++i )
+ {
+ auto index = vertices->GetElement( i );
+ _P point;
+ image->TransformContinuousIndexToPhysicalPoint( index, point );
+ bezier->AddPoint( point.GetVectorFromOrigin( ) );
+
+ } // rof
+
+ // 2. Slice image and prepare join filter
+ this->m_Join = TJoin::New( );
+ unsigned int nSlices = this->m_NumberOfSlices;
+ if( nSlices == 0 )
+ nSlices = bezier->GetNumberOfPoints( );
+ _V vpre;
+ _M mpre;
+ S len = S( 0 );
+ for( unsigned int i = 0; i <= nSlices; ++i )
+ {
+ // Get geometrical data and correct Frenet frame
+ S u = S( i ) / S( nSlices );
+ _V vnex = bezier->Evaluate( u );
+ _M mnex = bezier->EvaluateFrenetFrame( u );
+ if( i > 0 )
+ {
+ len += ( vpre - vnex ).GetNorm( );
+
+ // TODO: Update Frenet frame orientation
+
+ } // fi
+
+ // Slice image
+ typename TSlicer::Pointer slicer = TSlicer::New( );
+ slicer->SetInput( image );
+ slicer->SetRotation( mnex );
+ slicer->SetTranslation( vnex );
+ slicer->SetSize( S( this->m_SliceRadius ) );
+ slicer->SpacingFromMinimumOn( );
+ slicer->SetDefaultValue( background );
+ slicer->SetInterpolator( this->m_Interpolator );
+
+ // Add output to join filter and keep track of the current slicer
+ this->m_Join->SetInput( i, slicer->GetOutput( ) );
+ this->m_Slices.push_back( slicer );
+
+ // Update values
+ vpre = vnex;
+ mpre = mnex;
+
+ } // rof
+
+ // 3. Finish join filter configuration
+ this->m_Join->SetSpacing( double( len / S( nSlices + 1 ) ) );
+ this->m_Join->SetOrigin( double( 0 ) );
+
+ // 4. Graft outputs
+ this->m_Join->GraftOutput( this->GetOutput( ) );
+ this->m_Join->UpdateLargestPossibleRegion( );
+ this->GraftOutput( this->m_Join->GetOutput( ) );
+}
+
+#endif // __CPEXTENSIONS__ALGORITHMS__CPRFILTER__HXX__
+
+// eof - $RCSfile$
--- /dev/null
+#include <cpPlugins/Interface/Macros.h>
+
+#undef ITK_MANUAL_INSTANTIATION
+#include <itkPolyLineParametricPath.h>
+
+// -------------------------------------------------------------------------
+template class cpPlugins_Interface_EXPORT itk::PolyLineParametricPath< 2 >;
+template class cpPlugins_Interface_EXPORT itk::PolyLineParametricPath< 3 >;
+template class cpPlugins_Interface_EXPORT itk::PolyLineParametricPath< 4 >;
+
+// eof - $RCSfile$
--- /dev/null
+#include <cpPlugins/Interface/PolyLineParametricPath.h>
+
+// -------------------------------------------------------------------------
+void cpPlugins::Interface::PolyLineParametricPath::
+SetVTK( vtkObject* path )
+{
+}
+
+// -------------------------------------------------------------------------
+cpPlugins::Interface::PolyLineParametricPath::
+PolyLineParametricPath( )
+ : Superclass( )
+{
+}
+
+// -------------------------------------------------------------------------
+cpPlugins::Interface::PolyLineParametricPath::
+~PolyLineParametricPath( )
+{
+}
+
+// eof - $RCSfile$
--- /dev/null
+#ifndef __CPPLUGINS__INTERFACE__POLYLINEPARAMETRICPATH__H__
+#define __CPPLUGINS__INTERFACE__POLYLINEPARAMETRICPATH__H__
+
+#include <cpPlugins/Interface/DataObject.h>
+
+// Some forward declarations
+class vtkObject;
+
+namespace cpPlugins
+{
+ namespace Interface
+ {
+ /**
+ */
+ class cpPlugins_Interface_EXPORT PolyLineParametricPath
+ : public DataObject
+ {
+ public:
+ typedef PolyLineParametricPath Self;
+ typedef DataObject Superclass;
+ typedef itk::SmartPointer< Self > Pointer;
+ typedef itk::SmartPointer< const Self > ConstPointer;
+
+ public:
+ itkNewMacro( Self );
+ itkTypeMacro( PolyLineParametricPath, DataObject );
+ cpPlugins_Id_Macro( PolyLineParametricPath, DataObject );
+
+ public:
+ template< class P >
+ inline void SetITK( itk::Object* object );
+
+ virtual void SetVTK( vtkObject* path );
+
+ protected:
+ PolyLineParametricPath( );
+ virtual ~PolyLineParametricPath( );
+
+ private:
+ // Purposely not implemented
+ PolyLineParametricPath( const Self& );
+ Self& operator=( const Self& );
+ };
+
+ } // ecapseman
+
+} // ecapseman
+
+#include <cpPlugins/Interface/PolyLineParametricPath.hxx>
+
+#endif // __CPPLUGINS__INTERFACE__POLYLINEPARAMETRICPATH__H__
+
+// eof - $RCSfile$
--- /dev/null
+#ifndef __CPPLUGINS__INTERFACE__POLYLINEPARAMETRICPATH__HXX__
+#define __CPPLUGINS__INTERFACE__POLYLINEPARAMETRICPATH__HXX__
+
+#include <itkPolyLineParametricPath.h>
+
+// -------------------------------------------------------------------------
+template< class P >
+void cpPlugins::Interface::PolyLineParametricPath::
+SetITK( itk::Object* object )
+{
+ P* path = dynamic_cast< P* >( object );
+ if( path != NULL )
+ {
+ this->m_ITKObject = path;
+ this->m_VTKObject = NULL;
+ this->Modified( );
+
+ } // fi
+}
+
+#endif // __CPPLUGINS__INTERFACE__POLYLINEPARAMETRICPATH__HXX__
+
+// eof - $RCSfile$
Self& cpPlugins::Interface::InputProcessObjectPort::
operator=( const Superclass& other )
{
- auto i = dynamic_cast< const InputProcessObjectPort* >( &other );
this->Superclass::operator=( other );
+ auto i = dynamic_cast< const InputProcessObjectPort* >( &other );
if( i != NULL )
this->m_Required = i->m_Required;
return( *this );
--- /dev/null
+#include "CPRFilter.h"
+#include <cpPlugins/Interface/Image.h>
+#include <cpPlugins/Interface/PolyLineParametricPath.h>
+#include <cpExtensions/Algorithms/CPRFilter.h>
+#include <itkInterpolateImageFunction.h>
+
+// -------------------------------------------------------------------------
+cpPlugins::BasicFilters::CPRFilter::
+CPRFilter( )
+ : Superclass( )
+{
+ this->_AddInput( "InputImage", true );
+ this->_AddInput( "InputAxis", true );
+ this->_AddInput( "Interpolator", false );
+ this->_AddOutput< cpPlugins::Interface::Image >( "Output" );
+
+ this->m_Parameters->ConfigureAsUint( "NumberOfSlices" );
+ this->m_Parameters->ConfigureAsReal( "SliceRadius" );
+ std::vector< std::string > choices;
+ choices.push_back( "float" );
+ choices.push_back( "double" );
+ this->m_Parameters->ConfigureAsChoices( "ScalarType", choices );
+
+ this->m_Parameters->SetUint( "NumberOfSlices", 0 );
+ this->m_Parameters->SetReal( "SliceRadius", 10 );
+ this->m_Parameters->SetSelectedChoice( "ScalarType", "float" );
+}
+
+// -------------------------------------------------------------------------
+cpPlugins::BasicFilters::CPRFilter::
+~CPRFilter( )
+{
+}
+
+// -------------------------------------------------------------------------
+std::string cpPlugins::BasicFilters::CPRFilter::
+_GenerateData( )
+{
+ auto image =
+ this->GetInputData< cpPlugins::Interface::Image >( "InputImage" );
+ if( image == NULL )
+ return( "CPRFilter: No input image." );
+
+ itk::DataObject* itk_image = NULL;
+ std::string r = "";
+ cpPlugins_Image_Demangle_AllScalarTypes( 3, image, itk_image, r, _GD0 );
+ else r = "CPRFilter: Input image type not supported.";
+ return( r );
+}
+
+// -------------------------------------------------------------------------
+template< class I >
+std::string cpPlugins::BasicFilters::CPRFilter::
+_GD0( itk::DataObject* dobj )
+{
+ I* image = dynamic_cast< I* >( dobj );
+
+ auto choice = this->m_Parameters->GetSelectedChoice( "ScalarType" );
+ if( choice == "float" )
+ return( this->_GD1< I, float >( image ) );
+ else if( choice == "double" )
+ return( this->_GD1< I, double >( image ) );
+ else
+ return( "CPRFilter: Scalar type not supported." );
+}
+
+// -------------------------------------------------------------------------
+template< class I, class S >
+std::string cpPlugins::BasicFilters::CPRFilter::
+_GD1( I* image )
+{
+ typedef cpExtensions::Algorithms::CPRFilter< I, S > _Filter;
+ typedef itk::PolyLineParametricPath< I::ImageDimension > _Path;
+ typedef itk::InterpolateImageFunction< I, S > _Interpolator;
+
+ auto axis =
+ this->GetInputData< cpPlugins::Interface::PolyLineParametricPath >(
+ "InputAxis"
+ )->GetITK< _Path >( );
+ auto w_int =
+ this->GetInputData< cpPlugins::Interface::DataObject >( "Interpolator" );
+ _Interpolator* interpolator = NULL;
+ if( w_int != NULL )
+ interpolator = w_int->GetITK< _Interpolator >( );
+
+ // Configure filter
+ _Filter* filter = this->_CreateITK< _Filter >( );
+ filter->SetInput( image );
+ filter->SetAxis( axis );
+ if( interpolator != NULL )
+ filter->SetInterpolator( interpolator );
+ filter->SetNumberOfSlices( this->m_Parameters->GetUint( "NumberOfSlices" ) );
+ filter->SetSliceRadius( this->m_Parameters->GetReal( "SliceRadius" ) );
+ filter->Update( );
+
+ // Assign output
+ auto out =
+ this->GetOutputData< cpPlugins::Interface::Image >( "Output" );
+ out->SetITK< I >( filter->GetOutput( ) );
+ return( "" );
+}
+
+// eof - $RCSfile$
--- /dev/null
+#ifndef __CPPLUGINS__PLUGINS__CPRFILTER__H__
+#define __CPPLUGINS__PLUGINS__CPRFILTER__H__
+
+#include <cpPlugins/BasicFilters/cpPluginsBasicFilters_Export.h>
+#include <cpPlugins/Interface/BaseProcessObjects.h>
+
+namespace cpPlugins
+{
+ namespace BasicFilters
+ {
+ /**
+ */
+ class cpPluginsBasicFilters_EXPORT CPRFilter
+ : public cpPlugins::Interface::ImageToImageFilter
+ {
+ public:
+ typedef CPRFilter Self;
+ typedef cpPlugins::Interface::ImageToImageFilter Superclass;
+ typedef itk::SmartPointer< Self > Pointer;
+ typedef itk::SmartPointer< const Self > ConstPointer;
+
+ public:
+ itkNewMacro( Self );
+ itkTypeMacro(
+ CPRFilter,
+ cpPluginsInterfaceImageToImageFilter
+ );
+ cpPlugins_Id_Macro(
+ cpPlugins::BasicFilters::CPRFilter,
+ ImageToImageFilter
+ );
+
+ protected:
+ CPRFilter( );
+ virtual ~CPRFilter( );
+
+ virtual std::string _GenerateData( );
+
+ template< class I >
+ inline std::string _GD0( itk::DataObject* dobj );
+
+ template< class I, class S >
+ inline std::string _GD1( I* image );
+
+ private:
+ // Purposely not implemented
+ CPRFilter( const Self& );
+ Self& operator=( const Self& );
+ };
+
+ } // ecapseman
+
+} // ecapseman
+
+#endif // __CPPLUGINS__PLUGINS__CPRFILTER__H__
+
+// eof - $RCSfile$
--- /dev/null
+#include "ImageInterpolatorSource.h"
+
+#include <cpPlugins/Interface/Image.h>
+#include <itkLinearInterpolateImageFunction.h>
+#include <itkNearestNeighborInterpolateImageFunction.h>
+
+// -------------------------------------------------------------------------
+cpPlugins::BasicFilters::ImageInterpolatorSource::
+ImageInterpolatorSource( )
+ : Superclass( )
+{
+ this->_AddInput( "ReferenceImage", true );
+ this->_AddOutput< cpPlugins::Interface::DataObject >( "Output" );
+
+ std::vector< std::string > type_choices;
+ type_choices.push_back( "Linear" );
+ type_choices.push_back( "NearestNeighbor" );
+ this->m_Parameters->ConfigureAsChoices( "InterpolationType", type_choices );
+ this->m_Parameters->SetSelectedChoice( "InterpolationType", "Linear" );
+
+ std::vector< std::string > scalar_choices;
+ scalar_choices.push_back( "float" );
+ scalar_choices.push_back( "double" );
+ this->m_Parameters->ConfigureAsChoices( "ScalarType", scalar_choices );
+ this->m_Parameters->SetSelectedChoice( "ScalarType", "float" );
+}
+
+// -------------------------------------------------------------------------
+cpPlugins::BasicFilters::ImageInterpolatorSource::
+~ImageInterpolatorSource( )
+{
+}
+
+// -------------------------------------------------------------------------
+std::string cpPlugins::BasicFilters::ImageInterpolatorSource::
+_GenerateData( )
+{
+ auto image =
+ this->GetInputData< cpPlugins::Interface::Image >( "ReferenceImage" );
+ if( image == NULL )
+ return( "ImageInterpolatorSource: No input image." );
+
+ itk::DataObject* itk_image = NULL;
+ std::string r = "";
+ cpPlugins_Image_Demangle_AllScalarTypes( 2, image, itk_image, r, _GD0 );
+ else cpPlugins_Image_Demangle_AllScalarTypes( 3, image, itk_image, r, _GD0 );
+ else cpPlugins_Image_Demangle_AllScalarTypes( 4, image, itk_image, r, _GD0 );
+ else r = "ImageInterpolatorSource: Input image type not supported.";
+ return( r );
+}
+
+// -------------------------------------------------------------------------
+template< class I >
+std::string cpPlugins::BasicFilters::ImageInterpolatorSource::
+_GD0( itk::DataObject* dobj )
+{
+ std::string int_choice =
+ this->m_Parameters->GetSelectedChoice( "InterpolationType" );
+ std::string scalar_choice =
+ this->m_Parameters->GetSelectedChoice( "ScalarType" );
+
+ if( int_choice == "Linear" )
+ {
+ if( scalar_choice == "float" )
+ return(
+ this->_GD1< itk::LinearInterpolateImageFunction< I, float > >( )
+ );
+ else if( scalar_choice == "double" )
+ return(
+ this->_GD1< itk::LinearInterpolateImageFunction< I, double > >( )
+ );
+ else
+ return( "ImageInterpolatorSource: Invalid scalar type" );
+ }
+ else if( int_choice == "NearestNeighbor" )
+ {
+ if( scalar_choice == "float" )
+ return(
+ this->_GD1< itk::NearestNeighborInterpolateImageFunction< I, float > >( )
+ );
+ else if( scalar_choice == "double" )
+ return(
+ this->_GD1< itk::NearestNeighborInterpolateImageFunction< I, double > >( )
+ );
+ else
+ return( "ImageInterpolatorSource: Invalid scalar type" );
+ }
+ else
+ return( "ImageInterpolatorSource: Invalid interpolator" );
+}
+
+// -------------------------------------------------------------------------
+template< class T >
+std::string cpPlugins::BasicFilters::ImageInterpolatorSource::
+_GD1( )
+{
+ auto out =
+ this->GetOutputData< cpPlugins::Interface::DataObject >( "Output" );
+ if( out->GetITK< T >( ) == NULL )
+ {
+ typename T::Pointer res = T::New( );
+ out->SetITK( res.GetPointer( ) );
+
+ } // fi
+ return( "" );
+}
+
+// eof - $RCSfile$
--- /dev/null
+#ifndef __CPPLUGINS__PLUGINS__IMAGEINTERPOLATORSOURCE__H__
+#define __CPPLUGINS__PLUGINS__IMAGEINTERPOLATORSOURCE__H__
+
+#include <cpPlugins/BasicFilters/cpPluginsBasicFilters_Export.h>
+#include <cpPlugins/Interface/BaseProcessObjects.h>
+
+namespace cpPlugins
+{
+ namespace BasicFilters
+ {
+ /**
+ */
+ class cpPluginsBasicFilters_EXPORT ImageInterpolatorSource
+ : public cpPlugins::Interface::ProcessObject
+ {
+ public:
+ typedef ImageInterpolatorSource Self;
+ typedef cpPlugins::Interface::ProcessObject Superclass;
+ typedef itk::SmartPointer< Self > Pointer;
+ typedef itk::SmartPointer< const Self > ConstPointer;
+
+ public:
+ itkNewMacro( Self );
+ itkTypeMacro(
+ ImageInterpolatorSource, cpPlugins::Interface::ProcessObject
+ );
+ cpPlugins_Id_Macro(
+ cpPlugins::BasicFilters::ImageInterpolatorSource,
+ FunctionSource
+ );
+
+ protected:
+ ImageInterpolatorSource( );
+ virtual ~ImageInterpolatorSource( );
+
+ virtual std::string _GenerateData( );
+
+ template< class I >
+ inline std::string _GD0( itk::DataObject* dobj );
+
+ template< class T >
+ inline std::string _GD1( );
+
+ private:
+ // Purposely not implemented
+ ImageInterpolatorSource( const Self& );
+ Self& operator=( const Self& );
+ };
+
+ } // ecapseman
+
+} // ecapseman
+
+#endif // __CPPLUGINS__PLUGINS__IMAGEINTERPOLATORSOURCE__H__
+
+// eof - $RCSfile$