From 855f9954a822d2739efac96c38356d0aa788c982 Mon Sep 17 00:00:00 2001 From: Leonardo Florez-Valencia Date: Thu, 21 Jan 2016 18:47:57 -0500 Subject: [PATCH] ... --- lib/fpa/Base/Algorithm.h | 4 +- lib/fpa/Base/MinimumSpanningTree.h | 26 ++-- lib/fpa/Base/MinimumSpanningTree.hxx | 82 ++++++----- .../Image/DijkstraWithEndPointDetection.hxx | 9 +- lib/fpa/VTK/Image2DObserver.h | 2 +- lib/fpaPlugins/BaseImageFilter.cxx | 16 +++ lib/fpaPlugins/BaseImageFilter.h | 128 +++++++++++++++++ lib/fpaPlugins/CMakeLists.txt | 7 + lib/fpaPlugins/ImageDijkstra.cxx | 53 ++----- lib/fpaPlugins/ImageDijkstra.h | 17 +-- lib/fpaPlugins/ImageRegionGrow.cxx | 37 +---- lib/fpaPlugins/ImageRegionGrow.h | 17 +-- lib/fpaPlugins/MinimumSpanningTree.cxx | 16 +++ lib/fpaPlugins/MinimumSpanningTree.h | 47 +++++++ lib/fpaPlugins/MinimumSpanningTree.hxx | 21 +++ lib/fpaPlugins/MinimumSpanningTreeToMesh.cxx | 133 ++++++++++++++++++ lib/fpaPlugins/MinimumSpanningTreeToMesh.h | 51 +++++++ 17 files changed, 512 insertions(+), 154 deletions(-) create mode 100644 lib/fpaPlugins/BaseImageFilter.cxx create mode 100644 lib/fpaPlugins/BaseImageFilter.h create mode 100644 lib/fpaPlugins/MinimumSpanningTree.cxx create mode 100644 lib/fpaPlugins/MinimumSpanningTree.h create mode 100644 lib/fpaPlugins/MinimumSpanningTree.hxx create mode 100644 lib/fpaPlugins/MinimumSpanningTreeToMesh.cxx create mode 100644 lib/fpaPlugins/MinimumSpanningTreeToMesh.h diff --git a/lib/fpa/Base/Algorithm.h b/lib/fpa/Base/Algorithm.h index 62973da..246a5e3 100644 --- a/lib/fpa/Base/Algorithm.h +++ b/lib/fpa/Base/Algorithm.h @@ -85,9 +85,7 @@ namespace fpa typedef std::map< TVertex, _TNode, TVertexCompare > _TNodes; public: - typedef - fpa::Base::MinimumSpanningTree< V, _TCollisions, VC > - TMinimumSpanningTree; + typedef fpa::Base::MinimumSpanningTree< V, VC > TMinimumSpanningTree; public: itkTypeMacro( Algorithm, B ); diff --git a/lib/fpa/Base/MinimumSpanningTree.h b/lib/fpa/Base/MinimumSpanningTree.h index 4056267..0c2b720 100644 --- a/lib/fpa/Base/MinimumSpanningTree.h +++ b/lib/fpa/Base/MinimumSpanningTree.h @@ -13,21 +13,25 @@ namespace fpa { /** */ - template< class V, class C, class VC > + template< class V, class B > class MinimumSpanningTree - : public itk::SimpleDataObjectDecorator< std::map< V, std::pair< V, short >, VC > > + : public itk::SimpleDataObjectDecorator< std::map< V, std::pair< V, short >, B > > { public: typedef std::pair< V, short > TNodeInfo; - typedef std::map< V, TNodeInfo, VC > TDecorated; + typedef std::map< V, TNodeInfo, B > TDecorated; typedef MinimumSpanningTree Self; typedef itk::SimpleDataObjectDecorator< TDecorated > Superclass; typedef itk::SmartPointer< Self > Pointer; typedef itk::SmartPointer< const Self > ConstPointer; - typedef V TVertex; - typedef C TCollisions; - typedef VC TVertexCompare; + typedef V TVertex; + typedef B TVertexCompare; + + typedef std::vector< TVertex > TVertices; + typedef std::pair< TVertex, bool > TCollision; + typedef std::vector< TCollision > TCollisionsRow; + typedef std::vector< TCollisionsRow > TCollisions; protected: typedef std::vector< unsigned long > _TRow; @@ -52,13 +56,11 @@ namespace fpa this->m_Collisions.clear( ); this->m_FrontPaths.clear( ); } - virtual void GetPath( - std::vector< V >& path, const V& a, const V& b - ) const; + virtual std::vector< V > GetPath( const V& a, const V& b ) const; - template< class I, class P > - void GetPathFromImage( - std::vector< P >& path, const V& a, const V& b, + template< class I > + std::vector< typename I::PointType > GetPathFromImage( + const V& a, const V& b, const I* image, unsigned int kernel = 0 ) const; diff --git a/lib/fpa/Base/MinimumSpanningTree.hxx b/lib/fpa/Base/MinimumSpanningTree.hxx index ad0d06b..9d0939d 100644 --- a/lib/fpa/Base/MinimumSpanningTree.hxx +++ b/lib/fpa/Base/MinimumSpanningTree.hxx @@ -4,13 +4,13 @@ #include // ------------------------------------------------------------------------- -template< class V, class C, class B > -const unsigned long fpa::Base::MinimumSpanningTree< V, C, B >::INF_VALUE = +template< class V, class B > +const unsigned long fpa::Base::MinimumSpanningTree< V, B >::INF_VALUE = std::numeric_limits< unsigned long >::max( ) >> 1; // ------------------------------------------------------------------------- -template< class V, class C, class B > -void fpa::Base::MinimumSpanningTree< V, C, B >:: +template< class V, class B > +void fpa::Base::MinimumSpanningTree< V, B >:: SetCollisions( const TCollisions& collisions ) { this->m_Collisions = collisions; @@ -60,15 +60,16 @@ SetCollisions( const TCollisions& collisions ) } // ------------------------------------------------------------------------- -template< class V, class C, class B > -void fpa::Base::MinimumSpanningTree< V, C, B >:: -GetPath( std::vector< V >& path, const V& a, const V& b ) const +template< class V, class B > +std::vector< V > fpa::Base::MinimumSpanningTree< V, B >:: +GetPath( const V& a, const V& b ) const { + std::vector< V > path; typename TDecorated::const_iterator aIt = this->Get( ).find( a ); typename TDecorated::const_iterator bIt = this->Get( ).find( b ); if( aIt == this->Get( ).end( ) || bIt == this->Get( ).end( ) ) - return; + return( path ); short fa = aIt->second.second; short fb = bIt->second.second; @@ -121,49 +122,53 @@ GetPath( std::vector< V >& path, const V& a, const V& b ) const if( 0 < N ) { // First path: from start vertex to first collision - this->GetPath( - path, a, this->m_Collisions[ fpath[ 0 ] ][ fpath[ 1 ] ].first + path = this->GetPath( + a, this->m_Collisions[ fpath[ 0 ] ][ fpath[ 1 ] ].first ); // Intermediary paths for( unsigned int i = 1; i < N - 1; ++i ) { - this->GetPath( - path, - this->m_Collisions[ fpath[ i ] ][ fpath[ i - 1 ] ].first, - this->m_Collisions[ fpath[ i ] ][ fpath[ i + 1 ] ].first - ); + std::vector< V > ipath = + this->GetPath( + this->m_Collisions[ fpath[ i ] ][ fpath[ i - 1 ] ].first, + this->m_Collisions[ fpath[ i ] ][ fpath[ i + 1 ] ].first + ); + path.insert( path.end( ), ipath.begin( ), ipath.end( ) ); } // rof // Final path: from last collision to end point - this->GetPath( - path, - this->m_Collisions[ fpath[ N - 1 ] ][ fpath[ N - 2 ] ].first, b - ); + std::vector< V > lpath = + this->GetPath( + this->m_Collisions[ fpath[ N - 1 ] ][ fpath[ N - 2 ] ].first, b + ); + path.insert( path.end( ), lpath.begin( ), lpath.end( ) ); } // fi } // fi } // fi + return( path ); } // ------------------------------------------------------------------------- -template< class V, class C, class B > -template< class I, class P > -void fpa::Base::MinimumSpanningTree< V, C, B >:: +template< class V, class B > +template< class I > +std::vector< typename I::PointType > fpa::Base::MinimumSpanningTree< V, B >:: GetPathFromImage( - std::vector< P >& path, const V& a, const V& b, + const V& a, const V& b, const I* image, unsigned int kernel ) const { - std::vector< V > vertices; - this->GetPath( vertices, a, b ); - path.clear( ); + typedef typename I::PointType _P; + + std::vector< _P > path; + std::vector< V > vertices = this->GetPath( a, b ); for( unsigned int i = 0; i < vertices.size( ); ++i ) { - P p; + _P p; image->TransformIndexToPhysicalPoint( vertices[ i ], p ); path.push_back( p ); @@ -173,11 +178,11 @@ GetPathFromImage( if( kernel > 0 ) { int k = int( kernel ) >> 1; - std::vector< P > lowpass_path; + std::vector< _P > lowpass_path; for( unsigned int i = 0; i < path.size( ); ++i ) { - P p; - p.Fill( ( typename P::ValueType )( 0 ) ); + _P p; + p.Fill( ( typename _P::ValueType )( 0 ) ); unsigned int c = 0; for( int j = -k; j <= k; ++j ) { @@ -191,8 +196,8 @@ GetPathFromImage( } // rof if( c > 0 ) - for( unsigned int d = 0; d < P::PointDimension; ++d ) - p[ d ] /= ( typename P::ValueType )( c ); + for( unsigned int d = 0; d < _P::PointDimension; ++d ) + p[ d ] /= ( typename _P::ValueType )( c ); lowpass_path.push_back( p ); } // rof @@ -200,26 +205,27 @@ GetPathFromImage( path = lowpass_path; } // fi + return( path ); } // ------------------------------------------------------------------------- -template< class V, class C, class B > -fpa::Base::MinimumSpanningTree< V, C, B >:: +template< class V, class B > +fpa::Base::MinimumSpanningTree< V, B >:: MinimumSpanningTree( ) : Superclass( ) { } // ------------------------------------------------------------------------- -template< class V, class C, class B > -fpa::Base::MinimumSpanningTree< V, C, B >:: +template< class V, class B > +fpa::Base::MinimumSpanningTree< V, B >:: ~MinimumSpanningTree( ) { } // ------------------------------------------------------------------------- -template< class V, class C, class B > -void fpa::Base::MinimumSpanningTree< V, C, B >:: +template< class V, class B > +void fpa::Base::MinimumSpanningTree< V, B >:: _Path( std::vector< V >& path, const V& a ) const { typename TDecorated::const_iterator dIt = this->Get( ).find( a ); diff --git a/lib/fpa/Image/DijkstraWithEndPointDetection.hxx b/lib/fpa/Image/DijkstraWithEndPointDetection.hxx index cb417f0..85a9c46 100644 --- a/lib/fpa/Image/DijkstraWithEndPointDetection.hxx +++ b/lib/fpa/Image/DijkstraWithEndPointDetection.hxx @@ -336,8 +336,7 @@ _EndPointsAndBifurcations( ) endpoints->Insert( v ); // Get the path all the way to global seed - TVertices path; - mst->GetPath( path, v, seed ); + TVertices path = mst->GetPath( v, seed ); // Backtracking to find endpoints and bifurcations bool adding_new_points = true; @@ -398,8 +397,7 @@ _FindBranches( ) for( ; eIt != endpoints->End( ); ++eIt ) { // Get the path all the way to global seed - TVertices path; - mst->GetPath( path, *eIt, seed ); + TVertices path = mst->GetPath( *eIt, seed ); TVertex start_vertex = *eIt; typename TVertices::const_iterator pIt = path.begin( ); @@ -444,8 +442,7 @@ _LabelAll( ) actual_label++; brIt->second = actual_label; - TVertices path; - mst->GetPath( path, bIt->first, brIt->first ); + TVertices path = mst->GetPath( bIt->first, brIt->first ); typename TVertices::const_iterator pIt = path.begin( ); for( ; pIt != path.end( ); ++pIt ) { diff --git a/lib/fpa/VTK/Image2DObserver.h b/lib/fpa/VTK/Image2DObserver.h index c61af4d..bd5eea9 100644 --- a/lib/fpa/VTK/Image2DObserver.h +++ b/lib/fpa/VTK/Image2DObserver.h @@ -20,7 +20,7 @@ namespace fpa : public itk::Command { public: - typedef Image2DObserver Self; + typedef Image2DObserver Self; typedef itk::Command Superclass; typedef itk::SmartPointer< Self > Pointer; typedef itk::SmartPointer< const Self > ConstPointer; diff --git a/lib/fpaPlugins/BaseImageFilter.cxx b/lib/fpaPlugins/BaseImageFilter.cxx new file mode 100644 index 0000000..422d83b --- /dev/null +++ b/lib/fpaPlugins/BaseImageFilter.cxx @@ -0,0 +1,16 @@ +#include "BaseImageFilter.h" + +// ------------------------------------------------------------------------- +fpaPlugins::BaseImageFilter:: +BaseImageFilter( ) + : Superclass( ) +{ +} + +// ------------------------------------------------------------------------- +fpaPlugins::BaseImageFilter:: +~BaseImageFilter( ) +{ +} + +// eof - $RCSfile$ diff --git a/lib/fpaPlugins/BaseImageFilter.h b/lib/fpaPlugins/BaseImageFilter.h new file mode 100644 index 0000000..23e93e0 --- /dev/null +++ b/lib/fpaPlugins/BaseImageFilter.h @@ -0,0 +1,128 @@ +#ifndef __FPAPLUGINS__BASEIMAGEFILTER__H__ +#define __FPAPLUGINS__BASEIMAGEFILTER__H__ + +#include +#include + +namespace fpaPlugins +{ + /** + */ + class fpaPlugins_EXPORT BaseImageFilter + : public cpPlugins::Interface::ImageToImageFilter + { + public: + typedef BaseImageFilter Self; + typedef cpPlugins::Interface::ImageToImageFilter Superclass; + typedef itk::SmartPointer< Self > Pointer; + typedef itk::SmartPointer< const Self > ConstPointer; + + public: + itkTypeMacro( + BaseImageFilter, cpPlugins::Interface::ImageToImageFilter + ); + cpPlugins_Id_Macro( + BaseImageFilter, FrontPropagationImageAlgorithm + ); + + protected: + BaseImageFilter( ); + virtual ~BaseImageFilter( ); + + template< class F > + void _ConfigureDebugger( F* filter ); + + template< class F > + void _DeconfigureDebugger( F* filter ); + + private: + // Purposely not implemented. + BaseImageFilter( const Self& other ); + Self& operator=( const Self& other ); + + protected: + std::set< unsigned long > m_Observers; + }; + + // ----------------------------------------------------------------------- + /* + CPPLUGINS_INHERIT_PROVIDER( BaseImageFilter ); + */ + +} // ecapseman + +// ------------------------------------------------------------------------- +#include +//#include +#include +#include + +// ------------------------------------------------------------------------- +template< class F > +void fpaPlugins::BaseImageFilter:: +_ConfigureDebugger( F* filter ) +{ + typedef typename F::TInputImage _I; + typedef fpa::VTK::Image2DObserver< F, vtkRenderWindow > _2D; + // typedef fpa::VTK::Image3DObserver< F, vtkRenderWindow > _3D; + + this->m_Observers.clear( ); + if( this->m_Parameters->GetBool( "VisualDebug" ) ) + { + if( this->m_MPRViewer != NULL ) + { + if( _I::ImageDimension == 2 ) + { + auto iren = this->m_MPRViewer->GetInteractor( 2 ); + if( iren != NULL ) + { + typename _2D::Pointer debugger = _2D::New( ); + debugger->SetRenderWindow( iren->GetRenderWindow( ) ); + debugger->SetRenderPercentage( 0.01 ); + this->m_Observers.insert( + filter->AddObserver( itk::AnyEvent( ), debugger ) + ); + filter->ThrowEventsOn( ); + + } // fi + } + else if( _I::ImageDimension == 3 ) + { + // this->m_MPRViewer->GetInteractor( 3 ); + + } // fi + + } // fi + + if( this->m_SingleInteractor.GetPointer( ) != NULL ) + { + if( _I::ImageDimension == 2 ) + { + } + else if( _I::ImageDimension == 3 ) + { + } // fi + + } // fi + + } // fi +} + +// ------------------------------------------------------------------------- +template< class F > +void fpaPlugins::BaseImageFilter:: +_DeconfigureDebugger( F* filter ) +{ + if( filter != NULL ) + { + auto oIt = this->m_Observers.begin( ); + for( ; oIt != this->m_Observers.end( ); ++oIt ) + filter->RemoveObserver( *oIt ); + + } // fi + this->m_Observers.clear( ); +} + +#endif // __FPAPLUGINS__BASEIMAGEFILTER__H__ + +// eof - $RCSfile$ diff --git a/lib/fpaPlugins/CMakeLists.txt b/lib/fpaPlugins/CMakeLists.txt index a71c325..357e974 100644 --- a/lib/fpaPlugins/CMakeLists.txt +++ b/lib/fpaPlugins/CMakeLists.txt @@ -6,11 +6,15 @@ SET(LIBRARY_NAME fpaPlugins) SET( data_LIB_HEADERS + BaseImageFilter.h GrowFunction.h GrowFunction.hxx + MinimumSpanningTree.h + MinimumSpanningTree.cxx ) SET( filters_LIB_HEADERS + MinimumSpanningTreeToMesh.h AllPixelsImageGrowFunctionSource.h ThresholdImageGrowFunctionSource.h ImageRegionGrow.h @@ -18,10 +22,13 @@ SET( ) SET( data_LIB_SOURCES + BaseImageFilter.cxx GrowFunction.cxx + MinimumSpanningTree.cxx ) SET( filters_LIB_SOURCES + MinimumSpanningTreeToMesh.cxx AllPixelsImageGrowFunctionSource.cxx ThresholdImageGrowFunctionSource.cxx ImageRegionGrow.cxx diff --git a/lib/fpaPlugins/ImageDijkstra.cxx b/lib/fpaPlugins/ImageDijkstra.cxx index 44c1ae6..5f614e1 100644 --- a/lib/fpaPlugins/ImageDijkstra.cxx +++ b/lib/fpaPlugins/ImageDijkstra.cxx @@ -2,6 +2,7 @@ #include #include +#include #include #include @@ -19,6 +20,7 @@ ImageDijkstra( ) this->_AddInput( "Input" ); this->_AddInput( "Seeds" ); this->_AddOutput< cpPlugins::Interface::Image >( "Output" ); + this->_AddOutput< fpaPlugins::MinimumSpanningTree >( "MinimumSpanningTree" ); this->m_Parameters->ConfigureAsBool( "VisualDebug" ); this->m_Parameters->ConfigureAsBool( "StopAtOneFront" ); @@ -66,6 +68,7 @@ _GD0( itk::DataObject* data ) typedef typename _TFilter::TResult _TCost; typedef fpa::Base::Functors::InvertCostFunction< _TCost > _TCostFunctor; typedef typename I::PointType _TPoint; + typedef typename _TFilter::TMinimumSpanningTree _TMST; cpPlugins::Interface::PointList* seeds = this->GetInput< cpPlugins::Interface::PointList >( "Seeds" ); @@ -98,56 +101,28 @@ _GD0( itk::DataObject* data ) } // rof - // Connect visual debugger - std::set< unsigned long > observers; - if( - this->m_Parameters->GetBool( "VisualDebug" ) && - this->m_Interactors.size( ) > 0 - ) - { - if( I::ImageDimension == 2 ) - { - typedef - fpa::VTK::Image2DObserver< _TFilter, vtkRenderWindow > - _TDebugger; - - for( - auto iIt = this->m_Interactors.begin( ); - iIt != this->m_Interactors.end( ); - ++iIt - ) - { - typename _TDebugger::Pointer debugger = _TDebugger::New( ); - debugger->SetRenderWindow( ( *iIt )->GetRenderWindow( ) ); - debugger->SetRenderPercentage( 0.01 ); - observers.insert( filter->AddObserver( itk::AnyEvent( ), debugger ) ); - - } // rof - filter->ThrowEventsOn( ); - } - else if( I::ImageDimension == 3 ) - { - } // fi - - } // fi - // Go!!! + this->_ConfigureDebugger( filter ); filter->Update( ); - - // Remove observers (if any) - for( auto oIt = observers.begin( ); oIt != observers.end( ); ++oIt ) - filter->RemoveObserver( *oIt ); + this->_DeconfigureDebugger( filter ); // Connect output cpPlugins::Interface::Image* out = this->GetOutput< cpPlugins::Interface::Image >( "Output" ); + fpaPlugins::MinimumSpanningTree* mst = + this->GetOutput< fpaPlugins::MinimumSpanningTree >( "MinimumSpanningTree" ); if( out != NULL ) - { out->SetITK< _TOut >( filter->GetOutput( ) ); + else + return( "fpaPlugins::ImageDijkstra: output not correctly created." ); + + if( mst != NULL ) + { + mst->SetITK< _TMST >( filter->GetMinimumSpanningTree( ) ); return( "" ); } else - return( "fpaPlugins::ImageDijkstra: output not correctly created." ); + return( "fpaPlugins::ImageDijkstra: minimum spanning tree." ); } // eof - $RCSfile$ diff --git a/lib/fpaPlugins/ImageDijkstra.h b/lib/fpaPlugins/ImageDijkstra.h index c8f9d90..615d4da 100644 --- a/lib/fpaPlugins/ImageDijkstra.h +++ b/lib/fpaPlugins/ImageDijkstra.h @@ -1,27 +1,24 @@ #ifndef __FPAPLUGINS__IMAGEDIJKSTRA__H__ #define __FPAPLUGINS__IMAGEDIJKSTRA__H__ -#include -#include +#include "BaseImageFilter.h" namespace fpaPlugins { /** */ class fpaPlugins_EXPORT ImageDijkstra - : public cpPlugins::Interface::ImageToImageFilter + : public BaseImageFilter { public: - typedef ImageDijkstra Self; - typedef cpPlugins::Interface::ImageToImageFilter Superclass; - typedef itk::SmartPointer< Self > Pointer; - typedef itk::SmartPointer< const Self > ConstPointer; + typedef ImageDijkstra Self; + typedef BaseImageFilter Superclass; + typedef itk::SmartPointer< Self > Pointer; + typedef itk::SmartPointer< const Self > ConstPointer; public: itkNewMacro( Self ); - itkTypeMacro( - ImageDijkstra, cpPlugins::Interface::ImageToImageFilter - ); + itkTypeMacro( ImageDijkstra, BaseImageFilter ); cpPlugins_Id_Macro( ImageDijkstra, FrontPropagationImageAlgorithm ); diff --git a/lib/fpaPlugins/ImageRegionGrow.cxx b/lib/fpaPlugins/ImageRegionGrow.cxx index 92904e3..1f42de5 100644 --- a/lib/fpaPlugins/ImageRegionGrow.cxx +++ b/lib/fpaPlugins/ImageRegionGrow.cxx @@ -7,8 +7,6 @@ #include #include -#include -#include #include #include @@ -27,7 +25,6 @@ ImageRegionGrow( ) this->m_Parameters->ConfigureAsBool( "StopAtOneFront" ); this->m_Parameters->ConfigureAsReal( "InsideValue" ); this->m_Parameters->ConfigureAsReal( "OutsideValue" ); - // TODO: this->m_Parameters->ConfigureAsPointList( "Seeds" ); this->m_Parameters->SetBool( "VisualDebug", false ); this->m_Parameters->SetBool( "StopAtOneFront", false ); @@ -115,40 +112,10 @@ _GD0( itk::DataObject* data ) } // rof - // Connect visual debugger - if( - this->m_Parameters->GetBool( "VisualDebug" ) && - this->m_Interactors.size( ) > 0 - ) - { - if( I::ImageDimension == 2 ) - { - typedef - fpa::VTK::Image2DObserver< _TFilter, vtkRenderWindow > - _TDebugger; - - for( - auto iIt = this->m_Interactors.begin( ); - iIt != this->m_Interactors.end( ); - ++iIt - ) - { - typename _TDebugger::Pointer debugger = _TDebugger::New( ); - debugger->SetRenderWindow( ( *iIt )->GetRenderWindow( ) ); - debugger->SetRenderPercentage( 0.01 ); - filter->AddObserver( itk::AnyEvent( ), debugger ); - - } // rof - filter->ThrowEventsOn( ); - } - else if( I::ImageDimension == 3 ) - { - } // fi - - } // fi - // Go!!! + this->_ConfigureDebugger( filter ); filter->Update( ); + this->_DeconfigureDebugger( filter ); // Connect output cpPlugins::Interface::Image* out = diff --git a/lib/fpaPlugins/ImageRegionGrow.h b/lib/fpaPlugins/ImageRegionGrow.h index f6ce3ff..6e966a1 100644 --- a/lib/fpaPlugins/ImageRegionGrow.h +++ b/lib/fpaPlugins/ImageRegionGrow.h @@ -1,27 +1,24 @@ #ifndef __FPAPLUGINS__IMAGEREGIONGROW__H__ #define __FPAPLUGINS__IMAGEREGIONGROW__H__ -#include -#include +#include "BaseImageFilter.h" namespace fpaPlugins { /** */ class fpaPlugins_EXPORT ImageRegionGrow - : public cpPlugins::Interface::ImageToImageFilter + : public BaseImageFilter { public: - typedef ImageRegionGrow Self; - typedef cpPlugins::Interface::ImageToImageFilter Superclass; - typedef itk::SmartPointer< Self > Pointer; - typedef itk::SmartPointer< const Self > ConstPointer; + typedef ImageRegionGrow Self; + typedef BaseImageFilter Superclass; + typedef itk::SmartPointer< Self > Pointer; + typedef itk::SmartPointer< const Self > ConstPointer; public: itkNewMacro( Self ); - itkTypeMacro( - ImageRegionGrow, cpPlugins::Interface::ImageToImageFilter - ); + itkTypeMacro( ImageRegionGrow, BaseImageFilter ); cpPlugins_Id_Macro( ImageRegionGrow, FrontPropagationImageAlgorithm ); diff --git a/lib/fpaPlugins/MinimumSpanningTree.cxx b/lib/fpaPlugins/MinimumSpanningTree.cxx new file mode 100644 index 0000000..7803f8d --- /dev/null +++ b/lib/fpaPlugins/MinimumSpanningTree.cxx @@ -0,0 +1,16 @@ +#include + +// ------------------------------------------------------------------------- +fpaPlugins::MinimumSpanningTree:: +MinimumSpanningTree( ) + : Superclass( ) +{ +} + +// ------------------------------------------------------------------------- +fpaPlugins::MinimumSpanningTree:: +~MinimumSpanningTree( ) +{ +} + +// eof - $RCSfile$ diff --git a/lib/fpaPlugins/MinimumSpanningTree.h b/lib/fpaPlugins/MinimumSpanningTree.h new file mode 100644 index 0000000..19ef8e1 --- /dev/null +++ b/lib/fpaPlugins/MinimumSpanningTree.h @@ -0,0 +1,47 @@ +#ifndef __FPAPLUGINS__MINIMUMSPANNINGTREE__H__ +#define __FPAPLUGINS__MINIMUMSPANNINGTREE__H__ + +#include + +#include + +// ------------------------------------------------------------------------- +namespace fpaPlugins +{ + /** + */ + class cpPlugins_Interface_EXPORT MinimumSpanningTree + : public cpPlugins::Interface::DataObject + { + public: + typedef MinimumSpanningTree Self; + typedef cpPlugins::Interface::DataObject Superclass; + typedef itk::SmartPointer< Self > Pointer; + typedef itk::SmartPointer< const Self > ConstPointer; + + public: + itkNewMacro( Self ); + itkTypeMacro( MinimumSpanningTree, cpPlugins::Interface::DataObject ); + cpPlugins_Id_Macro( MinimumSpanningTree, MinimumSpanningTree ); + + public: + template< class M > + inline void SetITK( itk::Object* object ); + + protected: + MinimumSpanningTree( ); + virtual ~MinimumSpanningTree( ); + + private: + // Purposely not implemented + MinimumSpanningTree( const Self& ); + Self& operator=( const Self& ); + }; + +} // ecapseman + +#include + +#endif // __FPAPLUGINS__MINIMUMSPANNINGTREE__H__ + +// eof - $RCSfile$ diff --git a/lib/fpaPlugins/MinimumSpanningTree.hxx b/lib/fpaPlugins/MinimumSpanningTree.hxx new file mode 100644 index 0000000..34cf61f --- /dev/null +++ b/lib/fpaPlugins/MinimumSpanningTree.hxx @@ -0,0 +1,21 @@ +#ifndef __FPAPLUGINS__MINIMUMSPANNINGTREE__HXX__ +#define __FPAPLUGINS__MINIMUMSPANNINGTREE__HXX__ + +// ------------------------------------------------------------------------- +template< class M > +void fpaPlugins::MinimumSpanningTree:: +SetITK( itk::Object* object ) +{ + M* tree = dynamic_cast< M* >( object ); + if( tree != NULL ) + { + this->m_ITKObject = tree; + this->m_VTKObject = NULL; + this->Modified( ); + + } // fi +} + +#endif // __FPAPLUGINS__MINIMUMSPANNINGTREE__HXX__ + +// eof - $RCSfile$ diff --git a/lib/fpaPlugins/MinimumSpanningTreeToMesh.cxx b/lib/fpaPlugins/MinimumSpanningTreeToMesh.cxx new file mode 100644 index 0000000..9079a1c --- /dev/null +++ b/lib/fpaPlugins/MinimumSpanningTreeToMesh.cxx @@ -0,0 +1,133 @@ +#include "MinimumSpanningTreeToMesh.h" + +#include +#include +#include +#include +#include + +#include +#include +#include + +// ------------------------------------------------------------------------- +fpaPlugins::MinimumSpanningTreeToMesh:: +MinimumSpanningTreeToMesh( ) + : Superclass( ) +{ + this->_AddInput( "Input" ); + this->_AddInput( "Seeds" ); + this->_AddInput( "ReferenceImage" ); + this->_AddOutput< cpPlugins::Interface::Mesh >( "Output" ); + + this->m_Parameters->ConfigureAsUint( "Kernel" ); + this->m_Parameters->SetUint( "Kernel", 0 ); +} + +// ------------------------------------------------------------------------- +fpaPlugins::MinimumSpanningTreeToMesh:: +~MinimumSpanningTreeToMesh( ) +{ +} + +// ------------------------------------------------------------------------- +std::string fpaPlugins::MinimumSpanningTreeToMesh:: +_GenerateData( ) +{ + typedef itk::ImageBase< 2 > _2D; + typedef itk::ImageBase< 3 > _3D; + + cpPlugins::Interface::Image* input = + this->GetInput< cpPlugins::Interface::Image >( "ReferenceImage" ); + + if( input == NULL ) + return( "fpaPlugins::MinimumSpanningTreeToMesh: No reference image." ); + + _2D* im2d = input->GetITK< _2D >( ); + _3D* im3d = input->GetITK< _3D >( ); + if( im2d != NULL ) + return( this->_GD0( im2d ) ); + else if( im3d != NULL ) + return( this->_GD0( im3d ) ); + else + return( "fpaPlugins::MinimumSpanningTreeToMesh: Reference image type not supported." ); +} + +// ------------------------------------------------------------------------- +template< class I > +std::string fpaPlugins::MinimumSpanningTreeToMesh:: +_GD0( I* image ) +{ + typedef typename I::IndexType _V; + typedef typename I::PointType _P; + typedef itk::Functor::IndexLexicographicCompare< I::ImageDimension > _VC; + typedef fpa::Base::MinimumSpanningTree< _V, _VC > _MST; + + // Get inputs + fpaPlugins::MinimumSpanningTree* mst_wrapper = + this->GetInput< fpaPlugins::MinimumSpanningTree >( "Input" ); + if( mst_wrapper == NULL ) + return( "fpaPlugins::MinimumSpanningTreeToMesh: No input MST" ); + _MST* mst = mst_wrapper->GetITK< _MST >( ); + if( mst == NULL ) + return( "fpaPlugins::MinimumSpanningTreeToMesh: Input MST type not supported." ); + cpPlugins::Interface::PointList* seeds = + this->GetInput< cpPlugins::Interface::PointList >( "Seeds" ); + if( seeds == NULL ) + return( "fpaPlugins::MinimumSpanningTreeToMesh: No given seeds." ); + if( seeds->GetNumberOfPoints( ) < 2 ) + return( "fpaPlugins::MinimumSpanningTreeToMesh: Not enough seeds (<2)." ); + + // Get output + cpPlugins::Interface::Mesh* out = + this->GetOutput< cpPlugins::Interface::Mesh >( "Output" ); + vtkSmartPointer< vtkPolyData > pd = out->GetVTK< vtkPolyData >( ); + if( pd.GetPointer( ) == NULL ) + { + pd = vtkPolyData::New( ); + out->SetVTK( pd ); + + } // fi + + _P pa = seeds->GetPoint< _P >( 0 ); + _P pb = seeds->GetPoint< _P >( 1 ); + _V va, vb; + image->TransformPhysicalPointToIndex( pa, va ); + image->TransformPhysicalPointToIndex( pb, vb ); + + std::vector< _P > path = + mst->GetPathFromImage( + va, vb, image, + this->m_Parameters->GetUint( "Kernel" ) + ); + + vtkSmartPointer< vtkPoints > points = + vtkSmartPointer< vtkPoints >::New( ); + vtkSmartPointer< vtkCellArray > array = + vtkSmartPointer< vtkCellArray >::New( ); + for( unsigned int i = 0; i < path.size( ); ++i ) + { + if( I::ImageDimension == 2 ) + points->InsertNextPoint( path[ i ][ 0 ], path[ i ][ 1 ], 0 ); + else if( I::ImageDimension == 3 ) + points->InsertNextPoint( + path[ i ][ 0 ], path[ i ][ 1 ], path[ i ][ 2 ] + ); + else + points->InsertNextPoint( 0, 0, 0 ); + if( i > 0 ) + { + array->InsertNextCell( 2 ); + array->InsertCellPoint( i - 1 ); + array->InsertCellPoint( i ); + + } // fi + + } // rof + pd->SetPoints( points ); + pd->SetLines( array ); + + return( "" ); +} + +// eof - $RCSfile$ diff --git a/lib/fpaPlugins/MinimumSpanningTreeToMesh.h b/lib/fpaPlugins/MinimumSpanningTreeToMesh.h new file mode 100644 index 0000000..15ed2ed --- /dev/null +++ b/lib/fpaPlugins/MinimumSpanningTreeToMesh.h @@ -0,0 +1,51 @@ +#ifndef __FPAPLUGINS__MINIMUMSPANNINGTREETOMESH__H__ +#define __FPAPLUGINS__MINIMUMSPANNINGTREETOMESH__H__ + +#include +#include + +namespace fpaPlugins +{ + /** + */ + class fpaPlugins_EXPORT MinimumSpanningTreeToMesh + : public cpPlugins::Interface::MeshSource + { + public: + typedef MinimumSpanningTreeToMesh Self; + typedef cpPlugins::Interface::MeshSource Superclass; + typedef itk::SmartPointer< Self > Pointer; + typedef itk::SmartPointer< const Self > ConstPointer; + + public: + itkNewMacro( Self ); + itkTypeMacro( + MinimumSpanningTreeToMesh, cpPlugins::Interface::MeshSource + ); + cpPlugins_Id_Macro( + MinimumSpanningTreeToMesh, FrontPropagationImageAlgorithm + ); + + protected: + MinimumSpanningTreeToMesh( ); + virtual ~MinimumSpanningTreeToMesh( ); + + virtual std::string _GenerateData( ); + + template< class I > + std::string _GD0( I* data ); + + private: + // Purposely not implemented. + MinimumSpanningTreeToMesh( const Self& other ); + Self& operator=( const Self& other ); + }; + + // --------------------------------------------------------------------- + CPPLUGINS_INHERIT_PROVIDER( MinimumSpanningTreeToMesh ); + +} // ecapseman + +#endif // __FPAPLUGINS__MINIMUMSPANNINGTREETOMESH__H__ + +// eof - $RCSfile$ -- 2.45.1