From 528cb1796e1bc1e17589a227cc328d9209cb8bde Mon Sep 17 00:00:00 2001 From: Leonardo Florez-Valencia Date: Mon, 15 Feb 2016 16:11:57 -0500 Subject: [PATCH] Branches extraction algorithm from MSTs updated --- .../ExtractBranchesFromMinimumSpanningTree.h | 74 ++++ ...ExtractBranchesFromMinimumSpanningTree.hxx | 134 ++++++ lib/fpa/VTK/Image3DObserver.h | 70 +--- lib/fpa/VTK/Image3DObserver.hxx | 381 +++--------------- lib/fpaPlugins/BaseImageFilter.hxx | 15 +- lib/fpaPlugins/CMakeLists.txt | 2 + ...ExtractBranchesFromMinimumSpanningTree.cxx | 77 ++++ .../ExtractBranchesFromMinimumSpanningTree.h | 50 +++ 8 files changed, 411 insertions(+), 392 deletions(-) create mode 100644 lib/fpa/Base/ExtractBranchesFromMinimumSpanningTree.h create mode 100644 lib/fpa/Base/ExtractBranchesFromMinimumSpanningTree.hxx create mode 100644 lib/fpaPlugins/ExtractBranchesFromMinimumSpanningTree.cxx create mode 100644 lib/fpaPlugins/ExtractBranchesFromMinimumSpanningTree.h diff --git a/lib/fpa/Base/ExtractBranchesFromMinimumSpanningTree.h b/lib/fpa/Base/ExtractBranchesFromMinimumSpanningTree.h new file mode 100644 index 0000000..06c3046 --- /dev/null +++ b/lib/fpa/Base/ExtractBranchesFromMinimumSpanningTree.h @@ -0,0 +1,74 @@ +#ifndef __FPA__BASE__EXTRACTBRANCHESFROMMINIMUMSPANNINGTREE__H__ +#define __FPA__BASE__EXTRACTBRANCHESFROMMINIMUMSPANNINGTREE__H__ + +#include +#include +#include + +namespace fpa +{ + namespace Base + { + /** + */ + template< class T > + class ExtractBranchesFromMinimumSpanningTree + : public itk::ProcessObject + { + public: + typedef ExtractBranchesFromMinimumSpanningTree Self; + typedef itk::ProcessObject Superclass; + typedef itk::SmartPointer< Self > Pointer; + typedef itk::SmartPointer< const Self > ConstPointer; + + typedef T TMinimumSpanningTree; + typedef typename T::TVertex TVertex; + typedef typename T::TVertexCompare TVertexCompare; + typedef + fpa::Base::MatrixValuesContainer< TVertex, bool, TVertexCompare > + TBranches; + + typedef std::set< TVertex, TVertexCompare > TEndPoints; + + public: + itkNewMacro( Self ); + itkTypeMacro( + ExtractBranchesFromMinimumSpanningTree, + itk::ProcessObject + ); + + public: + const T* GetInput( ) const; + void SetInput( const T* tree ); + + TBranches* GetOutput( ); + + void ClearEndPoints( ); + void AddEndPoint( const TVertex& v ); + bool HasEndPoint( const TVertex& v ) const; + unsigned long GetNumberOfEndPoints( ) const; + + protected: + ExtractBranchesFromMinimumSpanningTree( ); + virtual ~ExtractBranchesFromMinimumSpanningTree( ); + + virtual void GenerateData( ); + + private: + // Purposely not implemented + ExtractBranchesFromMinimumSpanningTree( const Self& other ); + Self& operator=( const Self& other ); + + protected: + TEndPoints m_EndPoints; + }; + + } // ecapseman + +} // ecapseman + +#include + +#endif // __FPA__BASE__EXTRACTBRANCHESFROMMINIMUMSPANNINGTREE__H__ + +// eof - $RCSfile$ diff --git a/lib/fpa/Base/ExtractBranchesFromMinimumSpanningTree.hxx b/lib/fpa/Base/ExtractBranchesFromMinimumSpanningTree.hxx new file mode 100644 index 0000000..4af465f --- /dev/null +++ b/lib/fpa/Base/ExtractBranchesFromMinimumSpanningTree.hxx @@ -0,0 +1,134 @@ +#ifndef __FPA__BASE__EXTRACTBRANCHESFROMMINIMUMSPANNINGTREE__HXX__ +#define __FPA__BASE__EXTRACTBRANCHESFROMMINIMUMSPANNINGTREE__HXX__ + +// ------------------------------------------------------------------------- +template< class T > +const T* fpa::Base::ExtractBranchesFromMinimumSpanningTree< T >:: +GetInput( ) const +{ + return( + dynamic_cast< const T* >( this->itk::ProcessObject::GetInput( 0 ) ) + ); +} + +// ------------------------------------------------------------------------- +template< class T > +void fpa::Base::ExtractBranchesFromMinimumSpanningTree< T >:: +SetInput( const T* tree ) +{ + this->itk::ProcessObject::SetNthInput( 0, const_cast< T* >( tree ) ); +} + +// ------------------------------------------------------------------------- +template< class T > +typename fpa::Base::ExtractBranchesFromMinimumSpanningTree< T >:: +TBranches* fpa::Base::ExtractBranchesFromMinimumSpanningTree< T >:: +GetOutput( ) +{ + return( + itkDynamicCastInDebugMode< TBranches* >( this->GetPrimaryOutput( ) ) + ); +} + +// ------------------------------------------------------------------------- +template< class T > +void fpa::Base::ExtractBranchesFromMinimumSpanningTree< T >:: +ClearEndPoints( ) +{ + this->m_EndPoints.clear( ); + this->Modified( ); +} + +// ------------------------------------------------------------------------- +template< class T > +void fpa::Base::ExtractBranchesFromMinimumSpanningTree< T >:: +AddEndPoint( const TVertex& v ) +{ + if( this->m_EndPoints.find( v ) == this->m_EndPoints.end( ) ) + { + std::cout << "Add " << v << std::endl; + + this->m_EndPoints.insert( v ); + this->Modified( ); + + } // fi +} + +// ------------------------------------------------------------------------- +template< class T > +bool fpa::Base::ExtractBranchesFromMinimumSpanningTree< T >:: +HasEndPoint( const TVertex& v ) const +{ + return( this->m_EndPoints.find( v ) != this->m_EndPoints.end( ) ); +} + +// ------------------------------------------------------------------------- +template< class T > +unsigned long fpa::Base::ExtractBranchesFromMinimumSpanningTree< T >:: +GetNumberOfEndPoints( ) const +{ + return( this->m_EndPoints.size( ) ); +} + +// ------------------------------------------------------------------------- +template< class T > +fpa::Base::ExtractBranchesFromMinimumSpanningTree< T >:: +ExtractBranchesFromMinimumSpanningTree( ) + : Superclass( ) +{ + this->itk::ProcessObject::SetNumberOfRequiredInputs( 1 ); + + typename TBranches::Pointer out = + static_cast< TBranches* >( this->MakeOutput( 0 ).GetPointer( ) ); + this->itk::ProcessObject::SetNumberOfRequiredOutputs( 1 ); + this->itk::ProcessObject::SetNthOutput( 0, out.GetPointer( ) ); +} + +// ------------------------------------------------------------------------- +template< class T > +fpa::Base::ExtractBranchesFromMinimumSpanningTree< T >:: +~ExtractBranchesFromMinimumSpanningTree( ) +{ +} + +// ------------------------------------------------------------------------- +template< class T > +void fpa::Base::ExtractBranchesFromMinimumSpanningTree< T >:: +GenerateData( ) +{ + const T* tree = this->GetInput( ); + TBranches* branches = this->GetOutput( ); + + auto e0It = this->m_EndPoints.begin( ); + for( ; e0It != this->m_EndPoints.end( ); ++e0It ) + { + auto e1It = e0It; + e1It++; + for( ; e1It != this->m_EndPoints.end( ); ++e1It ) + { + std::cout << *e0It << " " << *e1It << std::endl; + // std::vector< TVertex > path = tree->GetPath( *e0It, *e1It ); + + } // rof + + } // rof +} + +/* + private: + // Purposely not implemented + ExtractBranchesFromMinimumSpanningTree( const Self& other ); + Self& operator=( const Self& other ); + + protected: + TEndPoints m_EndPoints; + }; + + } // ecapseman + + } // ecapseman +*/ + +#endif // __FPA__BASE__EXTRACTBRANCHESFROMMINIMUMSPANNINGTREE__HXX__ + +// eof - $RCSfile$ diff --git a/lib/fpa/VTK/Image3DObserver.h b/lib/fpa/VTK/Image3DObserver.h index 6b6af43..d5ec4e8 100644 --- a/lib/fpa/VTK/Image3DObserver.h +++ b/lib/fpa/VTK/Image3DObserver.h @@ -6,7 +6,6 @@ #include #include -#include #include #include #include @@ -27,10 +26,11 @@ namespace fpa typedef itk::SmartPointer< Self > Pointer; typedef itk::SmartPointer< const Self > ConstPointer; - typedef F TFilter; - typedef R TRenderWindow; - typedef typename TFilter::TInputImage TImage; - typedef typename TFilter::TVertex TVertex; + typedef F TFilter; + typedef R TRenderWindow; + typedef typename TFilter::TInputImage TImage; + typedef typename TFilter::TVertex TVertex; + typedef typename TFilter::TVertexCompare TVertexCompare; typedef std::set< TVertex > TVertices; @@ -43,13 +43,6 @@ namespace fpa public: void SetRenderWindow( R* rw ); - void SetPixel( - typename TImage::IndexType idx, - unsigned char red, - unsigned char green, - unsigned char blue, - unsigned char alpha - ); void Render( ); void Execute( itk::Object* c, const itk::EventObject& e ) { this->Execute( ( const itk::Object* )( c ), e ); } @@ -64,10 +57,11 @@ namespace fpa void operator=( const Self& ); // Not impl. protected: - vtkSmartPointer< vtkImageData > m_Stencil; vtkSmartPointer< vtkPolyData > m_PolyData; vtkSmartPointer< vtkPolyDataMapper > m_PolyDataMapper; vtkSmartPointer< vtkActor > m_PolyDataActor; + std::map< TVertex, unsigned long, TVertexCompare > m_PointsToReplace; + std::map< TVertex, unsigned long, TVertexCompare > m_PointsInFront; R* m_RenderWindow; unsigned long m_Count; @@ -75,56 +69,6 @@ namespace fpa double m_RenderPercentage; }; - /** - */ - /* - template< class F, class R > - class Image3DObserver - : public itk::Command - { - public: - typedef Image3DObserver Self; - typedef itk::Command Superclass; - typedef itk::SmartPointer< Self > Pointer; - typedef itk::SmartPointer< const Self > ConstPointer; - - typedef F TFilter; - typedef R TRenderWindow; - - public: - itkNewMacro( Self ); - itkTypeMacro( Image3DObserver, itkCommand ); - - itkGetConstMacro( RenderPercentage, double ); - itkSetMacro( RenderPercentage, double ); - - public: - void SetRenderWindow( R* rw ); - void Execute( itk::Object* c, const itk::EventObject& e ) - { this->Execute( ( const itk::Object* )( c ), e ); } - void Execute( const itk::Object* c, const itk::EventObject& e ); - - protected: - Image3DObserver( ); - virtual ~Image3DObserver( ) - { } - - private: - Image3DObserver( const Self& ); // Not impl. - void operator=( const Self& ); // Not impl. - - protected: - R* m_RenderWindow; - unsigned long m_Count; - unsigned long m_RenderCount; - double m_RenderPercentage; - - vtkSmartPointer< vtkPolyData > m_Data; - vtkSmartPointer< vtkPolyDataMapper > m_Mapper; - vtkSmartPointer< vtkActor > m_Actor; - }; - */ - } // ecapseman } // ecapseman diff --git a/lib/fpa/VTK/Image3DObserver.hxx b/lib/fpa/VTK/Image3DObserver.hxx index d39fc0b..6efa120 100644 --- a/lib/fpa/VTK/Image3DObserver.hxx +++ b/lib/fpa/VTK/Image3DObserver.hxx @@ -9,9 +9,6 @@ #include #include -#include - - // ------------------------------------------------------------------------- template< class F, class R > void fpa::VTK::Image3DObserver< F, R >:: @@ -20,46 +17,6 @@ SetRenderWindow( R* rw ) this->m_RenderWindow = rw; } -// ------------------------------------------------------------------------- -template< class F, class R > -void fpa::VTK::Image3DObserver< F, R >:: -SetPixel( - typename TImage::IndexType idx, - unsigned char red, - unsigned char green, - unsigned char blue, - unsigned char alpha - ) -{ - this->m_Stencil->SetScalarComponentFromDouble - ( idx[ 0 ], idx[ 1 ], idx[ 2 ], 0, red ); - this->m_Stencil->SetScalarComponentFromDouble - ( idx[ 0 ], idx[ 1 ], idx[ 2 ], 1, green ); - this->m_Stencil->SetScalarComponentFromDouble - ( idx[ 0 ], idx[ 1 ], idx[ 2 ], 2, blue ); - this->m_Stencil->SetScalarComponentFromDouble - ( idx[ 0 ], idx[ 1 ], idx[ 2 ], 3, alpha ); - - int ijk[ 3 ]; - ijk[ 0 ] = idx[ 0 ]; - ijk[ 1 ] = idx[ 1 ]; - ijk[ 2 ] = idx[ 2 ]; - long id = this->m_Stencil->ComputePointId( ijk ); - vtkUnsignedCharArray* pd_data = - dynamic_cast< vtkUnsignedCharArray* >( - this->m_PolyData->GetPointData( )->GetScalars( ) - ); - if( pd_data != NULL ) - { - pd_data->SetTuple4( id, red, green, blue, alpha ); - - } // fi - this->m_Stencil->Modified( ); - this->m_PolyData->Modified( ); - this->m_PolyDataMapper->Modified( ); - this->m_PolyDataActor->Modified( ); -} - // ------------------------------------------------------------------------- template< class F, class R > void fpa::VTK::Image3DObserver< F, R >:: @@ -109,86 +66,20 @@ Execute( const itk::Object* c, const itk::EventObject& e ) const F* filter = dynamic_cast< const F* >( c ); if( this->m_RenderWindow == NULL || filter == NULL ) return; + auto image = filter->GetInput( ); + if( image == NULL ) + return; const _TStartEvent* startEvt = dynamic_cast< const _TStartEvent* >( &e ); const _TStartBacktrackingEvent* startBackEvt = dynamic_cast< const _TStartBacktrackingEvent* >( &e ); if( startEvt != NULL || startBackEvt != NULL ) { - const typename F::TInputImage* img = filter->GetInput( ); - unsigned int minD = F::TInputImage::ImageDimension; - minD = ( minD < 3 )? minD: 3; - - int e[ 6 ] = { 0 }; - typename F::TInputImage::RegionType reg = img->GetRequestedRegion( ); - for( unsigned int i = 0; i < minD; i++ ) - { - e[ ( i << 1 ) + 0 ] = reg.GetIndex( )[ i ]; - e[ ( i << 1 ) + 1 ] = reg.GetIndex( )[ i ] + reg.GetSize( )[ i ] - 1; - - } // rof - - typename F::TInputImage::SpacingType spac = img->GetSpacing( ); - double s[ 3 ] = { 1, 1, 1 }; - for( unsigned int i = 0; i < minD; i++ ) - s[ i ] = double( spac[ i ] ); - - typename F::TInputImage::PointType orig = img->GetOrigin( ); - double o[ 3 ] = { 0 }; - for( unsigned int i = 0; i < minD; i++ ) - o[ i ] = double( orig[ i ] ); - - this->m_Stencil->SetExtent( e ); - this->m_Stencil->SetSpacing( s ); - this->m_Stencil->SetOrigin( o ); - this->m_Stencil->AllocateScalars( VTK_UNSIGNED_CHAR, 4 ); - for( unsigned int i = 0; i < 3; i++ ) - this->m_Stencil->GetPointData( )-> - GetScalars( )->FillComponent( i, 255 ); - this->m_Stencil->GetPointData( )->GetScalars( )->FillComponent( 3, 0 ); - - vtkSmartPointer< vtkPoints > pd_points = - vtkSmartPointer< vtkPoints >::New( ); - vtkSmartPointer< vtkCellArray > pd_verts = - vtkSmartPointer< vtkCellArray >::New( ); - vtkSmartPointer< vtkUnsignedCharArray > pd_data = - vtkSmartPointer< vtkUnsignedCharArray >::New( ); - long nPoints = this->m_Stencil->GetNumberOfPoints( ); - - pd_data->SetNumberOfComponents( 4 ); - pd_data->SetNumberOfTuples( nPoints ); - pd_points->SetNumberOfPoints( nPoints ); - double point[ 3 ]; - for( long pId = 0; pId < nPoints; ++pId ) - { - this->m_Stencil->GetPoint( pId, point ); - pd_points->InsertNextPoint( point ); - pd_verts->InsertNextCell( 1 ); - pd_verts->InsertCellPoint( pId ); - pd_data->SetTuple4( pId, 0, 0, 0, 0 ); - - } // rof - this->m_PolyData->SetPoints( pd_points ); - this->m_PolyData->SetVerts( pd_verts ); - // this->m_PolyData->GetPointData( )->SetScalars( pd_data ); - - /* - vtkSmartPointer< vtkPolyDataWriter > w = - vtkSmartPointer< vtkPolyDataWriter >::New( ); - w->SetInputData( this->m_PolyData ); - w->SetFileName( "fpa.vtk" ); - w->Update( ); - - std::exit( 1 ); - */ - - - - this->m_PolyDataMapper->SetInputData( this->m_PolyData ); - this->m_PolyDataActor->SetMapper( this->m_PolyDataMapper ); - this->m_Count = 0; - this->m_RenderCount = reg.GetNumberOfPixels( ); + this->m_RenderCount = + image->GetLargestPossibleRegion( ).GetNumberOfPixels( ); + this->m_PointsToReplace.clear( ); + this->m_PointsInFront.clear( ); vtkRenderer* ren = this->m_RenderWindow->GetRenderers( )->GetFirstRenderer( ); @@ -197,23 +88,34 @@ Execute( const itk::Object* c, const itk::EventObject& e ) } // fi - const _TAliveEvent* aliveEvt = dynamic_cast< const _TAliveEvent* >( &e ); const _TFrontEvent* frontEvt = dynamic_cast< const _TFrontEvent* >( &e ); - if( aliveEvt != NULL || frontEvt != NULL ) + if( frontEvt != NULL ) { - if( aliveEvt != NULL ) - this->SetPixel( - aliveEvt->Vertex, - Colors[ aliveEvt->FrontId ][ 0 ], - Colors[ aliveEvt->FrontId ][ 1 ], - Colors[ aliveEvt->FrontId ][ 2 ], - Colors[ aliveEvt->FrontId ][ 3 ] - ); - else if( frontEvt != NULL ) - this->SetPixel( frontEvt->Vertex, 255, 0, 0, 255 ); - this->m_Count++; + typename F::TInputImage::PointType pnt; + image->TransformIndexToPhysicalPoint( frontEvt->Vertex, pnt ); + if( this->m_PointsToReplace.empty( ) ) + { + unsigned long nPoints = this->m_PolyData->GetNumberOfPoints( ); + this->m_PolyData->GetPoints( )-> + InsertNextPoint( pnt[ 0 ], pnt[ 1 ], pnt[ 2 ] ); + this->m_PolyData->GetVerts( )->InsertNextCell( 1 ); + this->m_PolyData->GetVerts( )->InsertCellPoint( nPoints ); + this->m_PointsInFront[ frontEvt->Vertex ] = nPoints; + } + else + { + auto pIt = this->m_PointsToReplace.begin( ); + this->m_PolyData->GetPoints( )-> + SetPoint( pIt->second, pnt[ 0 ], pnt[ 1 ], pnt[ 2 ] ); + this->m_PointsToReplace.erase( pIt ); + + } // fi + this->m_PolyData->Modified( ); + this->m_PolyDataMapper->Modified( ); + this->m_PolyDataActor->Modified( ); // Render visual debug + this->m_Count++; double per = double( this->m_RenderCount ) * this->m_RenderPercentage; if( double( this->m_Count ) >= per ) this->Render( ); @@ -224,6 +126,20 @@ Execute( const itk::Object* c, const itk::EventObject& e ) } // fi + const _TAliveEvent* aliveEvt = dynamic_cast< const _TAliveEvent* >( &e ); + if( aliveEvt != NULL ) + { + auto pIt = this->m_PointsInFront.find( aliveEvt->Vertex ); + if( pIt != this->m_PointsInFront.end( ) ) + { + this->m_PointsToReplace[ pIt->first ] = pIt->second; + this->m_PointsInFront.erase( pIt ); + + } // fi + return; + + } // fi + const _TEndEvent* endEvt = dynamic_cast< const _TEndEvent* >( &e ); if( endEvt != NULL ) { @@ -241,7 +157,7 @@ Execute( const itk::Object* c, const itk::EventObject& e ) dynamic_cast< const _TEndBacktrackingEvent* >( &e ); if( backEvt != NULL ) { - this->SetPixel( backEvt->Vertex, 0, 0, 255, 255 ); + // TODO: return; } // fi @@ -249,6 +165,7 @@ Execute( const itk::Object* c, const itk::EventObject& e ) if( endBackEvt != NULL ) { this->m_RenderWindow->Render( ); + /* TODO: DEBUG std::cout << "Press enter: " << std::ends; int aux; @@ -267,211 +184,27 @@ Image3DObserver( ) m_RenderWindow( NULL ), m_RenderPercentage( double( 0.001 ) ) { - this->m_Stencil = vtkSmartPointer< vtkImageData >::New( ); this->m_PolyData = vtkSmartPointer< vtkPolyData >::New( ); this->m_PolyDataMapper = vtkSmartPointer< vtkPolyDataMapper >::New( ); this->m_PolyDataActor =vtkSmartPointer< vtkActor >::New( ); -} - -// ------------------------------------------------------------------------- -template< class F, class R > -fpa::VTK::Image3DObserver< F, R >:: -~Image3DObserver( ) -{ -} - -/* -#include -#include -#include -#include -#include -#include -// ------------------------------------------------------------------------- -template< class F, class R > -void fpa::VTK::Image3DObserver< F, R >:: -SetRenderWindow( R* rw ) -{ - this->m_RenderWindow = rw; -} - -// ------------------------------------------------------------------------- -template< class F, class R > -void fpa::VTK::Image3DObserver< F, R >:: -Execute( const itk::Object* c, const itk::EventObject& e ) -{ - typedef typename F::TStartEvent _TStartEvent; - typedef typename F::TStartLoopEvent _TStartLoopEvent; - typedef typename F::TEndEvent _TEndEvent; - typedef typename F::TEndLoopEvent _TEndLoopEvent; - typedef typename F::TAliveEvent _TAliveEvent; - typedef typename F::TFrontEvent _TFrontEvent; - typedef typename F::TFreezeEvent _TFreezeEvent; - - typedef typename F::TStartBacktrackingEvent _TStartBacktrackingEvent; - typedef typename F::TEndBacktrackingEvent _TEndBacktrackingEvent; - typedef typename F::TBacktrackingEvent _TBacktrackingEvent; - - // Check inputs - if( this->m_RenderWindow == NULL ) - return; - vtkRenderer* ren = - this->m_RenderWindow->GetRenderers( )->GetFirstRenderer( ); - if( ren == NULL ) - return; - const F* filter = dynamic_cast< const F* >( c ); - if( filter == NULL ) - return; - const _TImage* image = filter->GetInput( ); - if( image == NULL ) - return; - - const _TStartEvent* startEvt = dynamic_cast< const _TStartEvent* >( &e ); - const _TStartBacktrackingEvent* startBackEvt = - dynamic_cast< const _TStartBacktrackingEvent* >( &e ); - if( startEvt != NULL || startBackEvt != NULL ) - { - // Create actor - _TImage::RegionType reg = image->GetLargestPossibleRegion( ); - _TImage::SizeType siz = reg.GetSize( ); - if( this->m_Data.GetPointer( ) == NULL ) - { - this->m_Data = vtkSmartPointer< vtkPolyData >::New( ); - this->m_Mapper = vtkSmartPointer< vtkPolyDataMapper >::New( ); - this->m_Actor = vtkSmartPointer< vtkActor >::New( ); - - vtkSmartPointer< vtkPoints > points = - vtkSmartPointer< vtkPoints >::New( ); - vtkSmartPointer< vtkCellArray > vertices = - vtkSmartPointer< vtkCellArray >::New( ); - vtkSmartPointer< vtkFloatArray > scalars = - vtkSmartPointer< vtkFloatArray >::New( ); - this->m_Data->SetPoints( points ); - this->m_Data->SetVerts( vertices ); - this->m_Data->GetPointData( )->SetScalars( scalars ); - - this->m_Mapper->SetInputData( this->m_Data ); - this->m_Actor->SetMapper( this->m_Mapper ); - ren->AddActor( this->m_Actor ); - - this->m_Marks = TMarks::New( ); - this->m_Marks->SetLargestPossibleRegion( - image->GetLargestPossibleRegion( ) - ); - this->m_Marks->SetRequestedRegion( image->GetRequestedRegion( ) ); - this->m_Marks->SetBufferedRegion( image->GetBufferedRegion( ) ); - this->m_Marks->SetOrigin( image->GetOrigin( ) ); - this->m_Marks->SetSpacing( image->GetSpacing( ) ); - this->m_Marks->SetDirection( image->GetDirection( ) ); - this->m_Marks->Allocate( ); - this->m_Marks->FillBuffer( -1 ); - this->m_Count = 0; - this->m_RenderCount = reg.GetNumberOfPixels( ); - - } // fi - return; - - } // fi - - const _TAliveEvent* aliveEvt = dynamic_cast< const _TAliveEvent* >( &e ); - const _TFrontEvent* frontEvt = dynamic_cast< const _TFrontEvent* >( &e ); - if( aliveEvt != NULL || frontEvt != NULL ) - { - _TImage::IndexType vertex; - if( aliveEvt != NULL ) - vertex = aliveEvt->Vertex; - else if( frontEvt != NULL ) - vertex = frontEvt->Vertex; - - if( this->m_Marks->GetPixel( vertex ) == -1 ) - { - typename _TImage::PointType pnt; - image->TransformIndexToPhysicalPoint( vertex, pnt ); - - long pId = this->m_Data->GetNumberOfPoints( ); - this->m_Data->GetVerts( )->InsertNextCell( 1 ); - this->m_Data->GetVerts( )->InsertCellPoint( pId ); - this->m_Data->GetPoints( )-> - InsertNextPoint( pnt[ 0 ], pnt[ 1 ], pnt[ 2 ] ); - this->m_Data->GetPointData( )-> - GetScalars( )->InsertNextTuple1( 0.5 ); - this->m_Data->Modified( ); - - this->m_Marks->SetPixel( vertex, pId ); - this->m_Count++; - - // Render visual debug - double per = double( this->m_RenderCount ) * this->m_RenderPercentage; - if( double( this->m_Count ) >= per ) - this->m_RenderWindow->Render( ); - if( double( this->m_Count ) >= per ) - this->m_Count = 0; - - } // fi - return; - - } // fi - - const _TEndEvent* endEvt = dynamic_cast< const _TEndEvent* >( &e ); - if( endEvt != NULL ) - { - this->m_RenderWindow->Render( ); - ren->RemoveActor( this->m_Actor ); - this->m_RenderWindow->Render( ); - this->m_Marks = NULL; - this->m_Data = NULL; - this->m_Mapper = NULL; - this->m_Actor = NULL; - return; - - } // fi - - const _TBacktrackingEvent* backEvt = - dynamic_cast< const _TBacktrackingEvent* >( &e ); - const _TEndBacktrackingEvent* endBackEvt = - dynamic_cast< const _TEndBacktrackingEvent* >( &e ); - if( backEvt != NULL ) - { - static const unsigned long nColors = 10; - double back_id = - double( backEvt->FrontId % nColors ) / double( nColors ); - typename _TImage::PointType pnt; - image->TransformIndexToPhysicalPoint( backEvt->Vertex, pnt ); - - long pId = this->m_Data->GetNumberOfPoints( ); - this->m_Data->GetVerts( )->InsertNextCell( 1 ); - this->m_Data->GetVerts( )->InsertCellPoint( pId ); - this->m_Data->GetPoints( )-> - InsertNextPoint( pnt[ 0 ], pnt[ 1 ], pnt[ 2 ] ); - this->m_Data->GetPointData( )-> - GetScalars( )->InsertNextTuple1( back_id ); - this->m_Data->Modified( ); - return; - - } // fi - - if( endBackEvt != NULL ) - { - this->m_RenderWindow->Render( ); - std::cout << "Press enter: " << std::ends; - int aux; - std::cin >> aux; - return; - - } // fi + vtkSmartPointer< vtkPoints > points = + vtkSmartPointer< vtkPoints >::New( ); + vtkSmartPointer< vtkCellArray > verts = + vtkSmartPointer< vtkCellArray >::New( ); + this->m_PolyData->SetPoints( points ); + this->m_PolyData->SetVerts( verts ); + this->m_PolyDataMapper->SetInputData( this->m_PolyData ); + this->m_PolyDataActor->SetMapper( this->m_PolyDataMapper ); + this->m_PolyDataActor->GetProperty( )->SetColor( 0, 1, 0 ); } // ------------------------------------------------------------------------- template< class F, class R > fpa::VTK::Image3DObserver< F, R >:: -Image3DObserver( ) - : Superclass( ), - m_RenderWindow( NULL ), - m_RenderPercentage( double( 0.0001 ) ) +~Image3DObserver( ) { } -*/ #endif // __FPA__VTK__IMAGE3DOBSERVER__HXX__ diff --git a/lib/fpaPlugins/BaseImageFilter.hxx b/lib/fpaPlugins/BaseImageFilter.hxx index 22d8837..695794a 100644 --- a/lib/fpaPlugins/BaseImageFilter.hxx +++ b/lib/fpaPlugins/BaseImageFilter.hxx @@ -39,10 +39,15 @@ _ConfigureFilter( ) filter->ClearSeeds( ); for( unsigned int s = 0; s < seeds->GetNumberOfPoints( ); ++s ) { - _P pnt = seeds->GetPoint< _P >( s ); - typename _I::IndexType idx; - if( image->TransformPhysicalPointToIndex( pnt, idx ) ) - filter->AddSeed( idx, 0 ); + if( seeds->HaveEuclideanPoints( ) ) + { + _P pnt = seeds->GetPoint< _P >( s ); + typename _I::IndexType idx; + if( image->TransformPhysicalPointToIndex( pnt, idx ) ) + filter->AddSeed( idx, 0 ); + } + else + filter->AddSeed( seeds->GetPoint< typename _I::IndexType >( s ), 0 ); } // rof @@ -97,7 +102,7 @@ _ConfigureDebugger( F* filter ) } else if( _I::ImageDimension == 3 ) { - auto iren = this->m_MPRViewer->GetInteractor( 2 ); + auto iren = this->m_MPRViewer->GetInteractor( 3 ); if( iren != NULL ) { typename _3D::Pointer debugger = _3D::New( ); diff --git a/lib/fpaPlugins/CMakeLists.txt b/lib/fpaPlugins/CMakeLists.txt index f9bc177..773b4ff 100644 --- a/lib/fpaPlugins/CMakeLists.txt +++ b/lib/fpaPlugins/CMakeLists.txt @@ -15,6 +15,7 @@ SET( SET( filters_LIB_HEADERS MinimumSpanningTreeToMesh.h + ExtractBranchesFromMinimumSpanningTree.h AllPixelsImageGrowFunctionSource.h ThresholdImageGrowFunctionSource.h ImageRegionGrow.h @@ -29,6 +30,7 @@ SET( SET( filters_LIB_SOURCES MinimumSpanningTreeToMesh.cxx + ExtractBranchesFromMinimumSpanningTree.cxx AllPixelsImageGrowFunctionSource.cxx ThresholdImageGrowFunctionSource.cxx ImageRegionGrow.cxx diff --git a/lib/fpaPlugins/ExtractBranchesFromMinimumSpanningTree.cxx b/lib/fpaPlugins/ExtractBranchesFromMinimumSpanningTree.cxx new file mode 100644 index 0000000..dc07993 --- /dev/null +++ b/lib/fpaPlugins/ExtractBranchesFromMinimumSpanningTree.cxx @@ -0,0 +1,77 @@ +#include "ExtractBranchesFromMinimumSpanningTree.h" + +#include + +#include +#include + +#include +#include + +// ------------------------------------------------------------------------- +fpaPlugins::ExtractBranchesFromMinimumSpanningTree:: +ExtractBranchesFromMinimumSpanningTree( ) + : Superclass( ) +{ + this->_AddInput( "MinimumSpanningTree" ); + this->_AddInput( "EndPoints" ); + this->_AddOutput< cpPlugins::Interface::DataObject >( "Output" ); +} + +// ------------------------------------------------------------------------- +fpaPlugins::ExtractBranchesFromMinimumSpanningTree:: +~ExtractBranchesFromMinimumSpanningTree( ) +{ +} + +// ------------------------------------------------------------------------- +std::string fpaPlugins::ExtractBranchesFromMinimumSpanningTree:: +_GenerateData( ) +{ + std::string err = this->_GD0< 2 >( ); + if( err != "" ) + err = this->_GD0< 3 >( ); + if( err != "" ) + err = this->_GD0< 4 >( ); + return( err ); +} + +// ------------------------------------------------------------------------- +template< unsigned int D > +std::string fpaPlugins::ExtractBranchesFromMinimumSpanningTree:: +_GD0( ) +{ + typedef itk::Index< D > _V; + typedef itk::Functor::IndexLexicographicCompare< D > _VC; + typedef fpa::Base::MinimumSpanningTree< _V, _VC > _MST; + typedef fpa::Base::ExtractBranchesFromMinimumSpanningTree< _MST > _Filter; + + // Get inputs + auto tree = + this->GetInputData< fpaPlugins::MinimumSpanningTree >( + "MinimumSpanningTree" + )->GetITK< _MST >( ); + if( tree == NULL ) + return( "fpaPlugins::ExtractBranchesFromMinimumSpanningTree: Input MST type not supported." ); + auto endpoints = + this->GetInputData< cpPlugins::Interface::PointList >( "EndPoints" ); + if( endpoints->GetNumberOfPoints( ) < 2 ) + return( "fpaPlugins::ExtractBranchesFromMinimumSpanningTree: Not enough end-points (<2)." ); + if( endpoints->HaveEuclideanPoints( ) ) + return( "fpaPlugins::ExtractBranchesFromMinimumSpanningTree: end-points are on euclidean space." ); + + // Create filter and connect input + _Filter* filter = this->_CreateITK< _Filter >( ); + filter->SetInput( tree ); + for( unsigned int i = 0; i < endpoints->GetNumberOfPoints( ); ++i ) + filter->AddEndPoint( endpoints->GetPoint< _V >( i ) ); + filter->Update( ); + + // Connect output and finish + auto out = + this->GetOutputData< cpPlugins::Interface::DataObject >( "Output" ); + out->SetITK( filter->GetOutput( ) ); + return( "" ); +} + +// eof - $RCSfile$ diff --git a/lib/fpaPlugins/ExtractBranchesFromMinimumSpanningTree.h b/lib/fpaPlugins/ExtractBranchesFromMinimumSpanningTree.h new file mode 100644 index 0000000..66f50e4 --- /dev/null +++ b/lib/fpaPlugins/ExtractBranchesFromMinimumSpanningTree.h @@ -0,0 +1,50 @@ +#ifndef __FPAPLUGINS__EXTRACTBRANCHESFROMMINIMUMSPANNINGTREE__H__ +#define __FPAPLUGINS__EXTRACTBRANCHESFROMMINIMUMSPANNINGTREE__H__ + +#include +#include + +namespace fpaPlugins +{ + /** + */ + class fpaPlugins_EXPORT ExtractBranchesFromMinimumSpanningTree + : public cpPlugins::Interface::ProcessObject + { + public: + typedef ExtractBranchesFromMinimumSpanningTree Self; + typedef cpPlugins::Interface::ProcessObject Superclass; + typedef itk::SmartPointer< Self > Pointer; + typedef itk::SmartPointer< const Self > ConstPointer; + + public: + itkNewMacro( Self ); + itkTypeMacro( + ExtractBranchesFromMinimumSpanningTree, + cpPlugins::Interface::ProcessObject + ); + cpPlugins_Id_Macro( + ExtractBranchesFromMinimumSpanningTree, + FrontPropagationImageAlgorithm + ); + + protected: + ExtractBranchesFromMinimumSpanningTree( ); + virtual ~ExtractBranchesFromMinimumSpanningTree( ); + + virtual std::string _GenerateData( ); + + template< unsigned int D > + inline std::string _GD0( ); + + private: + // Purposely not implemented. + ExtractBranchesFromMinimumSpanningTree( const Self& other ); + Self& operator=( const Self& other ); + }; + +} // ecapseman + +#endif // __FPAPLUGINS__EXTRACTBRANCHESFROMMINIMUMSPANNINGTREE__H__ + +// eof - $RCSfile$ -- 2.45.1