]> Creatis software - FrontAlgorithms.git/commitdiff
Skeletonization improved.
authorLeonardo Flórez-Valencia <florez-l@javeriana.edu.co>
Tue, 8 Nov 2016 23:45:50 +0000 (18:45 -0500)
committerLeonardo Flórez-Valencia <florez-l@javeriana.edu.co>
Tue, 8 Nov 2016 23:45:50 +0000 (18:45 -0500)
lib/fpa/Image/SkeletonFilter.h
lib/fpa/Image/SkeletonFilter.hxx
plugins/Plugins/SkeletonFilter.cxx
plugins/Plugins/SkeletonFilter.h
plugins/Plugins/fpaPlugins.i

index 85618d79ef723af41774d6af8ed3d45b76e924b5..0ed3789ae0233df298ac811a10f337680d73bbff 100644 (file)
 #ifndef __fpa__Image__SkeletonFilter__h__
 #define __fpa__Image__SkeletonFilter__h__
 
-#include <itkProcessObject.h>
-#include <itkSimpleDataObjectDecorator.h>
-#include <fpa/Image/MinimumSpanningTree.h>
+#include <fpa/Image/Dijkstra.h>
 #include <cpExtensions/DataStructures/Skeleton.h>
+#include <itkSimpleDataObjectDecorator.h>
+#include <functional>
+#include <map>
 #include <set>
 
+/* TODO
+   #include <itkProcessObject.h>
+   #include <fpa/Image/MinimumSpanningTree.h>
+*/
+
 namespace fpa
 {
   namespace Image
   {
     /**
      */
-    template< class _TDistanceMap, class _TCostMap >
+    template< class _TImage >
     class SkeletonFilter
-      : public itk::ProcessObject
+      : public Dijkstra< _TImage, _TImage >
     {
     public:
       typedef SkeletonFilter                  Self;
-      typedef itk::ProcessObject              Superclass;
+      typedef Dijkstra< _TImage, _TImage >    Superclass;
       typedef itk::SmartPointer< Self >       Pointer;
       typedef itk::SmartPointer< const Self > ConstPointer;
 
-#ifdef ITK_USE_CONCEPT_CHECKING
-      itkConceptMacro(
-        SameDimension,
-        ( itk::Concept::SameDimension< _TDistanceMap::ImageDimension, _TCostMap::ImageDimension > )
+      typedef _TImage TImage;
+      itkStaticConstMacro(
+        Dimension, unsigned int, TImage::ImageDimension
         );
-#endif
-      typedef _TDistanceMap TDistanceMap;
-      typedef _TCostMap     TCostMap;
-      typedef typename TCostMap::IndexType TIndex;
-      typedef MinimumSpanningTree< TCostMap::ImageDimension > TMST;
+
+      typedef typename Superclass::TMST  TMST;
+      typedef typename TImage::IndexType TIndex;
+
       typedef
-      cpExtensions::DataStructures::Skeleton< TCostMap::ImageDimension >
-      TSkeleton;
-      typedef itk::Image< unsigned char, _TCostMap::ImageDimension > TMarks;
+      itk::Functor::IndexLexicographicCompare< Self::Dimension > TIndexCmp;
+      typedef std::set< TIndex, TIndexCmp >                      TIndicesData;
+      typedef itk::SimpleDataObjectDecorator< TIndicesData >     TIndices;
+      typedef itk::Image< unsigned char, Self::Dimension >       TMarks;
+      typedef
+      cpExtensions::DataStructures::Skeleton< Self::Dimension >  TSkeleton;
 
+    protected:
+      typedef typename Superclass::_TQueueNode _TQueueNode;
       typedef
-      itk::Functor::IndexLexicographicCompare< _TCostMap::ImageDimension >
-      TIndexCompare;
-      typedef std::set< TIndex, TIndexCompare > TIndicesData;
-      typedef itk::SimpleDataObjectDecorator< TIndicesData > TIndices;
+      std::multimap< double, TIndex, std::greater< double > >
+      _TSkeletonQueue;
 
     public:
       itkNewMacro( Self );
       itkTypeMacro( fpa::Image::SkeletonFilter, itk::Object );
 
     public:
-      _TDistanceMap* GetDistanceMap( );
-      const _TDistanceMap* GetDistanceMap( ) const;
-      void SetDistanceMap( _TDistanceMap* dmap );
-
-      _TCostMap* GetCostMap( );
-      const _TCostMap* GetCostMap( ) const;
-      void SetCostMap( _TCostMap* cmap );
-
-      TMST* GetMinimumSpanningTree( );
-      const TMST* GetMinimumSpanningTree( ) const;
-      void SetMinimumSpanningTree( TMST* mst );
-
       TIndices* GetEndPoints( );
-      const TIndices* GetEndPoints( ) const;
-
       TIndices* GetBifurcations( );
-      const TIndices* GetBifurcations( ) const;
-
       TSkeleton* GetSkeleton( );
-      const TSkeleton* GetSkeleton( ) const;
-
       TMarks* GetMarks( );
-      const TMarks* GetMarks( ) const;
 
     protected:
       SkeletonFilter( );
       virtual ~SkeletonFilter( );
 
-      virtual void GenerateData( ) fpa_OVERRIDE;
-
-      void _EndPoints(
-        const TDistanceMap* dmap,
-        const TCostMap* cmap,
-        const TMST* mst,
-        TIndicesData& end_points
-        );
-
-      void _Skeleton(
-        const TDistanceMap* dmap,
-        const TCostMap* cmap,
-        const TMST* mst,
-        const TIndicesData& end_points,
-        TIndicesData& bifurcations,
-        TSkeleton* skeleton
-        );
+      virtual void _BeforeGenerateData( ) fpa_OVERRIDE;
+      virtual void _UpdateResult( const _TQueueNode& n ) fpa_OVERRIDE;
+      virtual void _AfterGenerateData( ) fpa_OVERRIDE;
+
+      void _EndPoints( );
+      void _Skeleton( );
+
+      /* TODO
+         virtual void GenerateData( ) fpa_OVERRIDE;
+         const TDistanceMap* dmap,
+         const TCostMap* cmap,
+         const TMST* mst,
+         TIndicesData& end_points
+         );
+         const TDistanceMap* dmap,
+         const TCostMap* cmap,
+         const TMST* mst,
+         const TIndicesData& end_points,
+         TIndicesData& bifurcations,
+         TSkeleton* skeleton
+         );
+      */
 
     private:
       // Purposely not defined
       SkeletonFilter( const Self& other );
       Self& operator=( const Self& other );
+
+    protected:
+      _TSkeletonQueue m_SkeletonQueue;
+
+      unsigned long m_EndPointsIdx;
+      unsigned long m_BifurcationsIdx;
+      unsigned long m_SkeletonIdx;
+      unsigned long m_MarksIdx;
     };
 
   } // ecapseman
index 2e98935f43e2eeb9998ebddb7262aeaa7f834147..f0adeac99c7e2ec2b9f06414437314e172b16d13 100644 (file)
 #ifndef __fpa__Image__SkeletonFilter__hxx__
 #define __fpa__Image__SkeletonFilter__hxx__
 
-#include <queue>
-#include <itkImageRegionConstIteratorWithIndex.h>
+/* TODO
+   #include <queue>
+   #include <itkImageRegionConstIteratorWithIndex.h>
+*/
+#include <fpa/Base/Functors/Inverse.h>
+#include <fpa/Image/Functors/SimpleNeighborhood.h>
 #include <itkImageRegionIteratorWithIndex.h>
 
 // -------------------------------------------------------------------------
-#define fpa_Image_SkeletonFilter_InputMacro( i_n, i_t, i_i )            \
-  template< class _TDistanceMap, class _TCostMap >                      \
-  typename fpa::Image::SkeletonFilter< _TDistanceMap, _TCostMap >::     \
-  i_t* fpa::Image::SkeletonFilter< _TDistanceMap, _TCostMap >::         \
-  Get##i_n( )                                                           \
-  {                                                                     \
-    return(                                                             \
-      dynamic_cast< i_t* >( this->Superclass::GetInput( i_i ) )         \
-      );                                                                \
-  }                                                                     \
-  template< class _TDistanceMap, class _TCostMap >                      \
-  const                                                                 \
-  typename fpa::Image::SkeletonFilter< _TDistanceMap, _TCostMap >::     \
-  i_t* fpa::Image::SkeletonFilter< _TDistanceMap, _TCostMap >::         \
-  Get##i_n( ) const                                                     \
-  {                                                                     \
-    return(                                                             \
-      dynamic_cast< const i_t* >( this->Superclass::GetInput( i_i ) )   \
-      );                                                                \
-  }                                                                     \
-  template< class _TDistanceMap, class _TCostMap >                      \
-  void fpa::Image::SkeletonFilter< _TDistanceMap, _TCostMap >::         \
-  Set##i_n( i_t* input )                                                \
-  {                                                                     \
-    this->Superclass::SetNthInput( i_i, input );                        \
-  }
-
-fpa_Image_SkeletonFilter_InputMacro( DistanceMap, TDistanceMap, 0 );
-fpa_Image_SkeletonFilter_InputMacro( CostMap, TCostMap, 1 );
-fpa_Image_SkeletonFilter_InputMacro( MinimumSpanningTree, TMST, 2 );
-
-// -------------------------------------------------------------------------
-#define fpa_Image_SkeletonFilter_OutputMacro( o_n, o_t, o_i )           \
-  template< class _TDistanceMap, class _TCostMap >                      \
-  typename fpa::Image::SkeletonFilter< _TDistanceMap, _TCostMap >::     \
-  o_t* fpa::Image::SkeletonFilter< _TDistanceMap, _TCostMap >::         \
+#define fpa_Image_SkeletonFilter_OutputMacro( o_n, o_t )                \
+  template< class _TImage >                                             \
+  typename fpa::Image::SkeletonFilter< _TImage >::                      \
+  o_t* fpa::Image::SkeletonFilter< _TImage >::                          \
   Get##o_n( )                                                           \
   {                                                                     \
     return(                                                             \
-      dynamic_cast< o_t* >( this->Superclass::GetOutput( o_i ) )        \
-      );                                                                \
-  }                                                                     \
-  template< class _TDistanceMap, class _TCostMap >                      \
-  const typename                                                        \
-  fpa::Image::SkeletonFilter< _TDistanceMap, _TCostMap >::              \
-  o_t* fpa::Image::SkeletonFilter< _TDistanceMap, _TCostMap >::         \
-  Get##o_n( ) const                                                     \
-  {                                                                     \
-    return(                                                             \
-      dynamic_cast< const o_t* >( this->Superclass::GetOutput( o_i ) )  \
+      dynamic_cast< o_t* >(                                             \
+        this->itk::ProcessObject::GetOutput( this->m_##o_n##Idx )       \
+        )                                                               \
       );                                                                \
   }
 
-fpa_Image_SkeletonFilter_OutputMacro( Skeleton, TSkeleton, 0 );
-fpa_Image_SkeletonFilter_OutputMacro( EndPoints, TIndices, 1 );
-fpa_Image_SkeletonFilter_OutputMacro( Bifurcations, TIndices, 2 );
-fpa_Image_SkeletonFilter_OutputMacro( Marks, TMarks, 3 );
+fpa_Image_SkeletonFilter_OutputMacro( Skeleton, TSkeleton );
+fpa_Image_SkeletonFilter_OutputMacro( EndPoints, TIndices );
+fpa_Image_SkeletonFilter_OutputMacro( Bifurcations, TIndices );
+fpa_Image_SkeletonFilter_OutputMacro( Marks, TMarks );
 
 // -------------------------------------------------------------------------
-template< class _TDistanceMap, class _TCostMap >
-fpa::Image::SkeletonFilter< _TDistanceMap, _TCostMap >::
+template< class _TImage >
+fpa::Image::SkeletonFilter< _TImage >::
 SkeletonFilter( )
   : Superclass( )
 {
-  this->SetNumberOfRequiredInputs( 3 );
-  this->SetNumberOfRequiredOutputs( 3 );
+  typedef typename _TImage::PixelType _TPixel;
+  typedef typename _TImage::Superclass _TImageBase;
+  typedef fpa::Image::Functors::SimpleNeighborhood< _TImageBase > _TNeighFunc;
+  typedef fpa::Base::Functors::Inverse< _TPixel, _TPixel > _TInvFunc;
+
+  unsigned int nOutputs = this->GetNumberOfRequiredOutputs( );
+  this->SetNumberOfRequiredOutputs( nOutputs + 4 );
+  this->m_EndPointsIdx = nOutputs;
+  this->m_BifurcationsIdx = nOutputs + 1;
+  this->m_SkeletonIdx = nOutputs + 2;
+  this->m_MarksIdx = nOutputs + 3;
 
   typename TIndices::Pointer end_points = TIndices::New( );
   typename TIndices::Pointer bifurcations = TIndices::New( );
   typename TSkeleton::Pointer skeleton = TSkeleton::New( );
   typename TMarks::Pointer marks = TMarks::New( );
-  this->SetNthOutput( 0, skeleton.GetPointer( ) );
-  this->SetNthOutput( 1, end_points.GetPointer( ) );
-  this->SetNthOutput( 2, bifurcations.GetPointer( ) );
-  this->SetNthOutput( 3, marks.GetPointer( ) );
+  this->SetNthOutput( this->m_EndPointsIdx, end_points.GetPointer( ) );
+  this->SetNthOutput( this->m_BifurcationsIdx, bifurcations.GetPointer( ) );
+  this->SetNthOutput( this->m_SkeletonIdx, skeleton.GetPointer( ) );
+  this->SetNthOutput( this->m_MarksIdx, marks.GetPointer( ) );
+
+  typename _TNeighFunc::Pointer nfunc = _TNeighFunc::New( );
+  nfunc->SetOrder( 2 );
+  this->SetNeighborhoodFunction( nfunc );
+
+  typename _TInvFunc::Pointer ifunc = _TInvFunc::New( );
+  this->SetCostConversionFunction( ifunc );
 }
 
 // -------------------------------------------------------------------------
-template< class _TDistanceMap, class _TCostMap >
-fpa::Image::SkeletonFilter< _TDistanceMap, _TCostMap >::
+template< class _TImage >
+fpa::Image::SkeletonFilter< _TImage >::
 ~SkeletonFilter( )
 {
 }
 
 // -------------------------------------------------------------------------
-template< class _TDistanceMap, class _TCostMap >
-void fpa::Image::SkeletonFilter< _TDistanceMap, _TCostMap >::
-GenerateData( )
+template< class _TImage >
+void fpa::Image::SkeletonFilter< _TImage >::
+_BeforeGenerateData( )
 {
-  // 0. I/O objects
-  const TDistanceMap* dmap = this->GetDistanceMap( );
-  const TCostMap* cmap = this->GetCostMap( );
-  const TMST* mst = this->GetMinimumSpanningTree( );
-  TIndices* ep = this->GetEndPoints( );
-  TIndices* bi = this->GetBifurcations( );
-  TSkeleton* sk = this->GetSkeleton( );
-
-  // 1. Check input correspondance
-  // TODO
-
-  // 2. Detect end-points
-  this->_EndPoints( dmap, cmap, mst, ep->Get( ) );
-
-  // 3. Build skeleton and keep track of bifurcations
-  this->_Skeleton( dmap, cmap, mst, ep->Get( ), bi->Get( ), sk );
+  this->Superclass::_BeforeGenerateData( );
+  this->m_SkeletonQueue.clear( );
 }
 
 // -------------------------------------------------------------------------
-template< class _TDistanceMap, class _TCostMap >
-void fpa::Image::SkeletonFilter< _TDistanceMap, _TCostMap >::
-_EndPoints(
-  const TDistanceMap* dmap,
-  const TCostMap* cmap,
-  const TMST* mst,
-  TIndicesData& end_points
-  )
+template< class _TImage >
+void fpa::Image::SkeletonFilter< _TImage >::
+_UpdateResult( const _TQueueNode& n )
+{
+  typedef typename _TSkeletonQueue::value_type _TSkeletonQueueValue;
+
+  this->Superclass::_UpdateResult( n );
+
+  // Update skeleton candidates
+  double d = double( this->GetInput( )->GetPixel( n.Vertex ) );
+  if( d >= double( 0 ) )
+  {
+    d += double( 1e-5 );
+    double v = double( n.Result ) / ( d * d );
+    this->m_SkeletonQueue.insert( _TSkeletonQueueValue( v, n.Vertex ) );
+
+  } // fi
+}
+
+// -------------------------------------------------------------------------
+template< class _TImage >
+void fpa::Image::SkeletonFilter< _TImage >::
+_AfterGenerateData( )
+{
+  this->Superclass::_AfterGenerateData( );
+  this->_EndPoints( );
+  this->_Skeleton( );
+}
+
+// -------------------------------------------------------------------------
+template< class _TImage >
+void fpa::Image::SkeletonFilter< _TImage >::
+_EndPoints( )
 {
-  typedef itk::ImageRegionConstIteratorWithIndex< _TDistanceMap > _TDistMapIt;
-  typedef itk::ImageRegionConstIteratorWithIndex< _TCostMap > _TCostMapIt;
-  typedef std::multimap< double, TIndex, std::greater< double > > _TQueue;
-  typedef typename _TQueue::value_type _TQueueValue;
   typedef itk::ImageRegionIteratorWithIndex< TMarks > _TMarksIt;
 
-  static const double _eps = std::sqrt( double( TMarks::ImageDimension + 1 ) );
+  /* TODO
+     typedef itk::ImageRegionConstIteratorWithIndex< _TImage > _TDistMapIt;
+     typedef itk::ImageRegionConstIteratorWithIndex< _TOutput > _TOutputIt;
+     typedef std::multimap< double, TIndex, std::greater< double > > _TQueue;
+     typedef typename _TQueue::value_type _TQueueValue;
+  */
 
-  // Some values
+  static const double _eps = std::sqrt( double( Self::Dimension + 1 ) );
+  auto input = this->GetInput( );
+  auto mst = this->GetMinimumSpanningTree( );
   auto marks = this->GetMarks( );
-  marks->SetLargestPossibleRegion( dmap->GetLargestPossibleRegion( ) );
-  marks->SetRequestedRegion( dmap->GetRequestedRegion( ) );
-  marks->SetBufferedRegion( dmap->GetBufferedRegion( ) );
-  marks->SetSpacing( dmap->GetSpacing( ) );
-  marks->SetOrigin( dmap->GetOrigin( ) );
-  marks->SetDirection( dmap->GetDirection( ) );
+  auto& end_points = this->GetEndPoints( )->Get( );
+
+  // Some values
+  marks->SetLargestPossibleRegion( input->GetLargestPossibleRegion( ) );
+  marks->SetRequestedRegion( input->GetRequestedRegion( ) );
+  marks->SetBufferedRegion( input->GetBufferedRegion( ) );
+  marks->SetSpacing( input->GetSpacing( ) );
+  marks->SetOrigin( input->GetOrigin( ) );
+  marks->SetDirection( input->GetDirection( ) );
   marks->Allocate( );
   marks->FillBuffer( 0 );
 
-  // Create queue
-  _TQueue queue;
-  _TDistMapIt dIt( dmap, dmap->GetRequestedRegion( ) );
-  _TCostMapIt cIt( cmap, cmap->GetRequestedRegion( ) );
-  dIt.GoToBegin( );
-  cIt.GoToBegin( );
-  for( ; !dIt.IsAtEnd( ) && !cIt.IsAtEnd( ); ++dIt, ++cIt )
-  {
-    double d = double( dIt.Get( ) );
-    if( d >= double( 0 ) )
-    {
-      d += double( 1e-5 );
-      double v = double( cIt.Get( ) ) / ( d * d );
-      queue.insert( _TQueueValue( v, dIt.GetIndex( ) ) );
-
-    } // fi
-
-  } // rof
-
   // BFS from maximum queue
-  auto region = dmap->GetRequestedRegion( );
-  while( queue.size( ) > 0 )
+  auto region = input->GetRequestedRegion( );
+  while( this->m_SkeletonQueue.size( ) > 0 )
   {
     // Get node
-    auto nIt = queue.begin( );
+    auto nIt = this->m_SkeletonQueue.begin( );
     auto n = *nIt;
-    queue.erase( nIt );
+    this->m_SkeletonQueue.erase( nIt );
 
     // Mark it and update end-points
     unsigned char m = marks->GetPixel( n.second );
@@ -184,12 +162,12 @@ _EndPoints(
     for( unsigned long i = 0; i < path->GetSize( ); ++i )
     {
       TIndex idx = path->GetVertex( i );
-      typename _TCostMap::PointType cnt;
-      cmap->TransformIndexToPhysicalPoint( idx, cnt );
-      double r = double( dmap->GetPixel( idx ) ) * _eps;
+      typename _TImage::PointType cnt;
+      input->TransformIndexToPhysicalPoint( idx, cnt );
+      double r = double( input->GetPixel( idx ) ) * _eps;
 
       TIndex i0, i1;
-      for( unsigned int d = 0; d < TMarks::ImageDimension; ++d )
+      for( unsigned int d = 0; d < Self::Dimension; ++d )
       {
         long off = long( std::ceil( r / double( spac[ d ] ) ) );
         if( off < 3 )
@@ -205,11 +183,11 @@ _EndPoints(
 
       } // rof
 
-      typename TMarks::SizeType size;
-      for( unsigned int d = 0; d < TMarks::ImageDimension; ++d )
+      typename _TImage::SizeType size;
+      for( unsigned int d = 0; d < Self::Dimension; ++d )
         size[ d ] = i1[ d ] - i0[ d ] + 1;
 
-      typename TMarks::RegionType neighRegion;
+      typename _TImage::RegionType neighRegion;
       neighRegion.SetIndex( i0 );
       neighRegion.SetSize( size );
 
@@ -217,7 +195,7 @@ _EndPoints(
       for( mIt.GoToBegin( ); !mIt.IsAtEnd( ); ++mIt )
       {
         TIndex w = mIt.GetIndex( );
-        typename _TCostMap::PointType p;
+        typename _TImage::PointType p;
         marks->TransformIndexToPhysicalPoint( w, p );
         mIt.Set( 1 );
 
@@ -229,19 +207,15 @@ _EndPoints(
 }
 
 // -------------------------------------------------------------------------
-template< class _TDistanceMap, class _TCostMap >
-void fpa::Image::SkeletonFilter< _TDistanceMap, _TCostMap >::
-_Skeleton(
-  const TDistanceMap* dmap,
-  const TCostMap* cmap,
-  const TMST* mst,
-  const TIndicesData& end_points,
-  TIndicesData& bifurcations,
-  TSkeleton* skeleton
-  )
+template< class _TImage >
+void fpa::Image::SkeletonFilter< _TImage >::
+_Skeleton( )
 {
-  typedef typename TMST::TPath _TPath;
+  auto mst = this->GetMinimumSpanningTree( );
+  auto skeleton = this->GetSkeleton( );
+  auto& end_points = this->GetEndPoints( )->Get( );
 
+  typedef typename TMST::TPath _TPath;
   for( auto eIt = end_points.begin( ); eIt != end_points.end( ); ++eIt )
   {
     typename _TPath::Pointer path;
@@ -251,6 +225,22 @@ _Skeleton(
   } // rof
 }
 
+// -------------------------------------------------------------------------
+/* TODO
+   template< class _TImage >
+   void fpa::Image::SkeletonFilter< _TImage >::
+   _Skeleton(
+   const TDistanceMap* dmap,
+   const TCostMap* cmap,
+   const TMST* mst,
+   const TIndicesData& end_points,
+   TIndicesData& bifurcations,
+   TSkeleton* skeleton
+   )
+   {
+   }
+*/
+
 #endif // __fpa__Image__SkeletonFilter__hxx__
 
 // eof - $RCSfile$
index d68db4fc516fb9b71b70091377da5b448067c298..31f0f5c6cd3ca8031174016ae7b760a2a8e98c83 100644 (file)
@@ -5,11 +5,7 @@
 
 #include <fpa/Image/SkeletonFilter.h>
 #include <itkImage.h>
-
-/* TODO
-   #include <fpa/Image/SkeletonFilter.hxx>
-   #include <itkSimpleDataObjectDecorator.hxx>
-*/
+#include <vtkPolyData.h>
 
 // -------------------------------------------------------------------------
 fpaPlugins::SkeletonFilter::
@@ -18,16 +14,12 @@ SkeletonFilter( )
 {
   typedef cpPlugins::DataObjects::Image    _TImage;
   typedef cpPlugins::DataObjects::Skeleton _TSkeleton;
+  typedef cpPlugins::BaseObjects::DataObject _TData;
 
-  this->_ConfigureInput< _TImage >( "DistanceMap", true, false );
-  this->_ConfigureInput< _TImage >( "CostMap", true, false );
-  this->_ConfigureInput< _TImage >( "MST", true, false );
+  this->_ConfigureInput< _TImage >( "Input", true, false );
+  this->_ConfigureInput< _TData >( "Seeds", true, false );
   this->_ConfigureOutput< _TSkeleton >( "Skeleton" );
   this->_ConfigureOutput< _TImage >( "Marks" );
-  /* TODO
-     this->_ConfigureOutput< _TMesh >( "EndPoints" );
-     this->_ConfigureOutput< _TMesh >( "Bifurcations" );
-  */
 }
 
 // -------------------------------------------------------------------------
@@ -40,82 +32,46 @@ fpaPlugins::SkeletonFilter::
 void fpaPlugins::SkeletonFilter::
 _GenerateData( )
 {
-  auto o = this->GetInputData( "DistanceMap" );
+  auto o = this->GetInputData( "Input" );
   cpPlugins_Demangle_Image_RealPixels_AllDims_1( o, _GD0 )
     this->_Error( "Invalid input image." );
 }
 
 // -------------------------------------------------------------------------
-template< class _TDistanceMap >
+template< class _TImage >
 void fpaPlugins::SkeletonFilter::
-_GD0( _TDistanceMap* dmap )
+_GD0( _TImage* image )
 {
-  auto o = this->GetInputData( "CostMap" );
-  cpPlugins_Demangle_Image_RealPixels_2( o, _GD1, _TDistanceMap::ImageDimension, dmap )
-    this->_Error( "Invalid input image." );
-}
-
-// -------------------------------------------------------------------------
-template< class _TCostMap, class _TDistanceMap >
-void fpaPlugins::SkeletonFilter::
-_GD1( _TCostMap* cmap, _TDistanceMap* dmap )
-{
-  typedef fpa::Image::SkeletonFilter< _TDistanceMap, _TCostMap > _TFilter;
-  typedef typename _TFilter::TMST _TMST;
-
-  auto mst = this->GetInputData< _TMST >( "MST" );
-  if( mst == NULL )
-    this->_Error( "Invalid MST." );
-
+  typedef fpa::Image::SkeletonFilter< _TImage > _TFilter;
   auto filter = this->_CreateITK< _TFilter >( );
-  filter->SetDistanceMap( dmap );
-  filter->SetCostMap( cmap );
-  filter->SetMinimumSpanningTree( mst );
-  filter->Update( );
-  this->GetOutput( "Skeleton" )->SetITK( filter->GetSkeleton( ) );
-  this->GetOutput( "Marks" )->SetITK( filter->GetMarks( ) );
-
-  /* TODO
-     auto ep = filter->GetEndPoints( );
-     auto bi = filter->GetBifurcations( );
+  filter->SetInput( image );
 
-     auto ep_pd = this->GetOutputData< vtkPolyData >( "EndPoints" );
-     if( ep_pd == NULL )
-     {
-     auto points = vtkSmartPointer< vtkPoints >::New( );
-     auto verts = vtkSmartPointer< vtkCellArray >::New( );
-     auto lines = vtkSmartPointer< vtkCellArray >::New( );
-     auto polys = vtkSmartPointer< vtkCellArray >::New( );
-     auto strips = vtkSmartPointer< vtkCellArray >::New( );
-     auto pd = vtkSmartPointer< vtkPolyData >::New( );
-     pd->SetPoints( points );
-     pd->SetVerts( verts );
-     pd->SetLines( lines );
-     pd->SetPolys( polys );
-     pd->SetStrips( strips );
+  auto seeds = this->GetInputData< vtkPolyData >( "Seeds" );
+  if( seeds != NULL )
+  {
+    typename _TImage::PointType pnt;
+    typename _TImage::IndexType idx;
+    unsigned int dim =
+      ( _TImage::ImageDimension < 3 )? _TImage::ImageDimension: 3;
 
-     this->GetOutput( "EndPoints" )->SetVTK( pd );
-     ep_pd = this->GetOutputData< vtkPolyData >( "EndPoints" );
+    for( int i = 0; i < seeds->GetNumberOfPoints( ); ++i )
+    {
+      double buf[ 3 ];
+      seeds->GetPoint( i, buf );
+      pnt.Fill( 0 );
+      for( unsigned int d = 0; d < dim; ++d )
+        pnt[ d ] = buf[ d ];
 
-     } // fi
+      if( image->TransformPhysicalPointToIndex( pnt, idx ) )
+        filter->AddSeed( idx, 0 );
 
-     for( auto iIt = ep.begin( ); iIt != ep.end( ); ++iIt )
-     {
-     typename _TCostMap::PointType p;
-     cmap->TransformIndexToPhysicalPoint( *iIt, p );
+    } // rof
 
-     if( _TCostMap::ImageDimension == 1 )
-     ep_pd->GetPoints( )->InsertNextPoint( p[ 0 ], 0, 0 );
-     else if( _TCostMap::ImageDimension == 2 )
-     ep_pd->GetPoints( )->InsertNextPoint( p[ 0 ], p[ 1 ], 0 );
-     else if( _TCostMap::ImageDimension > 2 )
-     ep_pd->GetPoints( )->InsertNextPoint( p[ 0 ], p[ 1 ], p[ 2 ] );
+  } // fi
 
-     ep_pd->GetVerts( )->InsertNextCell( 1 );
-     ep_pd->GetVerts( )->InsertCellPoint( ep_pd->GetNumberOfPoints( ) - 1 );
-
-     } // rof
-  */
+  filter->Update( );
+  this->GetOutput( "Skeleton" )->SetITK( filter->GetSkeleton( ) );
+  this->GetOutput( "Marks" )->SetITK( filter->GetMarks( ) );
 }
 
 // eof - $RCSfile$
index 1337ca21489cab18e84b5740c5f09257cc8e68be..ee940c7f773cb221e40353ca4e4a78e0bbd6bcaf 100644 (file)
@@ -18,11 +18,8 @@ namespace fpaPlugins
       );
 
   protected:
-    template< class _TDistanceMap >
-    inline void _GD0( _TDistanceMap* dmap );
-
-    template< class _TCostMap, class _TDistanceMap >
-    inline void _GD1( _TCostMap* cmap, _TDistanceMap* dmap );
+    template< class _TImage >
+    inline void _GD0( _TImage* image );
   };
 
 } // ecapseman
index 57709d3b6d5d48585673b4530a48ba3ce94a6450..b01b712547dad2d7917bb95e1c07026a670cdc43 100644 (file)
@@ -21,6 +21,6 @@ instances fpa::Base::Functors::Inverse< #i_real#, #o_real# >
 instances fpa::Base::Functors::GaussianModel< #i_real#, #o_real# >
 
 instances fpa::Image::Dijkstra< itk::Image< #scalar_pixels#, #process_dims# >, itk::Image< #real_types#, #process_dims# > >
-instances fpa::Image::SkeletonFilter< itk::Image< #i_real#, #process_dims# >, itk::Image< #o_real#, #process_dims# > >
+instances fpa::Image::SkeletonFilter< itk::Image< #real_types#, #process_dims# > >
 
 ** eof - $RCSfile$