From 09046275d77a6f1bb9e6a309f22f9510fba13550 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Leonardo=20Fl=C3=B3rez-Valencia?= Date: Wed, 19 Jul 2017 16:28:40 -0500 Subject: [PATCH] ... --- lib/fpa/Image/Dijkstra.h | 17 +- lib/fpa/Image/Dijkstra.hxx | 60 +++++++ lib/fpa/Image/ExtractAxisFilter.h | 93 +++++++++++ lib/fpa/Image/ExtractAxisFilter.hxx | 151 ++++++++++++++++++ .../PolyLineParametricPathToPolyDataFilter.h | 81 ++++++++++ ...PolyLineParametricPathToPolyDataFilter.hxx | 145 +++++++++++++++++ 6 files changed, 545 insertions(+), 2 deletions(-) create mode 100644 lib/fpa/Image/Dijkstra.hxx create mode 100644 lib/fpa/Image/ExtractAxisFilter.h create mode 100644 lib/fpa/Image/ExtractAxisFilter.hxx create mode 100644 lib/fpa/Image/PolyLineParametricPathToPolyDataFilter.h create mode 100644 lib/fpa/Image/PolyLineParametricPathToPolyDataFilter.hxx diff --git a/lib/fpa/Image/Dijkstra.h b/lib/fpa/Image/Dijkstra.h index d755ebf..24c0643 100644 --- a/lib/fpa/Image/Dijkstra.h +++ b/lib/fpa/Image/Dijkstra.h @@ -10,6 +10,7 @@ #include #include #include +#include namespace fpa { @@ -34,13 +35,21 @@ namespace fpa typedef itk::SmartPointer< Self > Pointer; typedef itk::SmartPointer< const Self > ConstPointer; + typedef typename Superclass::TOutputValue TOutputValue; + typedef typename Superclass::TVertex TVertex; + + typedef fpa::Image::Functors::Dijkstra::Function< TInputImage, TOutputValue > TWeightFunction; + public: itkNewMacro( Self ); itkTypeMacro( fpa::Image::Dijkstra, fpa::Base::Dijkstra ); protected: - Dijkstra( ) : Superclass( ) { } - virtual ~Dijkstra( ) { } + Dijkstra( ); + virtual ~Dijkstra( ); + + virtual void _BeforeGenerateData( ) override; + virtual void _ConfigureOutput( const TOutputValue& v ) override; private: // Purposely not implemented. @@ -52,6 +61,10 @@ namespace fpa } // ecapseman +#ifndef ITK_MANUAL_INSTANTIATION +# include +#endif // ITK_MANUAL_INSTANTIATION + #endif // __fpa__Image__Dijkstra__h__ // eof - $RCSfile$ diff --git a/lib/fpa/Image/Dijkstra.hxx b/lib/fpa/Image/Dijkstra.hxx new file mode 100644 index 0000000..b0780de --- /dev/null +++ b/lib/fpa/Image/Dijkstra.hxx @@ -0,0 +1,60 @@ +// ========================================================================= +// @author Leonardo Florez Valencia +// @email florez-l@javeriana.edu.co +// ========================================================================= + +#ifndef __fpa__Image__Dijkstra__hxx__ +#define __fpa__Image__Dijkstra__hxx__ + +// ------------------------------------------------------------------------- +template< class _TInputImage, class _TOutputImage, class _TFrontId > +fpa::Image::Dijkstra< _TInputImage, _TOutputImage, _TFrontId >:: +Dijkstra( ) + : Superclass( ) +{ +} + +// ------------------------------------------------------------------------- +template< class _TInputImage, class _TOutputImage, class _TFrontId > +fpa::Image::Dijkstra< _TInputImage, _TOutputImage, _TFrontId >:: +~Dijkstra( ) +{ +} + +// ------------------------------------------------------------------------- +template< class _TInputImage, class _TOutputImage, class _TFrontId > +void fpa::Image::Dijkstra< _TInputImage, _TOutputImage, _TFrontId >:: +_BeforeGenerateData( ) +{ + this->Superclass::_BeforeGenerateData( ); + TWeightFunction* wf = + dynamic_cast< TWeightFunction* >( this->GetWeightFunction( ) ); + if( wf != NULL ) + wf->SetImage( this->GetInput( ) ); +} + +// ------------------------------------------------------------------------- +template< class _TInputImage, class _TOutputImage, class _TFrontId > +void fpa::Image::Dijkstra< _TInputImage, _TOutputImage, _TFrontId >:: +_ConfigureOutput( const TOutputValue& v ) +{ + this->Superclass::_ConfigureOutput( v ); + + const TInputImage* in = this->GetInput( ); + TMST* mst = this->GetMinimumSpanningTree( ); + mst->SetLargestPossibleRegion( in->GetLargestPossibleRegion( ) ); + mst->SetRequestedRegion( in->GetRequestedRegion( ) ); + mst->SetBufferedRegion( in->GetBufferedRegion( ) ); + mst->SetSpacing( in->GetSpacing( ) ); + mst->SetOrigin( in->GetOrigin( ) ); + mst->SetDirection( in->GetDirection( ) ); + mst->Allocate( ); + + typename TVertex::OffsetType o; + o.Fill( 0 ); + mst->FillBuffer( o ); +} + +#endif // __fpa__Image__Dijkstra__hxx__ + +// eof - $RCSfile$ diff --git a/lib/fpa/Image/ExtractAxisFilter.h b/lib/fpa/Image/ExtractAxisFilter.h new file mode 100644 index 0000000..25eee47 --- /dev/null +++ b/lib/fpa/Image/ExtractAxisFilter.h @@ -0,0 +1,93 @@ +// ========================================================================= +// @author Leonardo Florez Valencia +// @email florez-l@javeriana.edu.co +// ========================================================================= + +#ifndef __fpa__Image__ExtractAxisFilter__h__ +#define __fpa__Image__ExtractAxisFilter__h__ + +#include +#include + +#include +#include + +namespace fpa +{ + namespace Image + { + /** + */ + template< class _TInputImage, class _TScalar, class _TCenterness = itk::SignedMaurerDistanceMapImageFilter< _TInputImage, itk::Image< _TScalar, _TInputImage::ImageDimension > > > + class ExtractAxisFilter + : public itk::ProcessObject + { + public: + typedef ExtractAxisFilter Self; + typedef itk::ProcessObject Superclass; + typedef itk::SmartPointer< Self > Pointer; + typedef itk::SmartPointer< const Self > ConstPointer; + + typedef _TInputImage TInputImage; + typedef _TScalar TScalar; + typedef _TCenterness TCenterness; + itkStaticConstMacro( + Dimension, + unsigned int, + TInputImage::ImageDimension + ); + + typedef typename TCenterness::OutputImageType TOutputImage; + typedef typename TInputImage::IndexType TIndex; + + typedef fpa::Image::PolyLineParametricPath< Self::Dimension > TPath; + typedef fpa::Image::Dijkstra< TOutputImage, TOutputImage > TDijkstra; + + public: + itkNewMacro( Self ); + itkTypeMacro( fpa::Image::ExtractAxisFilter, fpa::Image::Dijkstra ); + + itkGetConstObjectMacro( Centerness, TCenterness ); + itkGetObjectMacro( Centerness, TCenterness ); + + public: + virtual itk::ModifiedTimeType GetMTime( ) const override; + + virtual void AddSeed( const TVertex& seed ); + virtual void AddSeed( const TPoint& seed ); + virtual void ClearSeeds( ); + + void SetInput( TInputImage* input ); + TInputImage* GetInput( ); + const TInputImage* GetInput( ) const; + + TPath* GetOutput( ); + const TPath* GetOutput( ) const; + + protected: + ExtractAxisFilter( ); + virtual ~ExtractAxisFilter( ); + + virtual void GenerateData( ) override; + + private: + // Purposely not implemented. + ExtractAxisFilter( const Self& other ); + Self& operator=( const Self& other ); + + protected: + typename TCenterness::Pointer m_Centerness; + typename TDijkstra::Pointer m_Dijkstra; + }; + + } // ecapseman + +} // ecapseman + +#ifndef ITK_MANUAL_INSTANTIATION +# include +#endif // ITK_MANUAL_INSTANTIATION + +#endif // __fpa__Image__ExtractAxisFilter__h__ + +// eof - $RCSfile$ diff --git a/lib/fpa/Image/ExtractAxisFilter.hxx b/lib/fpa/Image/ExtractAxisFilter.hxx new file mode 100644 index 0000000..6f91ade --- /dev/null +++ b/lib/fpa/Image/ExtractAxisFilter.hxx @@ -0,0 +1,151 @@ +// ========================================================================= +// @author Leonardo Florez Valencia +// @email florez-l@javeriana.edu.co +// ========================================================================= + +#ifndef __fpa__Image__ExtractAxisFilter__hxx__ +#define __fpa__Image__ExtractAxisFilter__hxx__ + +#include + +// ------------------------------------------------------------------------- +template< class _TInputImage, class _TScalar, class _TCenterness > +itk::ModifiedTimeType +fpa::Image::ExtractAxisFilter< _TInputImage, _TScalar, _TCenterness >:: +GetMTime( ) const +{ + itk::ModifiedTimeType a = this->Superclass::GetMTime( ); + itk::ModifiedTimeType b = this->m_Centerness->GetMTime( ); + itk::ModifiedTimeType c = this->m_Dijsktra->GetMTime( ); + a = ( a < b )? a: b; + return( ( a < c )? a: c ); +} + +// ------------------------------------------------------------------------- +template< class _TInputImage, class _TScalar, class _TCenterness > +void fpa::Image::ExtractAxisFilter< _TInputImage, _TScalar, _TCenterness >:: +AddSeed( const TVertex& seed ) +{ + this->m_Dijkstra->AddSeed( seed ); +} + +// ------------------------------------------------------------------------- +template< class _TInputImage, class _TScalar, class _TCenterness > +void fpa::Image::ExtractAxisFilter< _TInputImage, _TScalar, _TCenterness >:: +AddSeed( const TPoint& seed ) +{ + this->m_Dijkstra->AddSeed( seed ); +} + +// ------------------------------------------------------------------------- +template< class _TInputImage, class _TScalar, class _TCenterness > +void fpa::Image::ExtractAxisFilter< _TInputImage, _TScalar, _TCenterness >:: +ClearSeeds( ) +{ + this->m_Dijkstra->ClearSeeds( ); +} + +// ------------------------------------------------------------------------- +template< class _TInputImage, class _TScalar, class _TCenterness > +void fpa::Image::ExtractAxisFilter< _TInputImage, _TScalar, _TCenterness >:: +SetInput( TInputImage* input ) +{ + this->Superclass::SetNthInput( 0, input ); +} + +// ------------------------------------------------------------------------- +template< class _TInputImage, class _TScalar, class _TCenterness > +typename +fpa::Image::ExtractAxisFilter< _TInputImage, _TScalar, _TCenterness >:: +TInputImage* +fpa::Image::ExtractAxisFilter< _TInputImage, _TScalar, _TCenterness >:: +GetInput( ) +{ + return( dynamic_cast< TInputImage* >( this->Superclass::GetInput( 0 ) ) ); +} + +// ------------------------------------------------------------------------- +template< class _TInputImage, class _TScalar, class _TCenterness > +const typename +fpa::Image::ExtractAxisFilter< _TInputImage, _TScalar, _TCenterness >:: +TInputImage* +fpa::Image::ExtractAxisFilter< _TInputImage, _TScalar, _TCenterness >:: +GetInput( ) const +{ + return( + dynamic_cast< const TInputImage* >( this->Superclass::GetInput( 0 ) ) + ); +} + +// ------------------------------------------------------------------------- +template< class _TInputImage, class _TScalar, class _TCenterness > +typename +fpa::Image::ExtractAxisFilter< _TInputImage, _TScalar, _TCenterness >:: +TPath* +fpa::Image::ExtractAxisFilter< _TInputImage, _TScalar, _TCenterness >:: +GetOutput( ) +{ + return( dynamic_cast< TPath* >( this->Superclass::GetOutput( 0 ) ) ); +} + +// ------------------------------------------------------------------------- +template< class _TInputImage, class _TScalar, class _TCenterness > +const typename +fpa::Image::ExtractAxisFilter< _TInputImage, _TScalar, _TCenterness >:: +TPath* +fpa::Image::ExtractAxisFilter< _TInputImage, _TScalar, _TCenterness >:: +GetOutput( ) const +{ + return( dynamic_cast< const TPath* >( this->Superclass::GetOutput( 0 ) ) ); +} + +// ------------------------------------------------------------------------- +template< class _TInputImage, class _TScalar, class _TCenterness > +fpa::Image::ExtractAxisFilter< _TInputImage, _TScalar, _TCenterness >:: +ExtractAxisFilter( ) + : Superclass( ) +{ + // I/O configuration + this->SetNumberOfRequiredInputs( 1 ); + this->SetNumberOfRequiredOutputs( 1 ); + this->SetNthOutput( 0, TPath::New( ) ); + + // Prepare weight function + typedef fpa::Image::Functors::Dijkstra::Invert< TOutputImage, TScalar > _TWeight; + typename _TWeight::Pointer weight = _TWeight::New( ); + weight->SetAlpha( 1 ); + weight->SetBeta( 1 ); + + // Filters + this->m_Centerness = TCenterness::New( ); + this->m_Dijkstra = TDijkstra::New( ); + this->m_Dijkstra->SetWeightFunction( weight ); + this->m_Dijkstra->StopAtOneFront( ); +} + +// ------------------------------------------------------------------------- +template< class _TInputImage, class _TScalar, class _TCenterness > +fpa::Image::ExtractAxisFilter< _TInputImage, _TScalar, _TCenterness >:: +~ExtractAxisFilter( ) +{ +} + +// ------------------------------------------------------------------------- +template< class _TInputImage, class _TScalar, class _TCenterness > +void fpa::Image::ExtractAxisFilter< _TInputImage, _TScalar, _TCenterness >:: +GenerateData( ) +{ + // Execute minipipeline + this->m_Centerness->SetInput( this->GetInput( ) ); + this->m_Dijkstra->SetInput( this->m_Centerness->GetOutput( ) ); + this->m_Dijkstra->Update( ); + + // Extract axis + typename TInputImage::IndexType a = this->m_Dijkstra->GetSeeds( )[ 0 ]; + typename TInputImage::IndexType b = this->m_Dijkstra->GetSeeds( )[ 1 ]; + this->m_Dijkstra->GetMinimumSpanningTree( )->GetPolyLineParametricPath( this->GetOutput( ), a, b ); +} + +#endif // __fpa__Image__ExtractAxisFilter__hxx__ + +// eof - $RCSfile$ diff --git a/lib/fpa/Image/PolyLineParametricPathToPolyDataFilter.h b/lib/fpa/Image/PolyLineParametricPathToPolyDataFilter.h new file mode 100644 index 0000000..4c6318a --- /dev/null +++ b/lib/fpa/Image/PolyLineParametricPathToPolyDataFilter.h @@ -0,0 +1,81 @@ +// ========================================================================= +// @author Leonardo Florez Valencia +// @email florez-l@javeriana.edu.co +// ========================================================================= + +#ifndef __fpa__Image__PolyLineParametricPathToPolyDataFilter__h__ +#define __fpa__Image__PolyLineParametricPathToPolyDataFilter__h__ + +#include + +#ifdef USE_VTK +# include +#endif // USE_VTK + +namespace fpa +{ + namespace Image + { + /** + */ + template< class _TPolyLineParametricPath > + class PolyLineParametricPathToPolyDataFilter +#ifdef USE_VTK + : public vtkPolyDataAlgorithm +#endif // USE_VTK + { + public: + typedef PolyLineParametricPathToPolyDataFilter Self; + typedef _TPolyLineParametricPath TPolyLineParametricPath; + + public: +#ifdef USE_VTK + vtkTypeMacro( + PolyLineParametricPathToPolyDataFilter, + vtkPolyDataAlgorithm + ); +#endif // USE_VTK + + public: + static Self* New( ); + + const TPolyLineParametricPath* GetInput( ) const; + void SetInput( const TPolyLineParametricPath* path ); + + protected: + PolyLineParametricPathToPolyDataFilter( ); + virtual ~PolyLineParametricPathToPolyDataFilter( ); + +#ifdef USE_VTK + int RequestData( + vtkInformation* information, + vtkInformationVector** input, + vtkInformationVector* output + ); + int RequestInformation( + vtkInformation* information, + vtkInformationVector** input, + vtkInformationVector* output + ); +#endif // USE_VTK + + private: + // Purposely not implemented + PolyLineParametricPathToPolyDataFilter( const Self& ); + void operator=( const Self& ); + + protected: + const TPolyLineParametricPath* m_PolyLineParametricPath; + }; + + } // ecapseman + +} // ecapseman + +#ifndef ITK_MANUAL_INSTANTIATION +# include +#endif // ITK_MANUAL_INSTANTIATION + +#endif // __fpa__Image__PolyLineParametricPathToPolyDataFilter__h__ + +// eof - $RCSfile$ diff --git a/lib/fpa/Image/PolyLineParametricPathToPolyDataFilter.hxx b/lib/fpa/Image/PolyLineParametricPathToPolyDataFilter.hxx new file mode 100644 index 0000000..7dd4cb1 --- /dev/null +++ b/lib/fpa/Image/PolyLineParametricPathToPolyDataFilter.hxx @@ -0,0 +1,145 @@ +// ========================================================================= +// @author Leonardo Florez Valencia +// @email florez-l@javeriana.edu.co +// ========================================================================= + +#ifndef __fpa__Image__PolyLineParametricPathToPolyDataFilter__hxx__ +#define __fpa__Image__PolyLineParametricPathToPolyDataFilter__hxx__ + +#ifdef USE_VTK +# include +# include +# include +# include +# include +# include +#endif // USE_VTK + +// ------------------------------------------------------------------------- +template< class _TPolyLineParametricPath > +typename fpa::Image::PolyLineParametricPathToPolyDataFilter< _TPolyLineParametricPath >:: +Self* fpa::Image::PolyLineParametricPathToPolyDataFilter< _TPolyLineParametricPath >:: +New( ) +{ + return( new Self( ) ); +} + +// ------------------------------------------------------------------------- +template< class _TPolyLineParametricPath > +const typename +fpa::Image::PolyLineParametricPathToPolyDataFilter< _TPolyLineParametricPath >:: +TPolyLineParametricPath* fpa::Image::PolyLineParametricPathToPolyDataFilter< _TPolyLineParametricPath >:: +GetInput( ) const +{ + return( this->m_PolyLineParametricPath ); +} + +// ------------------------------------------------------------------------- +template< class _TPolyLineParametricPath > +void fpa::Image::PolyLineParametricPathToPolyDataFilter< _TPolyLineParametricPath >:: +SetInput( const TPolyLineParametricPath* path ) +{ + if( this->m_PolyLineParametricPath != path ) + { + this->m_PolyLineParametricPath = path; +#ifdef USE_VTK + this->Modified( ); +#endif // USE_VTK + + } // fi +} + +// ------------------------------------------------------------------------- +template< class _TPolyLineParametricPath > +fpa::Image::PolyLineParametricPathToPolyDataFilter< _TPolyLineParametricPath >:: +PolyLineParametricPathToPolyDataFilter( ) +#ifdef USE_VTK + : vtkPolyDataAlgorithm( ), + m_PolyLineParametricPath( NULL ) +#endif // USE_VTK +{ +#ifdef USE_VTK + this->SetNumberOfInputPorts( 0 ); +#endif // USE_VTK +} + +// ------------------------------------------------------------------------- +template< class _TPolyLineParametricPath > +fpa::Image::PolyLineParametricPathToPolyDataFilter< _TPolyLineParametricPath >:: +~PolyLineParametricPathToPolyDataFilter( ) +{ +} + +#ifdef USE_VTK +// ------------------------------------------------------------------------- +template< class _TPolyLineParametricPath > +int fpa::Image::PolyLineParametricPathToPolyDataFilter< _TPolyLineParametricPath >:: +RequestData( + vtkInformation* information, + vtkInformationVector** input, + vtkInformationVector* output + ) +{ + static const unsigned int dim = TPolyLineParametricPath::PathDimension; + if( this->m_PolyLineParametricPath == NULL ) + return( 0 ); + + // Get output + vtkInformation* info = output->GetInformationObject( 0 ); + vtkPolyData* out = vtkPolyData::SafeDownCast( + info->Get( vtkDataObject::DATA_OBJECT( ) ) + ); + + // Prepare data + out->SetPoints( vtkSmartPointer< vtkPoints >::New( ) ); + out->SetVerts( vtkSmartPointer< vtkCellArray >::New( ) ); + out->SetLines( vtkSmartPointer< vtkCellArray >::New( ) ); + out->SetPolys( vtkSmartPointer< vtkCellArray >::New( ) ); + out->SetStrips( vtkSmartPointer< vtkCellArray >::New( ) ); + vtkSmartPointer< vtkUnsignedIntArray > darray = + vtkSmartPointer< vtkUnsignedIntArray >::New( ); + darray->SetNumberOfComponents( 1 ); + out->GetPointData( )->SetScalars( darray ); + vtkPoints* points = out->GetPoints( ); + vtkCellArray* lines = out->GetLines( ); + + // Assign all data + const TPolyLineParametricPath* path = this->GetInput( ); + for( unsigned long i = 0; i < path->GetSize( ); ++i ) + { + auto pnt = path->GetPoint( i ); + if( dim == 1 ) + points->InsertNextPoint( pnt[ 0 ], 0, 0 ); + else if( dim == 2 ) + points->InsertNextPoint( pnt[ 0 ], pnt[ 1 ], 0 ); + else + points->InsertNextPoint( pnt[ 0 ], pnt[ 1 ], pnt[ 2 ] ); + darray->InsertNextTuple1( double( i ) ); + if( i > 0 ) + { + lines->InsertNextCell( 2 ); + lines->InsertCellPoint( points->GetNumberOfPoints( ) - 2 ); + lines->InsertCellPoint( points->GetNumberOfPoints( ) - 1 ); + + } // fi + + } // rof + return( 1 ); +} + +// ------------------------------------------------------------------------- +template< class _TPolyLineParametricPath > +int fpa::Image::PolyLineParametricPathToPolyDataFilter< _TPolyLineParametricPath >:: +RequestInformation( + vtkInformation* information, + vtkInformationVector** input, + vtkInformationVector* output + ) +{ + return( 1 ); +} +#endif // USE_VTK + +#endif // __fpa__Image__PolyLineParametricPathToPolyDataFilterFilter__hxx__ + +// eof - $RCSfile$ -- 2.47.1