]> Creatis software - FrontAlgorithms.git/commitdiff
...
authorLeonardo Florez-Valencia <florez-l@javeriana.edu.co>
Wed, 13 Apr 2016 20:46:16 +0000 (15:46 -0500)
committerLeonardo Florez-Valencia <florez-l@javeriana.edu.co>
Wed, 13 Apr 2016 20:46:16 +0000 (15:46 -0500)
14 files changed:
lib/fpa/Base/ExtractEndPointsAndBifurcationsFromMinimumSpanningTree.h
lib/fpa/Base/ExtractEndPointsAndBifurcationsFromMinimumSpanningTree.hxx
lib/fpa/Base/ImageSkeleton.h [new file with mode: 0644]
lib/fpa/Base/ImageSkeleton.hxx [new file with mode: 0644]
lib/fpa/Image/ExtractEndPointsAndBifurcationsFromMinimumSpanningTree.h
lib/fpa/Image/ExtractEndPointsAndBifurcationsFromMinimumSpanningTree.hxx
lib/fpa/VTK/Image/ImageSkeletonToPolyData.h [new file with mode: 0644]
lib/fpa/VTK/Image/ImageSkeletonToPolyData.hxx [new file with mode: 0644]
lib/fpa_Instances/Instances.i
plugins/fpa/CMakeLists.txt
plugins/fpa/ExtractEndPointsAndBifurcationsFromMinimumSpanningTree.cxx
plugins/fpa/ImageSkeleton.cxx [new file with mode: 0644]
plugins/fpa/ImageSkeleton.h [new file with mode: 0644]
plugins/fpa/MinimumSpanningTree.h

index 598e15d20b1d717593abdd83cadbe11b8d5d5dd8..9a129042e48411d1f30c9d29e2499212696b0b01 100644 (file)
@@ -26,7 +26,7 @@ namespace fpa
       typedef _TMST  TMinimumSpanningTree;
       typedef typename _TMST::TVertex       TVertex;
       typedef std::pair< TVertex, TVertex > TBranch;
-      typedef itk::SimpleDataObjectDecorator< std::vector< TBranch > > TBranches;
+      typedef std::vector< TBranch >        TBranches;
 
       typedef
       cpExtensions::DataStructures::ImageIndexesContainer< TVertex::Dimension >
@@ -45,7 +45,6 @@ namespace fpa
       TVertices* GetEndPoints( );
       TVertices* GetBifurcations( );
       TVertices* GetCollisions( );
-      TBranches* GetBranches( );
 
       virtual void Update( ) ITK_OVERRIDE
         {
@@ -76,6 +75,9 @@ namespace fpa
       // Purposely not implemented
       ExtractEndPointsAndBifurcationsFromMinimumSpanningTree( const Self& other );
       Self& operator=( const Self& other );
+
+    protected:
+      TBranches m_Branches;
     };
 
   } // ecapseman
index 3e8b6e591dc33fb916a1e22f849ddbeeb8af2bbf..afb5252f43c693f5e08644a9213dc3634ad38369 100644 (file)
@@ -65,19 +65,6 @@ GetCollisions( )
     );
 }
 
-// -------------------------------------------------------------------------
-template< class _TMST >
-typename
-fpa::Base::ExtractEndPointsAndBifurcationsFromMinimumSpanningTree< _TMST >::
-TBranches*
-fpa::Base::ExtractEndPointsAndBifurcationsFromMinimumSpanningTree< _TMST >::
-GetBranches( )
-{
-  return(
-    dynamic_cast< TBranches* >( this->itk::ProcessObject::GetOutput( 3 ) )
-    );
-}
-
 // -------------------------------------------------------------------------
 template< class _TMST >
 fpa::Base::ExtractEndPointsAndBifurcationsFromMinimumSpanningTree< _TMST >::
@@ -89,11 +76,9 @@ ExtractEndPointsAndBifurcationsFromMinimumSpanningTree( )
   typename TVertices::Pointer ep = TVertices::New( );
   typename TVertices::Pointer bf = TVertices::New( );
   typename TVertices::Pointer co = TVertices::New( );
-  typename TBranches::Pointer br = TBranches::New( );
   this->itk::ProcessObject::SetNthOutput( 0, ep.GetPointer( ) );
   this->itk::ProcessObject::SetNthOutput( 1, bf.GetPointer( ) );
   this->itk::ProcessObject::SetNthOutput( 2, co.GetPointer( ) );
-  this->itk::ProcessObject::SetNthOutput( 3, br.GetPointer( ) );
 }
 
 // -------------------------------------------------------------------------
@@ -119,11 +104,10 @@ GenerateData( )
   auto endpoints = this->GetEndPoints( );
   auto bifurcations = this->GetBifurcations( );
   auto collisions = this->GetCollisions( );
-  auto branches = this->GetBranches( );
   endpoints->Get( ).clear( );
   bifurcations->Get( ).clear( );
   collisions->Get( ).clear( );
-  branches->Get( ).clear( );
+  this->m_Branches.clear( );
 
   // 1. Get priority queue
   auto& q = mst->GetNodeQueue( );
@@ -144,7 +128,7 @@ GenerateData( )
 
     // 2.3. Prepare new branch data and prepare new end-point
     label++;
-    branches->Get( ).push_back( _TBranch( vertex, vertex ) );
+    this->m_Branches.push_back( _TBranch( vertex, vertex ) );
     endpoints->Get( ).push_back( vertex );
 
     // 2.4. Backtracking
@@ -160,10 +144,10 @@ GenerateData( )
         bifurcations->Get( ).push_back( *pIt );
 
         // Reorder labels
-        auto coll_branch = branches->Get( )[ mark ];
-        branches->Get( )[ mark  ] = _TBranch( coll_branch.first, *pIt );
-        branches->Get( )[ label - 1 ] = _TBranch( qIt->second, *pIt );
-        branches->Get( ).push_back( _TBranch( *pIt, coll_branch.second ) );
+        auto coll_branch = this->m_Branches[ mark ];
+        this->m_Branches[ mark  ] = _TBranch( coll_branch.first, *pIt );
+        this->m_Branches[ label - 1 ] = _TBranch( qIt->second, *pIt );
+        this->m_Branches.push_back( _TBranch( *pIt, coll_branch.second ) );
 
         // Mark skeleton (b,coll_branch_second) with the new label
         label++;
@@ -195,7 +179,7 @@ GenerateData( )
             double r = this->_Radius( *pIt );
             this->_MarkSkeleton( *pIt, label );
             this->_MarkSphere( *pIt, r, label );
-            branches->Get( )[ label - 1 ].second = *pIt;
+            this->m_Branches[ label - 1 ].second = *pIt;
 
             // 2.4.4. Is this a seed? -> add it to endpoints
             auto sIt = pIt;
diff --git a/lib/fpa/Base/ImageSkeleton.h b/lib/fpa/Base/ImageSkeleton.h
new file mode 100644 (file)
index 0000000..d7ca832
--- /dev/null
@@ -0,0 +1,70 @@
+#ifndef __FPA__BASE__IMAGESKELETON__H__
+#define __FPA__BASE__IMAGESKELETON__H__
+
+#include <itkSimpleDataObjectDecorator.h>
+#include <cpExtensions/DataStructures/PolyLineParametricPath.h>
+
+namespace fpa
+{
+  namespace Base
+  {
+    /**
+     */
+    template< class _TMST >
+    class ImageSkeleton
+      : public itk::SimpleDataObjectDecorator< std::map< typename _TMST::TVertex, std::map< typename _TMST::TVertex, typename cpExtensions::DataStructures::PolyLineParametricPath< _TMST::TVertex::Dimension >::Pointer, typename _TMST::TVertex::LexicographicCompare >, typename _TMST::TVertex::LexicographicCompare > >
+    {
+    public:
+      // Base types
+      typedef _TMST                                  TMinimumSpanningTree;
+      typedef typename _TMST::TVertex                TVertex;
+      typedef typename TVertex::LexicographicCompare TVertexCmp;
+      typedef
+      cpExtensions::DataStructures::PolyLineParametricPath< TVertex::Dimension >
+      TPath;
+      typedef
+      std::map< TVertex, typename TPath::Pointer, TVertexCmp >
+      TSkeletonRow;
+      typedef std::map< TVertex, TSkeletonRow, TVertexCmp > TSkeleton;
+
+      // ITK-related types
+      typedef ImageSkeleton                               Self;
+      typedef itk::SimpleDataObjectDecorator< TSkeleton > Superclass;
+      typedef itk::SmartPointer< Self >                   Pointer;
+      typedef itk::SmartPointer< const Self >             ConstPointer;
+
+    public:
+      itkNewMacro( Self );
+      itkTypeMacro( ImageSkeleton, itk::SimpleDataObjectDecorator );
+
+      itkGetConstObjectMacro( MinimumSpanningTree, _TMST );
+      itkSetConstObjectMacro( MinimumSpanningTree, _TMST );
+
+    public:
+      void AddBranch( const TVertex& a, const TVertex& b );
+      const TPath* GetBranch( const TVertex& a, const TVertex& b ) const;
+
+    protected:
+      ImageSkeleton( );
+      virtual ~ImageSkeleton( );
+
+    private:
+      // Purposely not implemented
+      ImageSkeleton( const Self& other );
+      Self& operator=( const Self& other );
+
+    protected:
+      typename _TMST::ConstPointer m_MinimumSpanningTree;
+    };
+
+  } // ecapseman
+
+} // ecapseman
+
+#ifndef ITK_MANUAL_INSTANTIATION
+#include <fpa/Base/ImageSkeleton.hxx>
+#endif // ITK_MANUAL_INSTANTIATION
+
+#endif // __FPA__BASE__IMAGESKELETON__H__
+
+// eof - $RCSfile$
diff --git a/lib/fpa/Base/ImageSkeleton.hxx b/lib/fpa/Base/ImageSkeleton.hxx
new file mode 100644 (file)
index 0000000..cd2daec
--- /dev/null
@@ -0,0 +1,73 @@
+#ifndef __FPA__BASE__IMAGESKELETON__HXX__
+#define __FPA__BASE__IMAGESKELETON__HXX__
+
+// -------------------------------------------------------------------------
+template< class _TMST >
+void fpa::Base::ImageSkeleton< _TMST >::
+AddBranch( const TVertex& a, const TVertex& b )
+{
+  if( this->m_MinimumSpanningTree.IsNull( ) )
+    return;
+
+  // Check if the branch already exists
+  bool found = false;
+  auto arIt = this->Get( ).find( a );
+  if( arIt != this->Get( ).end( ) )
+    found = ( arIt->second.find( b ) != arIt->second.end( ) );
+  if( found )
+    return;
+
+  // Create path
+  auto vertices = this->m_MinimumSpanningTree->GetPath( a, b );
+  typename TPath::Pointer path = TPath::New( );
+  for( auto vIt = vertices.begin( ); vIt != vertices.end( ); ++vIt )
+    path->AddVertex( *vIt );
+  
+  // Assign path vertices
+  path->SetReferenceImage( this->m_MinimumSpanningTree );
+  this->Get( )[ a ][ b ] = path;
+
+  // Create symmetric path
+  this->AddBranch( b, a );
+}
+
+// -------------------------------------------------------------------------
+template< class _TMST >
+const typename fpa::Base::ImageSkeleton< _TMST >::
+TPath* fpa::Base::ImageSkeleton< _TMST >::
+GetBranch( const TVertex& a, const TVertex& b ) const
+{
+  if( this->m_MinimumSpanningTree.IsNull( ) )
+    return( NULL );
+
+  auto aIt = this->Get( ).find( a );
+  if( aIt != this->Get( ).end( ) )
+  {
+    auto bIt = aIt->second.find( b );
+    if( bIt != aIt->second.end( ) )
+      return( bIt->second.GetPointer( ) );
+    else
+      return( NULL );
+  }
+  else
+    return( NULL );
+}
+
+// -------------------------------------------------------------------------
+template< class _TMST >
+fpa::Base::ImageSkeleton< _TMST >::
+ImageSkeleton( )
+  : Superclass( )
+{
+}
+
+// -------------------------------------------------------------------------
+template< class _TMST >
+fpa::Base::ImageSkeleton< _TMST >::
+~ImageSkeleton( )
+{
+}
+
+#endif // __FPA__BASE__IMAGESKELETON__HXX__
+
+// eof - $RCSfile$
index 312da367f18ad8d2bdc0c47828843410aabb9bf6..002afb4dba3898339455580c24d1d403830f7300 100644 (file)
@@ -2,6 +2,7 @@
 #define __FPA__IMAGE__EXTRACTENDPOINTSANDBIFURCATIONSFROMMINIMUMSPANNINGTREE__H__
 
 #include <fpa/Base/ExtractEndPointsAndBifurcationsFromMinimumSpanningTree.h>
+#include <fpa/Base/ImageSkeleton.h>
 
 namespace fpa
 {
@@ -26,6 +27,7 @@ namespace fpa
       typedef typename Superclass::TVertex              TVertex;
 
       typedef itk::Image< unsigned short, TImage::ImageDimension > TMarkImage;
+      typedef fpa::Base::ImageSkeleton< _TMST > TSkeleton;
 
     public:
       itkNewMacro( Self );
@@ -41,6 +43,7 @@ namespace fpa
     public:
       const TImage* GetCostsImage( );
       const TImage* GetDistanceMap( );
+      TSkeleton* GetSkeleton( );
       void SetCostsImage( TImage* image );
       void SetDistanceMap( TImage* image );
 
index 16d03e83ce3aa2e2bb5551f98b5feb0fc186cbc7..3e7a32bcac72602428bb2d21565b9cd2a20ee4f9 100644 (file)
@@ -30,6 +30,23 @@ GetDistanceMap( )
     );
 }
 
+// -------------------------------------------------------------------------
+template< class _TImage, class _TMST >
+typename
+fpa::Image::ExtractEndPointsAndBifurcationsFromMinimumSpanningTree< _TImage, _TMST >::
+TSkeleton*
+fpa::Image::ExtractEndPointsAndBifurcationsFromMinimumSpanningTree< _TImage, _TMST >::
+GetSkeleton( )
+{
+  return(
+    dynamic_cast< TSkeleton* >(
+      this->itk::ProcessObject::GetOutput(
+        this->GetNumberOfRequiredOutputs( ) - 1
+        )
+      )
+    );
+}
+
 // -------------------------------------------------------------------------
 template< class _TImage, class _TMST >
 void
@@ -56,6 +73,10 @@ ExtractEndPointsAndBifurcationsFromMinimumSpanningTree( )
     m_SquaredDistanceMap( false )
 {
   this->SetNumberOfRequiredInputs( 3 );
+  unsigned int nOuts = this->GetNumberOfRequiredOutputs( );
+  this->SetNumberOfRequiredOutputs( nOuts + 1 );
+  typename TSkeleton::Pointer sk = TSkeleton::New( );
+  this->itk::ProcessObject::SetNthOutput( nOuts, sk.GetPointer( ) );
 }
 
 // -------------------------------------------------------------------------
@@ -71,8 +92,8 @@ void
 fpa::Image::ExtractEndPointsAndBifurcationsFromMinimumSpanningTree< _TImage, _TMST >::
 GenerateData( )
 {
+  // Create auxiliary objects
   auto image = this->GetCostsImage( );
-
   this->m_MarkImage = TMarkImage::New( );
   this->m_MarkImage->SetLargestPossibleRegion( image->GetLargestPossibleRegion( ) );
   this->m_MarkImage->SetRequestedRegion( image->GetRequestedRegion( ) );
@@ -82,7 +103,6 @@ GenerateData( )
   this->m_MarkImage->SetSpacing( image->GetSpacing( ) );
   this->m_MarkImage->Allocate( );
   this->m_MarkImage->FillBuffer( 0 );
-
   this->m_SkeletonImage = TMarkImage::New( );
   this->m_SkeletonImage->SetLargestPossibleRegion( image->GetLargestPossibleRegion( ) );
   this->m_SkeletonImage->SetRequestedRegion( image->GetRequestedRegion( ) );
@@ -93,7 +113,15 @@ GenerateData( )
   this->m_SkeletonImage->Allocate( );
   this->m_SkeletonImage->FillBuffer( 0 );
 
+  // Real execution
   this->Superclass::GenerateData( );
+
+  // Build skeleton
+  auto sk = this->GetSkeleton( );
+  sk->SetMinimumSpanningTree( this->GetMinimumSpanningTree( ) );
+  auto bIt = this->m_Branches.begin( );
+  for( ; bIt != this->m_Branches.end( ); ++bIt )
+    sk->AddBranch( bIt->first, bIt->second );
 }
 
 // -------------------------------------------------------------------------
diff --git a/lib/fpa/VTK/Image/ImageSkeletonToPolyData.h b/lib/fpa/VTK/Image/ImageSkeletonToPolyData.h
new file mode 100644 (file)
index 0000000..3c19b7b
--- /dev/null
@@ -0,0 +1,67 @@
+#ifndef __FPA__VTK__IMAGESKELETONTOPOLYDATA__H__
+#define __FPA__VTK__IMAGESKELETONTOPOLYDATA__H__
+
+#include <vtkPolyDataAlgorithm.h>
+
+namespace fpa
+{
+  namespace VTK
+  {
+    namespace Image
+    {
+      /**
+       */
+      template< class _TSkeleton >
+      class ImageSkeletonToPolyData
+        : public vtkPolyDataAlgorithm
+      {
+      public:
+        typedef ImageSkeletonToPolyData Self;
+        typedef _TSkeleton TSkeleton;
+
+      public:
+        vtkTypeMacro( ImageSkeletonToPolyData, vtkPolyDataAlgorithm );
+
+      public:
+        static Self* New( );
+
+        const TSkeleton* GetInput( ) const;
+        void SetInput( const TSkeleton* sk );
+
+      protected:
+        ImageSkeletonToPolyData( );
+        virtual ~ImageSkeletonToPolyData( );
+
+        int RequestData(
+          vtkInformation* information,
+          vtkInformationVector** input,
+          vtkInformationVector* output
+          );
+        int RequestInformation(
+          vtkInformation* information,
+          vtkInformationVector** input,
+          vtkInformationVector* output
+          );
+
+      private:
+        // Purposely not implemented
+        ImageSkeletonToPolyData( const Self& );
+        void operator=( const Self& );
+
+      protected:
+        const TSkeleton* m_Skeleton;
+      };
+
+    } // ecapseman
+
+  } // ecapseman
+
+} // ecapseman
+
+#ifndef ITK_MANUAL_INSTANTIATION
+#include <fpa/VTK/Image/ImageSkeletonToPolyData.hxx>
+#endif // ITK_MANUAL_INSTANTIATION
+
+#endif //  __FPA__VTK__IMAGESKELETONTOPOLYDATA__H__
+
+// eof - $RCSfile$
diff --git a/lib/fpa/VTK/Image/ImageSkeletonToPolyData.hxx b/lib/fpa/VTK/Image/ImageSkeletonToPolyData.hxx
new file mode 100644 (file)
index 0000000..5e41358
--- /dev/null
@@ -0,0 +1,176 @@
+#ifndef __FPA__VTK__IMAGESKELETONTOPOLYDATA__HXX__
+#define __FPA__VTK__IMAGESKELETONTOPOLYDATA__HXX__
+
+#include <vtkInformation.h>
+#include <vtkInformationVector.h>
+#include <vtkSmartPointer.h>
+
+// -------------------------------------------------------------------------
+template< class _TSkeleton >
+typename fpa::VTK::Image::ImageSkeletonToPolyData< _TSkeleton >::
+Self* fpa::VTK::Image::ImageSkeletonToPolyData< _TSkeleton >::
+New( )
+{
+  return( new Self( ) );
+}
+
+// -------------------------------------------------------------------------
+template< class _TSkeleton >
+const _TSkeleton* fpa::VTK::Image::ImageSkeletonToPolyData< _TSkeleton >::
+GetInput( ) const
+{
+  return( this->m_Skeleton );
+}
+
+// -------------------------------------------------------------------------
+template< class _TSkeleton >
+void fpa::VTK::Image::ImageSkeletonToPolyData< _TSkeleton >::
+SetInput( const _TSkeleton* sk )
+{
+  if( this->m_Skeleton != sk )
+  {
+    this->m_Skeleton = sk;
+    this->Modified( );
+
+  } // fi
+}
+
+// -------------------------------------------------------------------------
+template< class _TSkeleton >
+fpa::VTK::Image::ImageSkeletonToPolyData< _TSkeleton >::
+ImageSkeletonToPolyData( )
+  : vtkPolyDataAlgorithm( ),
+    m_Skeleton( NULL )
+{
+  this->SetNumberOfInputPorts( 0 );
+}
+
+// -------------------------------------------------------------------------
+template< class _TSkeleton >
+fpa::VTK::Image::ImageSkeletonToPolyData< _TSkeleton >::
+~ImageSkeletonToPolyData( )
+{
+}
+
+// -------------------------------------------------------------------------
+template< class _TSkeleton >
+int fpa::VTK::Image::ImageSkeletonToPolyData< _TSkeleton >::
+RequestData(
+  vtkInformation* information,
+  vtkInformationVector** input,
+  vtkInformationVector* output
+  )
+{
+  typedef typename _TSkeleton::TVertex              _TVertex;
+  typedef typename _TSkeleton::TVertexCmp           _TCmp;
+  typedef itk::Point< double, _TVertex::Dimension > _TPoint;
+  typedef
+    std::map< _TVertex, std::map< _TVertex, bool, _TCmp >, _TCmp >
+    _TMarks;
+  static const unsigned int dim = _TVertex::Dimension;
+
+  if( this->m_Skeleton == NULL )
+    return( 0 );
+
+  // Get output
+  vtkInformation* info = output->GetInformationObject( 0 );
+  vtkPolyData* out = vtkPolyData::SafeDownCast(
+    info->Get( vtkDataObject::DATA_OBJECT( ) )
+    );
+
+  // Prepare points and cells
+  vtkSmartPointer< vtkPoints > points =
+    vtkSmartPointer< vtkPoints >::New( );
+  vtkSmartPointer< vtkCellArray > lines =
+    vtkSmartPointer< vtkCellArray >::New( );
+
+  // Iterator over input data
+  auto& sk = this->m_Skeleton->Get( );
+  auto mst = this->m_Skeleton->GetMinimumSpanningTree( );
+  _TMarks marks;
+  for( auto i = sk.begin( ); i != sk.end( ); ++i )
+  {
+    for( auto j = i->second.begin( ); j != i->second.end( ); ++j )
+    {
+      if( !marks[ i->first ][ j->first ] )
+      {
+        auto path = j->second.GetPointer( );
+        if( path != NULL )
+        {
+          auto vertices = path->GetVertexList( );
+          for( unsigned int v = 0; v < vertices->Size( ); ++v )
+          {
+            auto idx = vertices->GetElement( v );
+            _TPoint pnt;
+            mst->TransformContinuousIndexToPhysicalPoint( idx, pnt );
+            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 ] );
+            if( v > 0 )
+            {
+              lines->InsertNextCell( 2 );
+              lines->InsertCellPoint( points->GetNumberOfPoints( ) - 2 );
+              lines->InsertCellPoint( points->GetNumberOfPoints( ) - 1 );
+
+            } // fi
+
+          } // rof
+
+        } // fi
+
+        // Mark path and its symmetric as visited
+        marks[ i->first ][ j->first ] = true;
+        marks[ j->first ][ i->first ] = true;
+
+      } // fi
+
+    } // rof
+
+  } // rof
+  out->SetPoints( points );
+  out->SetLines( lines );
+  return( 1 );
+}
+
+// -------------------------------------------------------------------------
+template< class _TSkeleton >
+int fpa::VTK::Image::ImageSkeletonToPolyData< _TSkeleton >::
+RequestInformation(
+  vtkInformation* information,
+  vtkInformationVector** input,
+  vtkInformationVector* output
+  )
+{
+  vtkInformation* info = output->GetInformationObject( 0 );
+  /* TODO
+     info->Set(
+     vtkStreamingDemandDrivenPipeline::MAXIMUM_NUMBER_OF_PIECES( ), -1
+     );
+  */
+
+  if( this->m_Skeleton != NULL )
+  {
+    /* TODO
+       typename C::TScalar len = this->m_RGC->GetTotalLength( );
+       typename C::TScalar s0 = this->m_RGC->Gets0( );
+       typename C::TPoint p0 = this->m_RGC->Axis( s0 );
+       typename C::TPoint p1 = this->m_RGC->Axis( s0 + len );
+
+       info->Set(
+       vtkStreamingDemandDrivenPipeline::WHOLE_BOUNDING_BOX( ),
+       double( p0[ 0 ] ), double( p1[ 0 ] ),
+       double( p0[ 1 ] ), double( p1[ 1 ] ),
+       double( p0[ 2 ] ), double( p1[ 2 ] )
+       );
+    */
+
+  } // fi
+  return( 1 );
+}
+
+#endif //  __FPA__VTK__IMAGESKELETONTOPOLYDATA__HXX__
+
+// eof - $RCSfile$
index 526304688efb2d87685bc92280b68c492ca4bbb5..9c8d6d79571ee121c8b9de968cde9e6cc2f2155c 100644 (file)
@@ -4,11 +4,14 @@ t fpa/Base/MinimumSpanningTree.h
 t fpa/Image/MinimumSpanningTree.h
 t fpa/IO/MinimumSpanningTreeReader.h
 t fpa/IO/MinimumSpanningTreeWriter.h
+t fpa/Base/ImageSkeleton.h
+t fpa/VTK/Image/ImageSkeletonToPolyData.h
 
 t itkImage.h
 t itkImportImageContainer.h
 t itkImageRegionConstIteratorWithIndex.h
 t itkImageConstIteratorWithIndex.h
+t itkSimpleDataObjectDecorator.h
 
 d #dims=2;3
 d #int=char;short;int;long
@@ -33,9 +36,16 @@ c itk::ImportImageContainer< unsigned long, #i::{#mst}Data< #dims > >
 c itk::Image< #i::{#mst}Data< #dims >, #dims >
 c #b::#mst< itk::Image< #i::{#mst}Data< #dims >, #dims >, itk::Index< #dims > >
 c #i::#mst@{Data;{}}< #dims >
+c #b::ImageSkeleton< #i::#mst< #dims > >
 
 c itk::ImageConstIteratorWithIndex< #i::#mst< #dims > >
 c itk::ImageRegionConstIteratorWithIndex< #i::#mst< #dims > >
 c fpa::IO::MinimumSpanningTree@{Reader;Writer}< #i::#mst< #dims > >
 
+* ========================
+* == Conversion filters ==
+* ========================
+
+c fpa::VTK::Image::ImageSkeletonToPolyData< #b::ImageSkeleton< #i::#mst< #dims > > >
+
 * eof - $RCSfile$
index cc21d762dee895fb0bc932e5c48ba5c4ca0c1afe..84f58c333b1dfd63b75184bbdf31559f21d4fae6 100644 (file)
@@ -30,6 +30,8 @@ SET(
   ${CMAKE_CURRENT_SOURCE_DIR}/BaseImageFilter.cxx
   ${CMAKE_CURRENT_SOURCE_DIR}/MinimumSpanningTree.h
   ${CMAKE_CURRENT_SOURCE_DIR}/MinimumSpanningTree.cxx
+  ${CMAKE_CURRENT_SOURCE_DIR}/ImageSkeleton.h
+  ${CMAKE_CURRENT_SOURCE_DIR}/ImageSkeleton.cxx
   )
 SET(lib_QT4_HEADERS "")
 
index 793493b6f69847b2d821530744b4f36ff65bebc1..8078a67856b61512b08bad78dedf8a3436a70cb1 100644 (file)
@@ -3,6 +3,7 @@
 #include <fpa_Instances/Backtracking.h>
 #include <cpPlugins/Image.h>
 #include <cpPlugins/ImageIndexesContainer.h>
+#include <plugins/fpa/ImageSkeleton.h>
 
 // -------------------------------------------------------------------------
 fpaPlugins::ExtractEndPointsAndBifurcationsFromMinimumSpanningTree::
@@ -15,6 +16,7 @@ ExtractEndPointsAndBifurcationsFromMinimumSpanningTree( )
   this->_AddOutput< cpPlugins::ImageIndexesContainer >( "EndPoints" );
   this->_AddOutput< cpPlugins::ImageIndexesContainer >( "Bifurcations" );
   this->_AddOutput< cpPlugins::ImageIndexesContainer >( "Collisions" );
+  this->_AddOutput< fpaPlugins::ImageSkeleton >( "Skeleton" );
 
   this->m_Parameters.ConfigureAsBool( "SquaredDistanceMap" );
   this->m_Parameters.SetBool( "SquaredDistanceMap", false );
@@ -75,6 +77,7 @@ _GD0( _TImage* image )
   this->GetOutputData( "EndPoints" )->SetITK( filter->GetEndPoints( ) );
   this->GetOutputData( "Bifurcations" )->SetITK( filter->GetBifurcations( ) );
   this->GetOutputData( "Collisions" )->SetITK( filter->GetCollisions( ) );
+  this->GetOutputData( "Skeleton" )->SetITK( filter->GetSkeleton( ) );
   return( "" );
 }
 
diff --git a/plugins/fpa/ImageSkeleton.cxx b/plugins/fpa/ImageSkeleton.cxx
new file mode 100644 (file)
index 0000000..f121d66
--- /dev/null
@@ -0,0 +1,75 @@
+#include <plugins/fpa/ImageSkeleton.h>
+#include <fpa_Instances/Instances.h>
+#include <fpa/VTK/Image/ImageSkeletonToPolyData.h>
+
+// -------------------------------------------------------------------------
+void fpaPlugins::ImageSkeleton::
+SetITK( itk::LightObject* o )
+{
+  typedef
+    fpa::Base::ImageSkeleton< fpa::Image::MinimumSpanningTree< 2 > > _I2;
+  typedef
+    fpa::Base::ImageSkeleton< fpa::Image::MinimumSpanningTree< 3 > > _I3;
+
+  bool     r = this->_SetITK< _I2 >( o );
+  if( !r ) r = this->_SetITK< _I3 >( o );
+  if( !r )
+    this->Superclass::SetITK( NULL );
+}
+
+// -------------------------------------------------------------------------
+void fpaPlugins::ImageSkeleton::
+SetVTK( vtkObjectBase* o )
+{
+  // Do nothing: this only has sense in ITK
+}
+
+// -------------------------------------------------------------------------
+fpaPlugins::ImageSkeleton::
+ImageSkeleton( )
+  : Superclass( )
+{
+}
+
+// -------------------------------------------------------------------------
+fpaPlugins::ImageSkeleton::
+~ImageSkeleton( )
+{
+}
+
+// -------------------------------------------------------------------------
+template< class _TMST >
+bool fpaPlugins::ImageSkeleton::
+_SetITK( itk::LightObject* o )
+{
+  typedef fpa::VTK::Image::ImageSkeletonToPolyData< _TMST > _TFilter;
+
+  _TMST* mst = dynamic_cast< _TMST* >( o );
+  if( mst != NULL )
+  {
+    _TFilter* f = dynamic_cast< _TFilter* >( this->m_ITKvVTK.GetPointer( ) );
+    if( f == NULL )
+    {
+      vtkSmartPointer< _TFilter > nf = _TFilter::New( );
+      this->m_ITKvVTK = nf.GetPointer( );
+      f = nf.GetPointer( );
+
+    } // fi
+    f->SetInput( mst );
+    f->Update( );
+
+    // Keep object track
+    this->m_ITKObject = o;
+    this->m_VTKObject = f->GetOutput( );
+    return( true );
+  }
+  else
+  {
+    this->Superclass::SetITK( NULL );
+    this->Superclass::SetVTK( NULL );
+    return( false );
+
+  } // fi
+}
+
+// eof - $RCSfile$
diff --git a/plugins/fpa/ImageSkeleton.h b/plugins/fpa/ImageSkeleton.h
new file mode 100644 (file)
index 0000000..e8a1345
--- /dev/null
@@ -0,0 +1,52 @@
+#ifndef __FPAPLUGINS__IMAGESKELETON__H__
+#define __FPAPLUGINS__IMAGESKELETON__H__
+
+#include <fpa/fpaPlugins_Export.h>
+#include <cpPlugins/DataObject.h>
+#include <vtkPolyDataAlgorithm.h>
+#include <vtkSmartPointer.h>
+
+// -------------------------------------------------------------------------
+namespace fpaPlugins
+{
+  /**
+   */
+  class fpaPlugins_EXPORT ImageSkeleton
+    : public cpPlugins::DataObject
+  {
+  public:
+    typedef ImageSkeleton             Self;
+    typedef cpPlugins::DataObject           Superclass;
+    typedef itk::SmartPointer< Self >       Pointer;
+    typedef itk::SmartPointer< const Self > ConstPointer;
+
+  public:
+    itkNewMacro( Self );
+    itkTypeMacro( ImageSkeleton, cpPlugins::DataObject );
+    cpPlugins_Id_Macro( ImageSkeleton, ImageSkeleton );
+
+  public:
+    virtual void SetITK( itk::LightObject* o ) override;
+    virtual void SetVTK( vtkObjectBase* o ) override;
+
+  protected:
+    ImageSkeleton( );
+    virtual ~ImageSkeleton( );
+
+    template< class _TMST >
+      inline bool _SetITK( itk::LightObject* o );
+
+  private:
+    // Purposely not implemented
+    ImageSkeleton( const Self& );
+    Self& operator=( const Self& );
+
+  protected:
+    vtkSmartPointer< vtkPolyDataAlgorithm > m_ITKvVTK;
+      };
+
+} // ecapseman
+
+#endif // __FPAPLUGINS__IMAGESKELETON__H__
+
+// eof - $RCSfile$
index 2904600c0d53270f315681595be9b5258a7aad48..e391ae6974094dbd41e9223a5a54607a9cf433d0 100644 (file)
@@ -32,7 +32,7 @@ namespace fpaPlugins
     virtual ~MinimumSpanningTree( );
 
     template< class _TMST >
-    bool _SetITK( itk::LightObject* o );
+      inline bool _SetITK( itk::LightObject* o );
 
   private:
     // Purposely not implemented