]> Creatis software - cpPlugins.git/commitdiff
...
authorLeonardo Flórez-Valencia <florez-l@javeriana.edu.co>
Mon, 9 Oct 2017 16:22:19 +0000 (11:22 -0500)
committerLeonardo Flórez-Valencia <florez-l@javeriana.edu.co>
Mon, 9 Oct 2017 16:22:19 +0000 (11:22 -0500)
48 files changed:
CMakeLists.txt
cmake/cpPlgInstallCommands.cmake
cmake/cpPlgUninstall.cmake.in [moved from cmake_uninstall.cmake.in with 100% similarity]
config/install_mxe.sh
config/mxe.patch
lib/ivq/Config.h.in
lib/ivq/ITK/BooleanMapSaliencyFunction.h
lib/ivq/ITK/BooleanMapSaliencyFunction.hxx
lib/ivq/ITK/CPRImageFilter.h
lib/ivq/ITK/CPRImageFilter.hxx
lib/ivq/ITK/ExtractLabelFunction.h
lib/ivq/ITK/ExtractLabelFunction.hxx
lib/ivq/ITK/Graph.h [new file with mode: 0644]
lib/ivq/ITK/Graph.hxx [new file with mode: 0644]
lib/ivq/ITK/ImageMinimumSpanningTree.h [new file with mode: 0644]
lib/ivq/ITK/ImageMinimumSpanningTree.hxx [new file with mode: 0644]
lib/ivq/ITK/ImagePath.h [new file with mode: 0644]
lib/ivq/ITK/ImagePath.hxx [new file with mode: 0644]
lib/ivq/ITK/ImagePathReader.h [new file with mode: 0644]
lib/ivq/ITK/ImagePathReader.hxx [new file with mode: 0644]
lib/ivq/ITK/ImagePathWriter.h [new file with mode: 0644]
lib/ivq/ITK/ImagePathWriter.hxx [new file with mode: 0644]
lib/ivq/ITK/ImageROIFromFunction.h
lib/ivq/ITK/ImageROIFromFunction.hxx
lib/ivq/ITK/ImageSkeleton.h [new file with mode: 0644]
lib/ivq/ITK/ImageSkeleton.hxx [new file with mode: 0644]
lib/ivq/ITK/ImageSkeletonReader.h [new file with mode: 0644]
lib/ivq/ITK/ImageSkeletonReader.hxx [new file with mode: 0644]
lib/ivq/ITK/ImageSkeletonWriter.h [new file with mode: 0644]
lib/ivq/ITK/ImageSkeletonWriter.hxx [new file with mode: 0644]
lib/ivq/ITK/ImageStatisticsFromSeeds.h
lib/ivq/ITK/ImageStatisticsFromSeeds.hxx
lib/ivq/ITK/ImageUnaryFunctionFilter.h
lib/ivq/ITK/ImageUnaryFunctionFilter.hxx
lib/ivq/ITK/IncrementalMeanAndVariance.h
lib/ivq/ITK/IsoImageSlicer.h
lib/ivq/ITK/IsoImageSlicer.hxx
lib/ivq/ITK/MinimumSpanningTree.h [new file with mode: 0644]
lib/ivq/ITK/MinimumSpanningTree.hxx [new file with mode: 0644]
lib/ivq/ITK/PeakDetector.h
lib/ivq/ITK/RasterContourFilter.h
lib/ivq/ITK/RasterContourFilter.hxx
lib/ivq/ITK/RegionOfInterestWithPaddingImageFilter.h
lib/ivq/ITK/RegionOfInterestWithPaddingImageFilter.hxx
lib/ivq/ITK/Simple3DCurve.cxx
lib/ivq/ITK/Simple3DCurve.h
lib/ivq/ITK/ThresholdFunction.h
lib/ivq/ITK/ThresholdFunction.hxx

index c3431881383059eae5e5ce49e47a9cb3f9ed6f74..c601431734d9dcd5f90eebe0d9c80727dab7e45b 100644 (file)
@@ -63,14 +63,4 @@ include(cmake/cpPlgInstallCommands.cmake)
 ## == CMake scripts
 subdirs(cmake)
 
-## == Uninstall target
-configure_file(
-  "${CMAKE_CURRENT_SOURCE_DIR}/cmake_uninstall.cmake.in"
-  "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake"
-  IMMEDIATE @ONLY
-  )
-add_custom_target(
-  uninstall
-  COMMAND ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake)
-
 ## eof - $RCSfile$
index fe30b484338eb168099cb7db921fe5cc4e5f6fe6..e62ede776ff011ff9f80d95d0913c7055f92a999 100644 (file)
@@ -39,4 +39,19 @@ if(${PROJECT_NAME}_BUILD)
     )
 endif(${PROJECT_NAME}_BUILD)
 
+## ======================
+## == Uninstall target ==
+## ======================
+
+configure_file(
+  "${PROJECT_SOURCE_DIR}/cmake/cpPlgUninstall.cmake.in"
+  "${PROJECT_BINARY_DIR}/cmake/cpPlgUninstall.cmake"
+  IMMEDIATE @ONLY
+  )
+add_custom_target(
+  uninstall
+  COMMAND ${CMAKE_COMMAND} -P ${PROJECT_BINARY_DIR}/cmake/cpPlgUninstall.cmake
+  )
+
+
 ## eof - $RCSfile$
index e43c7dde4beed8e3f04af04a0c7597818d32693b..e23f5acaaee61e89aed6f1f83f89432eaff8f0d2 100755 (executable)
@@ -8,10 +8,6 @@ while [[ "$#" -gt 1 ]]; do
         prefix="$2"
         shift
         ;;
-        -suffix)
-        suffix="$2"
-        shift
-        ;;
         -cores)
         cores="$2"
         shift
@@ -25,7 +21,7 @@ done
 
 ## -- Check command line options
 if [ -z "$prefix" ] ; then
-    (>&2 echo "Usage: $0 -prefix [dir] [-suffix [string]] [-cores [n]]")
+    (>&2 echo "Usage: $0 -prefix [dir] [-cores [n]]")
     exit 1
 fi
 
@@ -33,9 +29,6 @@ fi
 if [ -z "$cores" ] ; then
     cores="1"
 fi
-if [ ! -z "$suffix" ] ; then
-    qt_suffix="-qtlibinfix $suffix"
-fi
 curr_dir=`pwd`
 
 ## -- Get mxe
@@ -46,6 +39,9 @@ git clone https://github.com/mxe/mxe.git
 cd $prefix/mxe
 echo "MXE_TARGETS := x86_64-w64-mingw32.shared" > settings.mk
 
+## -- Patch mxe
+patch -s -p1 < $curr_dir/mxe.patch
+
 ## -- Compile all
 make -j$cores -k qtbase vtk itk nsis
 
index 1a354af1b9be0e52f366de6a6d3dc2185ee65971..cdf60f174d65765a9b3e68cbd7422f447f58e018 100644 (file)
@@ -1,7 +1,16 @@
 diff --git a/src/itk.mk b/src/itk.mk
-index a8194fa9..ae5df898 100644
+index a8194fa..5c48425 100644
 --- a/src/itk.mk
 +++ b/src/itk.mk
+@@ -9,7 +9,7 @@ $(PKG)_CHECKSUM := 334312cc31925fd6c2622c9cd4ed33fecbbbd5b97e03b93f34b259d08352e
+ $(PKG)_SUBDIR   := InsightToolkit-$($(PKG)_VERSION)
+ $(PKG)_FILE     := $($(PKG)_SUBDIR).tar.xz
+ $(PKG)_URL      := https://$(SOURCEFORGE_MIRROR)/project/$(PKG)/$(PKG)/$(call SHORT_PKG_VERSION,$(PKG))/$($(PKG)_FILE)
+-$(PKG)_DEPS     := gcc expat hdf5 jpeg libpng tiff zlib
++$(PKG)_DEPS     := gcc expat hdf5 jpeg libpng tiff zlib vtk
+ define $(PKG)_UPDATE
+     $(WGET) -q -O- 'https://itk.org/ITK/resources/software.html' | \
 @@ -31,6 +31,10 @@ define $(PKG)_BUILD
          -DITK_USE_SYSTEM_PNG=TRUE \
          -DITK_USE_SYSTEM_TIFF=TRUE \
index 46a01449d114a919b9cb1cc4767fe0bb78791914..35b65ad8c72ca8fca6f3916fe9491b8a4e2b4e76 100644 (file)
@@ -6,6 +6,7 @@
 #define __ivq__Config__h__
 
 #include <ivq/ivq_export.h>
+#include <itkMacro.h>
 
 #if @cpPlugins_USE_VTK@ == 1
 #  define ivq_USE_VTK
 #  define ivq_USE_Qt5
 #endif // @cpPlugins_USE_Qt5@ == 1
 
+// -------------------------------------------------------------------------
+#define ivqITKInputMacro( __n__, __t__ )        \
+  private:                                      \
+  unsigned int m_##__n__##Idx;                  \
+  public:                                       \
+  __t__* Get##__n__( )                          \
+  {                                             \
+    return(                                     \
+      dynamic_cast< __t__* >(                   \
+        this->itk::ProcessObject::GetInput(     \
+          this->m_##__n__##Idx                  \
+          ) ) );                                \
+  }                                             \
+  const __t__* Get##__n__( ) const              \
+  {                                             \
+    return(                                     \
+      dynamic_cast< const __t__* >(             \
+        this->itk::ProcessObject::GetInput(     \
+          this->m_##__n__##Idx                  \
+          ) ) );                                \
+  }                                             \
+  void Set##__n__( const __t__* i )             \
+  {                                             \
+    this->itk::ProcessObject::SetNthInput(      \
+      this->m_##__n__##Idx,                     \
+      const_cast< __t__* >( i )                 \
+      );                                        \
+  }
+
+// -------------------------------------------------------------------------
+#define ivqITKInputConfigureMacro( __n__, __t__ )               \
+  this->m_##__n__##Idx = this->GetNumberOfRequiredInputs( );    \
+  this->itk::ProcessObject::SetNumberOfRequiredInputs(          \
+    this->m_##__n__##Idx + 1                                    \
+    )
+
+// -------------------------------------------------------------------------
+#define ivqITKOutputMacro( __n__, __t__ )       \
+  private:                                      \
+  unsigned int m_##__n__##Idx;                  \
+  public:                                       \
+  __t__* Get##__n__( )                          \
+  {                                             \
+    return(                                     \
+      dynamic_cast< __t__* >(                   \
+        this->itk::ProcessObject::GetOutput(    \
+          this->m_##__n__##Idx                  \
+          ) ) );                                \
+  }                                             \
+  const __t__* Get##__n__( ) const              \
+  {                                             \
+    return(                                     \
+      dynamic_cast< const __t__* >(             \
+        this->itk::ProcessObject::GetOutput(    \
+          this->m_##__n__##Idx                  \
+          ) ) );                                \
+  }
+
+// -------------------------------------------------------------------------
+#define ivqITKOutputConfigureMacro( __n__, __t__ )              \
+  this->m_##__n__##Idx = this->GetNumberOfRequiredOutputs( );   \
+  this->itk::ProcessObject::SetNumberOfRequiredOutputs(         \
+    this->m_##__n__##Idx + 1                                    \
+    );                                                          \
+  this->SetNthOutput( this->m_##__n__##Idx, __t__::New( ) )
+
 #endif // __ivq__Config__h__
 
 // eof - $RCSfile$
index ce39edeaab368c2a6c32a3a3dbc01f5e22a0be9f..f5a1f9d1b9e29ea91a50f3e95e0d48ee6f159f2b 100644 (file)
@@ -1,9 +1,7 @@
-/* =======================================================================
- * @author: Leonardo Florez-Valencia
- * @email: florez-l@javeriana.edu.co
- * =======================================================================
- */
-
+// =======================================================================
+// @author: Leonardo Florez-Valencia
+// @email: florez-l@javeriana.edu.co
+// =======================================================================
 #ifndef __ivq__ITK__BooleanMapSaliencyFunction__h__
 #define __ivq__ITK__BooleanMapSaliencyFunction__h__
 
@@ -75,7 +73,6 @@ namespace ivq
 #ifndef ITK_MANUAL_INSTANTIATION
 #  include <ivq/ITK/BooleanMapSaliencyFunction.hxx>
 #endif // ITK_MANUAL_INSTANTIATION
-
 #endif // __ivq__ITK__BooleanMapSaliencyFunction__h__
 
 // eof - $RCSfile$
index 8084ac1b859edaf4d0a56de0c281c84fb0b0d37e..373318285d1612ba73dfb8a0af121d76be62125e 100644 (file)
@@ -1,9 +1,7 @@
-/* =======================================================================
- * @author: Leonardo Florez-Valencia
- * @email: florez-l@javeriana.edu.co
- * =======================================================================
- */
-
+// =======================================================================
+// @author: Leonardo Florez-Valencia
+// @email: florez-l@javeriana.edu.co
+// =======================================================================
 #ifndef __ivq__ITK__BooleanMapSaliencyFilter__hxx__
 #define __ivq__ITK__BooleanMapSaliencyFilter__hxx__
 
index 6d42fa044b038be0d5453b8aaf803075dc0a68cf..aa8bbb789b88f685ec5d85cd87e037b83325db12 100644 (file)
@@ -1,9 +1,7 @@
-/* =======================================================================
- * @author: Leonardo Florez-Valencia
- * @email: florez-l@javeriana.edu.co
- * =======================================================================
- */
-
+// =======================================================================
+// @author: Leonardo Florez-Valencia
+// @email: florez-l@javeriana.edu.co
+// =======================================================================
 #ifndef __ivq__ITK__CPRImageFilter__h__
 #define __ivq__ITK__CPRImageFilter__h__
 
@@ -12,6 +10,7 @@
 #include <itkImageToImageFilter.h>
 #include <itkJoinSeriesImageFilter.h>
 
+#include <ivq/Config.h>
 #include <ivq/ITK/IsoImageSlicer.h>
 
 namespace ivq
@@ -50,10 +49,7 @@ namespace ivq
       itkSetMacro( SliceRadius, double );
       itkSetObjectMacro( Interpolator, TInterpolateFunction );
 
-    public:
-      _TCurve* GetCurve( );
-      const _TCurve* GetCurve( ) const;
-      void SetCurve( _TCurve* curve );
+      ivqITKInputMacro( InputCurve, _TCurve );
 
     protected:
       CPRImageFilter( );
@@ -78,7 +74,6 @@ namespace ivq
 #ifndef ITK_MANUAL_INSTANTIATION
 #  include <ivq/ITK/CPRImageFilter.hxx>
 #endif // ITK_MANUAL_INSTANTIATION
-
 #endif // __ivq__ITK__CPRImageFilter__h__
 
 // eof - $RCSfile$
index 346cc0a777ca464bb494f7619fcf91d1961adc97..b07ee85fa1696d753aea472acf422b7d28372572 100644 (file)
@@ -1,42 +1,12 @@
-/* =======================================================================
- * @author: Leonardo Florez-Valencia
- * @email: florez-l@javeriana.edu.co
- * =======================================================================
- */
-
+// =======================================================================
+// @author: Leonardo Florez-Valencia
+// @email: florez-l@javeriana.edu.co
+// =======================================================================
 #ifndef __ivq__ITK__CPRImageFilter__hxx__
 #define __ivq__ITK__CPRImageFilter__hxx__
 
 #include <itkMinimumMaximumImageCalculator.h>
 
-// -------------------------------------------------------------------------
-template< class _TImage, class _TCurve >
-_TCurve* ivq::ITK::CPRImageFilter< _TImage, _TCurve >::
-GetCurve( )
-{
-  return(
-    dynamic_cast< _TCurve* >( this->itk::ProcessObject::GetInput( 1 ) )
-    );
-}
-
-// -------------------------------------------------------------------------
-template< class _TImage, class _TCurve >
-const _TCurve* ivq::ITK::CPRImageFilter< _TImage, _TCurve >::
-GetCurve( ) const
-{
-  return(
-    dynamic_cast< const _TCurve* >( this->itk::ProcessObject::GetInput( 1 ) )
-    );
-}
-
-// -------------------------------------------------------------------------
-template< class _TImage, class _TCurve >
-void ivq::ITK::CPRImageFilter< _TImage, _TCurve >::
-SetCurve( _TCurve* curve )
-{
-  this->itk::ProcessObject::SetNthInput( 1, curve );
-}
-
 // -------------------------------------------------------------------------
 template< class _TImage, class _TCurve >
 ivq::ITK::CPRImageFilter< _TImage, _TCurve >::
@@ -44,7 +14,7 @@ CPRImageFilter( )
   : Superclass( ),
     m_SliceRadius( 0 )
 {
-  this->Superclass::SetNumberOfRequiredInputs( 2 );
+  ivqITKInputConfigureMacro( InputCurve, _TCurve );
 }
 
 // -------------------------------------------------------------------------
@@ -79,7 +49,7 @@ GenerateData( )
   typedef itk::MinimumMaximumImageCalculator< _TImage > _TMinMax;
 
   const _TImage* input = this->GetInput( );
-  const _TCurve* curve = this->GetCurve( );
+  const _TCurve* curve = this->GetInputCurve( );
   _TImage* output = this->GetOutput( );
 
   // Compute image intensity range
index bd9f70b11f4ceffe1278970684d732048169e87f..3dcfa6f8587273dfc65751084c3d8035c10cfc27 100644 (file)
@@ -1,9 +1,7 @@
-/* =======================================================================
- * @author: Leonardo Florez-Valencia
- * @email: florez-l@javeriana.edu.co
- * =======================================================================
- */
-
+// =======================================================================
+// @author: Leonardo Florez-Valencia
+// @email: florez-l@javeriana.edu.co
+// =======================================================================
 #ifndef __ivq__ITK__ExtractLabelFunction__h__
 #define __ivq__ITK__ExtractLabelFunction__h__
 
@@ -67,7 +65,6 @@ namespace ivq
 #ifndef ITK_MANUAL_INSTANTIATION
 #  include <ivq/ITK/ExtractLabelFunction.hxx>
 #endif // ITK_MANUAL_INSTANTIATION
-
 #endif // __ivq__ITK__ExtractLabelFunction__h__
 
 // eof - $RCSfile$
index 1f009cf4339f61c5f45ce5abbed4197c37d0ec1d..5c84fac84968ae1b3e789b8781fe249402fac454 100644 (file)
@@ -1,9 +1,7 @@
-/* =======================================================================
- * @author: Leonardo Florez-Valencia
- * @email: florez-l@javeriana.edu.co
- * =======================================================================
- */
-
+// =======================================================================
+// @author: Leonardo Florez-Valencia
+// @email: florez-l@javeriana.edu.co
+// =======================================================================
 #ifndef __ivq__ITK__ExtractLabelFunction__hxx__
 #define __ivq__ITK__ExtractLabelFunction__hxx__
 
diff --git a/lib/ivq/ITK/Graph.h b/lib/ivq/ITK/Graph.h
new file mode 100644 (file)
index 0000000..7ea6094
--- /dev/null
@@ -0,0 +1,167 @@
+// =========================================================================
+// @author Leonardo Florez Valencia
+// @email florez-l@javeriana.edu.co
+// =========================================================================
+#ifndef __ivq__ITK__Graph__h__
+#define __ivq__ITK__Graph__h__
+
+#include <map>
+#include <set>
+#include <vector>
+#include <itkDataObject.h>
+#include <itkObjectFactory.h>
+
+namespace ivq
+{
+  namespace ITK
+  {
+    /** \brief A generic graph with templated index types.
+     *
+     *  @param _TVertex Vertex type.
+     *  @param _TCost   Cost type.
+     *  @param _TIndex  Index type (it should be a strict weak ordering type).
+     */
+    template< class _TVertex, class _TCost, class _TIndex = unsigned long, class _TIndexCompare = std::less< _TIndex > >
+    class Graph
+      : public itk::DataObject
+    {
+    public:
+      typedef Graph                           Self;
+      typedef itk::DataObject                 Superclass;
+      typedef itk::SmartPointer< Self >       Pointer;
+      typedef itk::SmartPointer< const Self > ConstPointer;
+
+      typedef _TVertex       TVertex;
+      typedef _TCost         TCost;
+      typedef _TIndex        TIndex;
+      typedef _TIndexCompare TIndexCompare;
+
+      // Base types
+      typedef std::map< TIndex, TVertex, TIndexCompare >    TVertices;
+      typedef std::vector< TCost >                          TEdges;
+      typedef std::map< TIndex, TEdges, TIndexCompare >     TMatrixRow;
+      typedef std::map< TIndex, TMatrixRow, TIndexCompare > TMatrix;
+
+    public:
+      itkNewMacro( Self );
+      itkTypeMacro( Graph, itk::DataObject );
+
+    public:
+      /*! \brief Iterators over vertices.
+       *         These allow you to iterate over all of graph's vertices.
+       *
+       * Typical iteration should be done as:
+       *
+       *  TGraph g;
+       *  ...
+       *  TGraph::TVertices::[const_]iterator vIt = g.BeginVertices( );
+       *  for( ; vIt != g.EndVertices( ); ++vIt )
+       *  {
+       *    vIt->first;  --> this is the vertex's index <--
+       *    vIt->second; --> this is the vertex's value <--
+       *  }
+       */
+      inline typename TVertices::iterator BeginVertices( )
+        { return( this->m_Vertices.begin( ) ); }
+      inline typename TVertices::iterator EndVertices( )
+        { return( this->m_Vertices.end( ) ); }
+      inline typename TVertices::const_iterator BeginVertices( ) const
+        { return( this->m_Vertices.begin( ) ); }
+      inline typename TVertices::const_iterator EndVertices( ) const
+        { return( this->m_Vertices.end( ) ); }
+
+      /*! \brief Iterators over edges.
+       *         These allow you to iterate over all of graph's edges.
+       *
+       * Typical iteration should be done as:
+       *
+       *  TGraph g;
+       *  ...
+       *  TGraph::TMatrix::[const_]iterator mIt = g.BeginEdgesRows( );
+       *  for( ; mIt != g.EndEdgesRows( ); ++mIt )
+       *  {
+       *    mIt->first; --> this is the row index. <--
+       *    TGraph::TMatrixRow::[const_]iterator rIt = mIt->second.begin( );
+       *    for( ; rIt != mIt->second.end( ); ++rIt )
+       *    {
+       *      rIt->first;  --> this is the column index.
+       *      TGraph::TEdges::[const_]iterator eIt = rIt->second.begin( );
+       *      for( ; eIt != rIt->second.end( ); ++eIt )
+       *        *eIt; --> this is the cost between mIt->first and rIt->first
+       *    }
+       *  }
+       */
+      inline typename TMatrix::iterator BeginEdgesRows( )
+        { return( this->m_Matrix.begin( ) ); }
+      inline typename TMatrix::iterator EndEdgetsRows( )
+        { return( this->m_Matrix.end( ) ); }
+      inline typename TMatrix::const_iterator BeginEdgesRows( ) const
+        { return( this->m_Matrix.begin( ) ); }
+      inline typename TMatrix::const_iterator EndEdgesRows( ) const
+        { return( this->m_Matrix.end( ) ); }
+
+      /*! \brief Clear all vertices and edges.
+       */
+      void Clear( );
+
+      /*! \brief Clear all edges.
+       */
+      inline void ClearEdges( )
+        { this->m_Matrix.clear( ); }
+
+      /*! \brief Vertex manipulation methods.
+       *         Names are self-explanatory.
+       */
+      inline bool HasVertexIndex( const TIndex& i ) const
+        { return( this->m_Vertices.find( i ) != this->m_Vertices.end( ) ); }
+      inline void SetVertex( const TIndex& index, TVertex& vertex )
+        { this->m_Vertices[ index ] = vertex; }
+      inline TVertex& GetVertex( const TIndex& index )
+        { return( this->m_Vertices[ index ] ); }
+      inline const TVertex& GetVertex( const TIndex& index ) const
+        { return( this->m_Vertices[ index ] ); }
+      bool RenameVertex( const TIndex& old_index, const TIndex& new_index );
+      void RemoveVertex( const TIndex& index );
+
+      /*! \brief Edge manipulation methods.
+       *         Names are self-explanatory.
+       */
+      inline void AddEdge( const TIndex& orig, const TIndex& dest, const TCost& cost )
+        { this->m_Matrix[ orig ][ dest ].push_back( cost ); }
+      TEdges& GetEdges( const TIndex& orig, const TIndex& dest );
+      const TEdges& GetEdges( const TIndex& orig, const TIndex& dest ) const;
+      bool HasEdge( const TIndex& orig, const TIndex& dest ) const;
+      void RemoveEdge( const TIndex& orig, const TIndex& dest, const TCost& cost );
+      void RemoveEdges( const TIndex& orig, const TIndex& dest );
+
+      /*! \brief Returns graph's sinks.
+       *
+       *  A sink is a special vertex which does not have any "exiting" edges.
+       *
+       *  @return Sinks ordered by their index.
+       */
+      std::set< TIndex, TIndexCompare > GetSinks( ) const;
+
+    protected:
+      Graph( );
+      virtual ~Graph( );
+
+    private:
+      // Purposely not implemented
+      Graph( const Self& other );
+      Self& operator=( const Self& other );
+
+    protected:
+      TVertices m_Vertices;
+      TMatrix   m_Matrix;
+    };
+
+  } // ecapseman
+
+} // ecapseman
+
+#ifndef ITK_MANUAL_INSTANTIATION
+#  include <ivq/ITK/Graph.hxx>
+#endif // ITK_MANUAL_INSTANTIATION
+#endif // __ivq__ITK__Graph__h__
+// eof - $RCSfile$
diff --git a/lib/ivq/ITK/Graph.hxx b/lib/ivq/ITK/Graph.hxx
new file mode 100644 (file)
index 0000000..4331ce0
--- /dev/null
@@ -0,0 +1,265 @@
+// =========================================================================
+// @author Leonardo Florez Valencia
+// @email florez-l@javeriana.edu.co
+// =========================================================================
+#ifndef __ivq__ITK__Graph__hxx__
+#define __ivq__ITK__Graph__hxx__
+
+// -------------------------------------------------------------------------
+template< class _TVertex, class _TCost, class _TIndex, class _TIndexCompare >
+void ivq::ITK::Graph< _TVertex, _TCost, _TIndex, _TIndexCompare >::
+Clear( )
+{
+  this->m_Vertices.clear( );
+  this->m_Matrix.clear( );
+}
+
+// -------------------------------------------------------------------------
+template< class _TVertex, class _TCost, class _TIndex, class _TIndexCompare >
+bool ivq::ITK::Graph< _TVertex, _TCost, _TIndex, _TIndexCompare >::
+RenameVertex( const TIndex& old_index, const TIndex& new_index )
+{
+  typename TVertices::iterator old_v = this->m_Vertices.find( old_index );
+  typename TVertices::iterator new_v = this->m_Vertices.find( new_index );
+  if( old_v != this->m_Vertices.end( ) && new_v == this->m_Vertices.end( ) )
+  {
+    // Replace vertex
+    this->m_Vertices[ new_index ] = old_v->second;
+    this->m_Vertices.erase( old_index );
+
+    // Duplicate edges
+    typename TMatrix::iterator mIt = this->m_Matrix.begin( );
+    typename TMatrix::iterator found_row = this->m_Matrix.end( );
+    for( ; mIt != this->m_Matrix.end( ); ++mIt )
+    {
+      if( mIt->first == old_index )
+        found_row = mIt;
+
+      typename TMatrixRow::iterator rIt = mIt->second.begin( );
+      for( ; rIt != mIt->second.end( ); ++rIt )
+      {
+        if( mIt->first == old_index )
+          this->m_Matrix[ new_index ][ rIt->first ] = rIt->second;
+        else if( rIt->first == old_index )
+          this->m_Matrix[ mIt->first ][ new_index ] = rIt->second;
+
+      } // rof
+
+    } // rof
+
+    // Delete old edges
+    if( found_row != this->m_Matrix.end( ) )
+      this->m_Matrix.erase( found_row );
+
+    mIt = this->m_Matrix.begin( );
+    for( ; mIt != this->m_Matrix.end( ); ++mIt )
+    {
+      typename TMatrixRow::iterator rIt = mIt->second.begin( );
+      while( rIt != mIt->second.end( ) )
+      {
+        if( rIt->first == old_index )
+        {
+          mIt->second.erase( rIt );
+          rIt = mIt->second.begin( );
+        }
+        else
+          ++rIt;
+
+      } // elihw
+
+    } // rof
+    return( true );
+  }
+  else
+    return( false );
+}
+
+// -------------------------------------------------------------------------
+template< class _TVertex, class _TCost, class _TIndex, class _TIndexCompare >
+void ivq::ITK::Graph< _TVertex, _TCost, _TIndex, _TIndexCompare >::
+RemoveVertex( const TIndex& index )
+{
+  typename TVertices::iterator i = this->m_Vertices.find( index );
+  if( i != this->m_Vertices.end( ) )
+  {
+    // Delete vertex
+    this->m_Vertices.erase( i );
+
+    // Delete edges starting from given vertex
+    typename TMatrix::iterator mIt = this->m_Matrix.find( index );
+    if( mIt != this->m_Matrix.end( ) )
+      this->m_Matrix.erase( mIt );
+
+    // Delete edges arriving to given vertex
+    mIt = this->m_Matrix.begin( );
+    for( ; mIt != this->m_Matrix.end( ); ++mIt )
+    {
+      typename TMatrixRow::iterator rIt = mIt->second.begin( );
+      while( rIt != mIt->second.end( ) )
+      {
+        if( rIt->first == index )
+        {
+          mIt->second.erase( rIt );
+          rIt = mIt->second.begin( );
+        }
+        else
+          ++rIt;
+
+      } // elihw
+
+    } // rof
+
+  } // fi
+}
+
+// -------------------------------------------------------------------------
+template< class _TVertex, class _TCost, class _TIndex, class _TIndexCompare >
+typename ivq::ITK::Graph< _TVertex, _TCost, _TIndex, _TIndexCompare >::
+TEdges& ivq::ITK::Graph< _TVertex, _TCost, _TIndex, _TIndexCompare >::
+GetEdges( const TIndex& orig, const TIndex& dest )
+{
+  static TEdges null_edges;
+  typename TMatrix::iterator o = this->m_Matrix.find( orig );
+  if( o != this->m_Matrix.find( orig ) )
+  {
+    typename TMatrixRow::iterator d = o->second.find( dest );
+    if( d == o->second.end( ) )
+    {
+      null_edges.clear( );
+      return( null_edges );
+    }
+    else
+      return( d->second );
+  }
+  else
+  {
+    null_edges.clear( );
+    return( null_edges );
+
+  } // fi
+}
+
+// -------------------------------------------------------------------------
+template< class _TVertex, class _TCost, class _TIndex, class _TIndexCompare >
+const typename ivq::ITK::Graph< _TVertex, _TCost, _TIndex, _TIndexCompare >::
+TEdges& ivq::ITK::Graph< _TVertex, _TCost, _TIndex, _TIndexCompare >::
+GetEdges( const TIndex& orig, const TIndex& dest ) const
+{
+  static const TEdges null_edges;
+  typename TMatrix::iterator o = this->m_Matrix.find( orig );
+  if( o != this->m_Matrix.find( orig ) )
+  {
+    typename TMatrixRow::iterator d = o->second.find( dest );
+    if( d == o->second.end( ) )
+      return( null_edges );
+    else
+      return( d->second );
+  }
+  else
+    return( null_edges );
+}
+
+// -------------------------------------------------------------------------
+template< class _TVertex, class _TCost, class _TIndex, class _TIndexCompare >
+bool ivq::ITK::Graph< _TVertex, _TCost, _TIndex, _TIndexCompare >::
+HasEdge( const TIndex& orig, const TIndex& dest ) const
+{
+  typename TMatrix::const_iterator mIt = this->m_Matrix.find( orig );
+  if( mIt != this->m_Matrix.end( ) )
+    return( mIt->second.find( dest ) != mIt->second.end( ) );
+  else
+    return( false );
+}
+
+// -------------------------------------------------------------------------
+template< class _TVertex, class _TCost, class _TIndex, class _TIndexCompare >
+void ivq::ITK::Graph< _TVertex, _TCost, _TIndex, _TIndexCompare >::
+RemoveEdge( const TIndex& orig, const TIndex& dest, const TCost& cost )
+{
+  typename TMatrix::iterator m = this->m_Matrix.find( orig );
+  if( m != this->m_Matrix.end( ) )
+  {
+    typename TMatrixRow::iterator r = m->second.find( dest );
+    if( r != m->second.end( ) )
+    {
+      typename TEdges::iterator e = r->second.end( );
+      for(
+        typename TEdges::iterator i = r->second.begin( );
+        i != r->second.end( ) && e == r->second.end( );
+        ++i
+        )
+        if( *i == cost )
+          e = i;
+      if( e != r->second.end( ) )
+      {
+        r->second.erase( e );
+        if( r->second.size( ) == 0 )
+        {
+          m->second.erase( r );
+          if( m->second.size( ) == 0 )
+            this->m_Matrix.erase( m );
+
+        } // fi
+
+      } // fi
+
+    } // fi
+
+  } // fi
+}
+
+// -------------------------------------------------------------------------
+template< class _TVertex, class _TCost, class _TIndex, class _TIndexCompare >
+void ivq::ITK::Graph< _TVertex, _TCost, _TIndex, _TIndexCompare >::
+RemoveEdges( const TIndex& orig, const TIndex& dest )
+{
+  typename TMatrix::iterator m = this->m_Matrix.find( orig );
+  if( m != this->m_Matrix.end( ) )
+  {
+    typename TMatrixRow::iterator r = m->second.find( dest );
+    if( r != m->second.end( ) )
+    {
+      m->second.erase( r );
+      if( m->second.size( ) == 0 )
+        this->m_Matrix.erase( m );
+
+    } // fi
+
+  } // fi
+}
+
+// -------------------------------------------------------------------------
+template< class _TVertex, class _TCost, class _TIndex, class _TIndexCompare >
+std::set< _TIndex, _TIndexCompare >
+ivq::ITK::Graph< _TVertex, _TCost, _TIndex, _TIndexCompare >::
+GetSinks( ) const
+{
+  std::set< _TIndex, _TIndexCompare > sinks;
+
+  typename TVertices::iterator vIt = this->m_Vertices.begin( );
+  for( ; vIt != this->m_Vertices.end( ); ++vIt )
+    sinks.insert( vIt->first );
+  typename TMatrix::iterator mIt = this->m_Matrix.begin( );
+  for( ; mIt != this->m_Matrix.end( ); ++mIt )
+    sinks.erase( mIt->first );
+
+  return( sinks );
+}
+
+// -------------------------------------------------------------------------
+template< class _TVertex, class _TCost, class _TIndex, class _TIndexCompare >
+ivq::ITK::Graph< _TVertex, _TCost, _TIndex, _TIndexCompare >::
+Graph( )
+  : Superclass( )
+{
+}
+
+// -------------------------------------------------------------------------
+template< class _TVertex, class _TCost, class _TIndex, class _TIndexCompare >
+ivq::ITK::Graph< _TVertex, _TCost, _TIndex, _TIndexCompare >::
+~Graph( )
+{
+}
+
+#endif // __ivq__ITK__Graph__hxx__
+// eof - $RCSfile$
diff --git a/lib/ivq/ITK/ImageMinimumSpanningTree.h b/lib/ivq/ITK/ImageMinimumSpanningTree.h
new file mode 100644 (file)
index 0000000..6e18212
--- /dev/null
@@ -0,0 +1,72 @@
+// =========================================================================
+// @author Leonardo Florez Valencia
+// @email florez-l@javeriana.edu.co
+// =========================================================================
+#ifndef __ivq__ITK__ImageMinimumSpanningTree__h__
+#define __ivq__ITK__ImageMinimumSpanningTree__h__
+
+#include <itkImage.h>
+#include <ivq/ITK/MinimumSpanningTree.h>
+#include <ivq/ITK/ImagePath.h>
+
+namespace ivq
+{
+  namespace ITK
+  {
+    /**
+     */
+    template< unsigned int _VDim >
+    class ImageMinimumSpanningTree
+      : public ivq::ITK::MinimumSpanningTree< itk::Index< _VDim >, itk::Image< itk::Offset< _VDim >, _VDim > >
+    {
+    public:
+      typedef itk::Index< _VDim > TVertex;
+      typedef itk::Image< itk::Offset< _VDim >, _VDim > TITKImage;
+
+      typedef ImageMinimumSpanningTree                                  Self;
+      typedef itk::SmartPointer< Self >                              Pointer;
+      typedef itk::SmartPointer< const Self >                   ConstPointer;
+      typedef ivq::ITK::MinimumSpanningTree< TVertex, TITKImage > Superclass;
+
+      typedef typename Superclass::TCollision     TCollision;
+      typedef typename Superclass::TCollisionsRow TCollisionsRow;
+      typedef typename Superclass::TCollisions    TCollisions;
+      typedef typename Superclass::TVertices      TVertices;
+
+      typedef ivq::ITK::ImagePath< _VDim > TPath;
+
+    public:
+      itkNewMacro( Self );
+      itkTypeMacro(
+        ivq::ITK::ImageMinimumSpanningTree,
+        ivq::ITK::MinimumSpanningTree
+        );
+
+    public:
+      virtual TVertex GetParent( const TVertex& v ) const override;
+      virtual void SetParent( const TVertex& v, const TVertex& p ) override;
+
+      void GetPath( typename TPath::Pointer& path, const TVertex& a ) const;
+      void GetPath(
+        typename TPath::Pointer& path,
+        const TVertex& a, const TVertex& b
+        ) const;
+
+    protected:
+      ImageMinimumSpanningTree( );
+      virtual ~ImageMinimumSpanningTree( );
+
+    private:
+      MinimumSpanningTree( const Self& other );
+      Self& operator=( const Self& other );
+    };
+
+  } // ecapseman
+
+} // ecapseman
+
+#ifndef ITK_MANUAL_INSTANTIATION
+#  include <ivq/ITK/Image/MinimumSpanningTree.hxx>
+#endif // ITK_MANUAL_INSTANTIATION
+#endif // __ivq__ITK__ImageMinimumSpanningTree__h__
+// eof - $RCSfile$
diff --git a/lib/ivq/ITK/ImageMinimumSpanningTree.hxx b/lib/ivq/ITK/ImageMinimumSpanningTree.hxx
new file mode 100644 (file)
index 0000000..23b5c31
--- /dev/null
@@ -0,0 +1,71 @@
+// =========================================================================
+// @author Leonardo Florez Valencia
+// @email florez-l@javeriana.edu.co
+// =========================================================================
+#ifndef __ivq__ITK__ImageMinimumSpanningTree__hxx__
+#define __ivq__ITK__ImageMinimumSpanningTree__hxx__
+
+// -------------------------------------------------------------------------
+template< unsigned int _VDim >
+typename ivq::ITK::ImageMinimumSpanningTree< _VDim >::
+TVertex ivq::ITK::ImageMinimumSpanningTree< _VDim >::
+GetParent( const TVertex& v ) const
+{
+  return( v + this->GetPixel( v ) );
+}
+
+// -------------------------------------------------------------------------
+template< unsigned int _VDim >
+void ivq::ITK::ImageMinimumSpanningTree< _VDim >::
+SetParent( const TVertex& v, const TVertex& p )
+{
+  this->SetPixel( v, p - v );
+}
+
+// -------------------------------------------------------------------------
+template< unsigned int _VDim >
+void ivq::ITK::ImageMinimumSpanningTree< _VDim >::
+GetPath( typename TPath::Pointer& path, const TVertex& a ) const
+{
+  TVertices v = this->GetAxis( a );
+  if( path.IsNull( ) )
+    path = TPath::New( );
+  path->SetReferenceImage( this );
+  typename TVertices::const_iterator vIt = v.begin( );
+  for( ; vIt != v.end( ); ++vIt )
+    path->AddVertex( *vIt );
+}
+
+// -------------------------------------------------------------------------
+template< unsigned int _VDim >
+void ivq::ITK::ImageMinimumSpanningTree< _VDim >::
+GetPath(
+  typename TPath::Pointer& path, const TVertex& a, const TVertex& b
+  ) const
+{
+  TVertices v = this->GetAxis( a, b );
+  if( path.IsNull( ) )
+    path = TPath::New( );
+  path->SetReferenceImage( this );
+  typename TVertices::const_iterator vIt = v.begin( );
+  for( ; vIt != v.end( ); ++vIt )
+    path->AddVertex( *vIt );
+}
+
+// -------------------------------------------------------------------------
+template< unsigned int _VDim >
+ivq::ITK::ImageMinimumSpanningTree< _VDim >::
+ImageMinimumSpanningTree( )
+  : Superclass( )
+{
+}
+
+// -------------------------------------------------------------------------
+template< unsigned int _VDim >
+ivq::ITK::ImageMinimumSpanningTree< _VDim >::
+~ImageMinimumSpanningTree( )
+{
+}
+
+#endif // __ivq__ITK__ImageMinimumSpanningTree__hxx__
+// eof - $RCSfile$
diff --git a/lib/ivq/ITK/ImagePath.h b/lib/ivq/ITK/ImagePath.h
new file mode 100644 (file)
index 0000000..d5318f5
--- /dev/null
@@ -0,0 +1,92 @@
+// =========================================================================
+// @author Leonardo Florez Valencia
+// @email florez-l@javeriana.edu.co
+// =========================================================================
+#ifndef __ivq__ITK__ImagePath__h__
+#define __ivq__ITK__ImagePath__h__
+
+#include <itkPolyLineParametricPath.h>
+#include <itkImageBase.h>
+
+namespace ivq
+{
+  namespace ITK
+  {
+    /**
+     */
+    template< unsigned int _VDim >
+    class ImagePath
+      : public itk::PolyLineParametricPath< _VDim >
+    {
+    public:
+      typedef ImagePath                            Self;
+      typedef itk::PolyLineParametricPath< _VDim > Superclass;
+      typedef itk::SmartPointer< Self >            Pointer;
+      typedef itk::SmartPointer< const Self >      ConstPointer;
+
+      itkStaticConstMacro( Dimension, unsigned int, _VDim );
+
+      typedef itk::ImageBase< _VDim >                  TImageBase;
+      typedef typename TImageBase::SpacingType         TSpacing;
+      typedef typename TImageBase::PointType           TPoint;
+      typedef typename TImageBase::DirectionType       TDirection;
+      typedef typename Superclass::ContinuousIndexType TContinuousIndex;
+      typedef typename TContinuousIndex::IndexType     TIndex;
+
+    public:
+      itkNewMacro( Self );
+      itkTypeMacro( ImagePath, itk::PolyLineParametricPath );
+
+      itkGetConstReferenceMacro( Spacing, TSpacing );
+      itkGetConstReferenceMacro( Origin, TPoint );
+      itkGetConstReferenceMacro( Direction, TDirection );
+      itkGetConstReferenceMacro( InverseDirection, TDirection );
+
+      itkSetMacro( Origin, TPoint );
+
+    public:
+      unsigned long GetSize( ) const;
+      TContinuousIndex GetContinuousVertex( unsigned long i ) const;
+      TIndex GetVertex( unsigned long i ) const;
+      TPoint GetPoint( unsigned long i ) const;
+
+      virtual void SetSpacing( const TSpacing& spac );
+      virtual void SetSpacing( const double spac[ _VDim ] );
+      virtual void SetSpacing( const float spac[ _VDim ] );
+      virtual void SetOrigin( const double ori[ _VDim ] );
+      virtual void SetOrigin( const float ori[ _VDim ] );
+      virtual void SetDirection( const TDirection& dir );
+      virtual void SetReferenceImage( const TImageBase* image );
+
+      virtual void Graft( itk::DataObject* o );
+
+    protected:
+      ImagePath( );
+      virtual ~ImagePath( );
+
+      virtual void _ComputeIndexToPhysicalPointMatrices( );
+
+    private:
+      // Purposely not implemented
+      ImagePath( const Self& other );
+      Self& operator=( const Self& other );
+
+    protected:
+      TSpacing   m_Spacing;
+      TPoint     m_Origin;
+      TDirection m_Direction;
+      TDirection m_InverseDirection;
+      TDirection m_IndexToPhysicalPoint;
+      TDirection m_PhysicalPointToIndex;
+    };
+
+  } // ecapseman
+
+} // ecapseman
+
+#ifndef ITK_MANUAL_INSTANTIATION
+#  include <ivq/ITK/Image/Path.hxx>
+#endif // ITK_MANUAL_INSTANTIATION
+#endif // __ivq__ITK__ImagePath__h__
+
+// eof - $RCSfile$
diff --git a/lib/ivq/ITK/ImagePath.hxx b/lib/ivq/ITK/ImagePath.hxx
new file mode 100644 (file)
index 0000000..81ac1d6
--- /dev/null
@@ -0,0 +1,224 @@
+// =========================================================================
+// @author Leonardo Florez Valencia
+// @email florez-l@javeriana.edu.co
+// =========================================================================
+#ifndef __ivq__ITK__ImagePath__hxx__
+#define __ivq__ITK__ImagePath__hxx__
+
+#include <itkMath.h>
+#include <itkNumericTraits.h>
+
+// -------------------------------------------------------------------------
+template< unsigned int _VDim >
+unsigned long ivq::ITK::ImagePath< _VDim >::
+GetSize( ) const
+{
+  return( this->GetVertexList( )->Size( ) );
+}
+
+// -------------------------------------------------------------------------
+template< unsigned int _VDim >
+typename ivq::ITK::ImagePath< _VDim >::
+TContinuousIndex ivq::ITK::ImagePath< _VDim >::
+GetContinuousVertex( unsigned long i ) const
+{
+  return( this->GetVertexList( )->GetElement( i ) );
+}
+
+// -------------------------------------------------------------------------
+template< unsigned int _VDim >
+typename ivq::ITK::ImagePath< _VDim >::
+TIndex ivq::ITK::ImagePath< _VDim >::
+GetVertex( unsigned long i ) const
+{
+  TContinuousIndex cidx = this->GetContinuousVertex( i );
+  TIndex idx;
+  for( unsigned int d = 0; d < _VDim; ++d )
+    idx[ d ] = cidx[ d ];
+  return( idx );
+}
+
+// -------------------------------------------------------------------------
+template< unsigned int _VDim >
+typename ivq::ITK::ImagePath< _VDim >::
+TPoint ivq::ITK::ImagePath< _VDim >::
+GetPoint( unsigned long i ) const
+{
+  typedef typename TPoint::CoordRepType _TCoordRep;
+  TPoint pnt;
+  TContinuousIndex idx = this->GetVertex( i );
+  for( unsigned int r = 0; r < _VDim; ++r )
+  {
+    _TCoordRep sum = itk::NumericTraits< _TCoordRep >::ZeroValue( );
+    for( unsigned int c = 0; c < _VDim; ++c )
+      sum += this->m_IndexToPhysicalPoint( r, c ) * idx[ c ];
+    pnt[ r ] = sum + this->m_Origin[ r ];
+
+  } // rof
+  return( pnt );
+}
+
+// -------------------------------------------------------------------------
+template< unsigned int _VDim >
+void ivq::ITK::ImagePath< _VDim >::
+SetSpacing( const TSpacing& spac )
+{
+  if( this->m_Spacing != spac )
+  {
+    this->m_Spacing = spac;
+    this->_ComputeIndexToPhysicalPointMatrices( );
+    this->Modified( );
+
+  } // fi
+}
+
+// -------------------------------------------------------------------------
+template< unsigned int _VDim >
+void ivq::ITK::ImagePath< _VDim >::
+SetSpacing( const double spac[ _VDim ] )
+{
+  this->SetSpacing( TSpacing( spac ) );
+}
+
+// -------------------------------------------------------------------------
+template< unsigned int _VDim >
+void ivq::ITK::ImagePath< _VDim >::
+SetSpacing( const float spac[ _VDim ] )
+{
+  TSpacing s;
+  for( unsigned int d = 0; d < _VDim; ++d )
+    s[ d ] = spac[ d ];
+  this->SetSpacing( s );
+}
+
+// -------------------------------------------------------------------------
+template< unsigned int _VDim >
+void ivq::ITK::ImagePath< _VDim >::
+SetOrigin( const double ori[ _VDim ] )
+{
+  this->SetOrigin( TPoint( ori ) );
+}
+
+// -------------------------------------------------------------------------
+template< unsigned int _VDim >
+void ivq::ITK::ImagePath< _VDim >::
+SetOrigin( const float ori[ _VDim ] )
+{
+  this->SetOrigin( TPoint( ori ) );
+}
+
+// -------------------------------------------------------------------------
+template< unsigned int _VDim >
+void ivq::ITK::ImagePath< _VDim >::
+SetDirection( const TDirection& dir )
+{
+  bool modified = false;
+  for( unsigned int r = 0; r < _VDim; r++ )
+  {
+    for( unsigned int c = 0; c < _VDim; c++ )
+    {
+      if(
+        itk::Math::NotExactlyEquals(
+          this->m_Direction[ r ][ c ], dir[ r ][ c ]
+          )
+        )
+      {
+        this->m_Direction[ r ][ c ] = dir[ r ][ c ];
+        modified = true;
+      } // fi
+
+    } // rof
+
+  } // rof
+  if( modified )
+  {
+    this->_ComputeIndexToPhysicalPointMatrices( );
+    this->m_InverseDirection = this->m_Direction.GetInverse( );
+    this->Modified( );
+
+  } // fi
+}
+
+// -------------------------------------------------------------------------
+template< unsigned int _VDim >
+void ivq::ITK::ImagePath< _VDim >::
+SetReferenceImage( const TImageBase* image )
+{
+  this->SetSpacing( image->GetSpacing( ) );
+  this->SetOrigin( image->GetOrigin( ) );
+  this->SetDirection( image->GetDirection( ) );
+}
+
+// -------------------------------------------------------------------------
+template< unsigned int _VDim >
+void ivq::ITK::ImagePath< _VDim >::
+Graft( itk::DataObject* o )
+{
+  this->Superclass::Graft( o );
+  Self* other = dynamic_cast< Self* >( o );
+  if( other != NULL )
+  {
+    this->m_DefaultInputStepSize = other->m_DefaultInputStepSize;
+    this->Initialize( );
+    for( unsigned long i = 0; i < other->GetSize( ); ++i )
+      this->AddVertex( other->GetContinuousVertex( i ) );
+    this->m_Spacing = other->m_Spacing;
+    this->m_Origin = other->m_Origin;
+    this->m_Direction = other->m_Direction;
+    this->m_InverseDirection = other->m_InverseDirection;
+    this->m_IndexToPhysicalPoint = other->m_IndexToPhysicalPoint;
+    this->m_PhysicalPointToIndex = other->m_PhysicalPointToIndex;
+
+  } // fi
+}
+
+// -------------------------------------------------------------------------
+template< unsigned int _VDim >
+ivq::ITK::ImagePath< _VDim >::
+ImagePath( )
+  : Superclass( )
+{
+  this->m_Spacing.Fill( 1.0 );
+  this->m_Origin.Fill( 0.0 );
+  this->m_Direction.SetIdentity( );
+  this->m_InverseDirection.SetIdentity( );
+  this->m_IndexToPhysicalPoint.SetIdentity( );
+  this->m_PhysicalPointToIndex.SetIdentity( );
+}
+
+// -------------------------------------------------------------------------
+template< unsigned int _VDim >
+ivq::ITK::ImagePath< _VDim >::
+~ImagePath( )
+{
+}
+
+// -------------------------------------------------------------------------
+template< unsigned int _VDim >
+void ivq::ITK::ImagePath< _VDim >::
+_ComputeIndexToPhysicalPointMatrices( )
+{
+  TDirection scale;
+  scale.Fill( 0.0 );
+  for( unsigned int i = 0; i < _VDim; i++ )
+  {
+    if( this->m_Spacing[ i ] == 0.0 )
+      itkExceptionMacro(
+        "A spacing of 0 is not allowed: Spacing is " << this->m_Spacing
+        );
+    scale[ i ][ i ] = this->m_Spacing[ i ];
+
+  } // rof
+
+  if( vnl_determinant( this->m_Direction.GetVnlMatrix( ) ) == 0.0 )
+    itkExceptionMacro(
+      << "Bad direction, determinant is 0. Direction is "
+      << this->m_Direction
+      );
+  this->m_IndexToPhysicalPoint = this->m_Direction * scale;
+  this->m_PhysicalPointToIndex = this->m_IndexToPhysicalPoint.GetInverse( );
+  this->Modified( );
+}
+
+#endif // __ivq__ITK__ImagePath__hxx__
+// eof - $RCSfile$
diff --git a/lib/ivq/ITK/ImagePathReader.h b/lib/ivq/ITK/ImagePathReader.h
new file mode 100644 (file)
index 0000000..af3575d
--- /dev/null
@@ -0,0 +1,81 @@
+// =========================================================================
+// @author Leonardo Florez Valencia
+// @email florez-l@javeriana.edu.co
+// =========================================================================
+#ifndef __ivq__ITK__ImagePathReader__h__
+#define __ivq__ITK__ImagePathReader__h__
+
+#include <itkProcessObject.h>
+
+namespace ivq
+{
+  namespace ITK
+  {
+    /**
+     */
+    template< class _TPath >
+    class ImagePathReader
+      : public itk::ProcessObject
+    {
+    public:
+      // Basic types
+      typedef ImagePathReader                 Self;
+      typedef itk::ProcessObject              Superclass;
+      typedef itk::SmartPointer< Self >       Pointer;
+      typedef itk::SmartPointer< const Self > ConstPointer;
+
+      typedef _TPath TPath;
+
+    public:
+      itkNewMacro( Self );
+      itkTypeMacro( ImagePathReader, itk::ProcessObject );
+
+      itkGetConstMacro( FileName, std::string );
+      itkSetMacro( FileName, std::string );
+
+    public:
+      TPath* GetOutput( );
+      TPath* GetOutput( unsigned int i );
+
+      virtual void GraftOutput( itk::DataObject* out );
+      virtual void GraftOutput(
+        const typename Superclass::DataObjectIdentifierType& key,
+        itk::DataObject* out
+        );
+      virtual void GraftNthOutput( unsigned int i, itk::DataObject* out );
+      virtual itk::DataObject::Pointer MakeOutput(
+        itk::ProcessObject::DataObjectPointerArraySizeType i
+        ) override;
+
+      virtual void Update( ) override
+        { this->GenerateData( ); }
+
+    protected:
+      ImagePathReader( );
+      virtual ~ImagePathReader( );
+
+      virtual void GenerateData( ) override;
+
+      // Do nothing
+      virtual void GenerateOutputInformation( ) override
+        { }
+
+    private:
+      // Purposely not implemented
+      ImagePathReader( const Self& );
+      void operator=( const Self& );
+
+    protected:
+      std::string m_FileName;
+    };
+
+  } // ecapseman
+
+} // ecapseman
+
+#ifndef ITK_MANUAL_INSTANTIATION
+#  include <ivq/ITK/ImagePathReader.hxx>
+#endif // ITK_MANUAL_INSTANTIATION
+#endif // __ivq__ITK__ImagePathReader__h__
+
+// eof - $RCSfile$
diff --git a/lib/ivq/ITK/ImagePathReader.hxx b/lib/ivq/ITK/ImagePathReader.hxx
new file mode 100644 (file)
index 0000000..43d0f69
--- /dev/null
@@ -0,0 +1,172 @@
+// =========================================================================
+// @author Leonardo Florez Valencia
+// @email florez-l@javeriana.edu.co
+// =========================================================================
+#ifndef __ivq__ITK__ImagePathReader__hxx__
+#define __ivq__ITK__ImagePathReader__hxx__
+
+// -------------------------------------------------------------------------
+template< class _TPath >
+_TPath* ivq::ITK::ImagePathReader< _TPath >::
+GetOutput( )
+{
+  return(
+    itkDynamicCastInDebugMode< TPath* >( this->GetPrimaryOutput( ) )
+    );
+}
+
+// -------------------------------------------------------------------------
+template< class _TPath >
+_TPath* ivq::ITK::ImagePathReader< _TPath >::
+GetOutput( unsigned int i )
+{
+  return(
+    itkDynamicCastInDebugMode< TPath* >(
+      this->itk::ProcessObject::GetOutput( i )
+      )
+    );
+}
+
+// -------------------------------------------------------------------------
+template< class _TPath >
+void ivq::ITK::ImagePathReader< _TPath >::
+GraftOutput( itk::DataObject* out )
+{
+  this->GraftNthOutput( 0, out );
+}
+
+// -------------------------------------------------------------------------
+template< class _TPath >
+void ivq::ITK::ImagePathReader< _TPath >::
+GraftOutput(
+  const typename Superclass::DataObjectIdentifierType& key,
+  itk::DataObject* out
+  )
+{
+  if( out == NULL )
+  {
+    itkExceptionMacro(
+      << "Requested to graft output that is a NULL pointer"
+      );
+
+  } // fi
+  itk::DataObject* output = this->itk::ProcessObject::GetOutput( key );
+  output->Graft( out );
+}
+
+// -------------------------------------------------------------------------
+template< class _TPath >
+void ivq::ITK::ImagePathReader< _TPath >::
+GraftNthOutput( unsigned int i, itk::DataObject* out )
+{
+  if( i >= this->GetNumberOfIndexedOutputs( ) )
+  {
+    itkExceptionMacro(
+      << "Requested to graft output " << i
+      << " but this filter only has "
+      << this->GetNumberOfIndexedOutputs( )
+      << " indexed Outputs."
+      );
+
+  } // fi
+  this->GraftOutput( this->MakeNameFromOutputIndex( i ), out );
+}
+
+// -------------------------------------------------------------------------
+template< class _TPath >
+itk::DataObject::Pointer ivq::ITK::ImagePathReader< _TPath >::
+MakeOutput( itk::ProcessObject::DataObjectPointerArraySizeType i )
+{
+  return( TPath::New( ).GetPointer( ) );
+}
+
+// -------------------------------------------------------------------------
+template< class _TPath >
+ivq::ITK::ImagePathReader< _TPath >::
+PathReader( )
+  : Superclass( )
+{
+  typename TPath::Pointer out =
+    static_cast< TPath* >( this->MakeOutput( 0 ).GetPointer( ) );
+  this->itk::ProcessObject::SetNumberOfRequiredInputs( 0 );
+  this->itk::ProcessObject::SetNumberOfRequiredOutputs( 1 );
+  this->itk::ProcessObject::SetNthOutput( 0, out.GetPointer( ) );
+}
+
+// -------------------------------------------------------------------------
+template< class _TPath >
+ivq::ITK::ImagePathReader< _TPath >::
+~PathReader( )
+{
+}
+
+// -------------------------------------------------------------------------
+template< class _TPath >
+void ivq::ITK::ImagePathReader< _TPath >::
+GenerateData( )
+{
+  std::string buffer;
+  std::ifstream file_stream( this->m_FileName.c_str( ) );
+  if( !file_stream )
+  {
+    itkExceptionMacro(
+      << "Error reading skeleton from \"" << this->m_FileName << "\""
+      );
+    return;
+
+  } // fi
+  file_stream.seekg( 0, std::ios::end );
+  buffer.reserve( ( unsigned int )( file_stream.tellg( ) ) );
+  file_stream.seekg( 0, std::ios::beg );
+  buffer.assign(
+    ( std::istreambuf_iterator< char >( file_stream ) ),
+    std::istreambuf_iterator< char >( )
+    );
+  file_stream.close( );
+
+  std::istringstream in( buffer );
+  unsigned int dim;
+  in >> dim;
+  if( dim != TPath::Dimension )
+  {
+    itkExceptionMacro(
+      << "Mismatched path dimension: " << dim
+      << " != " << TPath::Dimension
+      );
+    return;
+
+  } // fi
+
+  // Read spatial parameters
+  typename TPath::TSpacing spa;
+  typename TPath::TDirection dir;
+  typename TPath::TPoint ori;
+  for( unsigned int d = 0; d < dim; ++d )
+    in >> spa[ d ];
+  for( unsigned int d = 0; d < dim; ++d )
+    for( unsigned int e = 0; e < dim; ++e )
+      in >> dir[ d ][ e ];
+  for( unsigned int d = 0; d < dim; ++d )
+    in >> ori[ d ];
+
+  // Read path
+  TPath* path = this->GetOutput( );
+  path->SetSpacing( spa );
+  path->SetOrigin( ori );
+  path->SetDirection( dir );
+
+  unsigned long pathSize;
+  in >> pathSize;
+  for( unsigned long id = 0; id < pathSize; ++id )
+  {
+    typename TPath::TIndex idx;
+    for( unsigned int d = 0; d < dim; ++d )
+      in >> idx[ d ];
+    path->AddVertex( idx );
+
+  } // rof
+}
+
+#endif // __ivq__ITK__ImagePathReader__hxx__
+
+// eof - $RCSfile$
diff --git a/lib/ivq/ITK/ImagePathWriter.h b/lib/ivq/ITK/ImagePathWriter.h
new file mode 100644 (file)
index 0000000..20e5bdd
--- /dev/null
@@ -0,0 +1,65 @@
+// =========================================================================
+// @author Leonardo Florez Valencia
+// @email florez-l@javeriana.edu.co
+// =========================================================================
+#ifndef __ivq__ITK__ImagePathWriter__h__
+#define __ivq__ITK__ImagePathWriter__h__
+
+#include <itkProcessObject.h>
+#include <ivq/Config.h>
+
+namespace ivq
+{
+  namespace ITK
+  {
+    /**
+     */
+    template< class _TPath >
+    class ImagePathWriter
+      : public itk::ProcessObject
+    {
+    public:
+      // Basic types
+      typedef ImagePathWriter                 Self;
+      typedef itk::ProcessObject              Superclass;
+      typedef itk::SmartPointer< Self >       Pointer;
+      typedef itk::SmartPointer< const Self > ConstPointer;
+
+      typedef _TPath TPath;
+
+    public:
+      itkNewMacro( Self );
+      itkTypeMacro( ImagePathWriter, itk::ProcessObject );
+
+      itkGetConstMacro( FileName, std::string );
+      itkSetMacro( FileName, std::string );
+
+      ivqITKInputMacro( Input, TPath );
+
+    public:
+      virtual void Update( ) override;
+
+    protected:
+      ImagePathWriter( );
+      virtual ~ImagePathWriter( );
+
+      virtual void GenerateData( ) override;
+
+    private:
+      // Purposely not implemented
+      ImagePathWriter( const Self& );
+      void operator=( const Self& );
+
+    protected:
+      std::string m_FileName;
+    };
+
+  } // ecapseman
+
+} // ecapseman
+
+#ifndef ITK_MANUAL_INSTANTIATION
+#  include <ivq/ITK/ImagePathWriter.hxx>
+#endif // ITK_MANUAL_INSTANTIATION
+#endif // __ivq__ITK__ImagePathWriter__h__
+// eof - $RCSfile$
diff --git a/lib/ivq/ITK/ImagePathWriter.hxx b/lib/ivq/ITK/ImagePathWriter.hxx
new file mode 100644 (file)
index 0000000..af5b3c6
--- /dev/null
@@ -0,0 +1,91 @@
+// =========================================================================
+// @author Leonardo Florez Valencia
+// @email florez-l@javeriana.edu.co
+// =========================================================================
+#ifndef __ivq__ITK__ImagePathWriter__hxx__
+#define __ivq__ITK__ImagePathWriter__hxx__
+
+#include <fstream>
+
+// -------------------------------------------------------------------------
+template< class _TPath >
+void ivq::ITK::ImagePathWriter< _TPath >::
+Update( )
+{
+  TPath* input = const_cast< TPath* >( this->GetInput( ) );
+  if( input != NULL )
+  {
+    input->UpdateOutputInformation( );
+    input->UpdateOutputData( );
+    this->GenerateData( );
+    this->ReleaseInputs( );
+
+  } // fi
+}
+
+// -------------------------------------------------------------------------
+template< class _TPath >
+ivq::ITK::ImagePathWriter< _TPath >::
+ImagePathWriter( )
+  : Superclass( ),
+    m_FileName( "" )
+{
+  ivqITKInputConfigureMacro( Input, TPath );
+}
+
+// -------------------------------------------------------------------------
+template< class _TPath >
+ivq::ITK::ImagePathWriter< _TPath >::
+~ImagePathWriter( )
+{
+}
+
+// -------------------------------------------------------------------------
+template< class _TPath >
+void ivq::ITK::ImagePathWriter< _TPath >::
+GenerateData( )
+{
+  const TPath* path = this->GetInput( );
+
+  // Write base information
+  std::stringstream out1, out2;
+  out1 << TPath::Dimension << std::endl;
+  typename TPath::TSpacing spa = path->GetSpacing( );
+  for( unsigned int d = 0; d < TPath::Dimension; ++d )
+    out1 << spa[ d ] << " ";
+  out1 << std::endl;
+  typename TPath::TDirection dir = path->GetDirection( );
+  for( unsigned int d = 0; d < TPath::Dimension; ++d )
+    for( unsigned int e = 0; e < TPath::Dimension; ++e )
+      out1 << dir[ d ][ e ] << " ";
+  out1 << std::endl;
+  typename TPath::TPoint ori = path->GetOrigin( );
+  for( unsigned int d = 0; d < TPath::Dimension; ++d )
+    out1 << ori[ d ] << " ";
+  out1 << std::endl;
+
+  // Write path
+  unsigned int size = path->GetSize( );
+  out2 << size << std::endl;
+  for( unsigned int i = 0; i < path->GetSize( ); ++i )
+  {
+    typename TPath::TIndex v = path->GetVertex( i );
+    for( unsigned int d = 0; d < TPath::Dimension; ++d )
+      out2 << v[ d ] << " ";
+
+  } // rof
+
+  // Real write
+  std::ofstream file_stream( this->m_FileName.c_str( ), std::ofstream::binary );
+  if( !file_stream )
+    itkExceptionMacro(
+      << "Unable to write skeleton to \""
+      << this->m_FileName
+      << "\""
+      );
+  file_stream.write( out1.str( ).c_str( ), out1.str( ).size( ) );
+}
+
+#endif // __ivq__ITK__ImagePathWriter__hxx__
+
+// eof - $RCSfile$
index 6aef0f96edeca3c1747632aa61539200a683a00e..3a50e64f2336cb7142417af8d9f7fb3c7075eec7 100644 (file)
@@ -1,9 +1,7 @@
-/* =======================================================================
- * @author: Leonardo Florez-Valencia
- * @email: florez-l@javeriana.edu.co
- * =======================================================================
- */
-
+// =======================================================================
+// @author: Leonardo Florez-Valencia
+// @email: florez-l@javeriana.edu.co
+// =======================================================================
 #ifndef __ivq__ITK__ImageROIFromFunction__h__
 #define __ivq__ITK__ImageROIFromFunction__h__
 
@@ -77,7 +75,6 @@ namespace ivq
 #ifndef ITK_MANUAL_INSTANTIATION
 #  include <ivq/ITK/ImageROIFromFunction.hxx>
 #endif // ITK_MANUAL_INSTANTIATION
-
 #endif // __ivq__ITK__ImageROIFromFunction__h__
 
 // eof - $RCSfile$
index d7ba4e3677186397d01cf0e30f4ef18f22f71213..6c01510afa777d00f61bab00a20c8bde06eb269a 100644 (file)
@@ -1,9 +1,7 @@
-/* =======================================================================
- * @author: Leonardo Florez-Valencia
- * @email: florez-l@javeriana.edu.co
- * =======================================================================
- */
-
+// =======================================================================
+// @author: Leonardo Florez-Valencia
+// @email: florez-l@javeriana.edu.co
+// =======================================================================
 #ifndef __ivq__ITK__ImageROIFromFunction__hxx__
 #define __ivq__ITK__ImageROIFromFunction__hxx__
 
diff --git a/lib/ivq/ITK/ImageSkeleton.h b/lib/ivq/ITK/ImageSkeleton.h
new file mode 100644 (file)
index 0000000..e479df6
--- /dev/null
@@ -0,0 +1,65 @@
+// =========================================================================
+// @author Leonardo Florez Valencia
+// @email florez-l@javeriana.edu.co
+// =========================================================================
+#ifndef __ivq__ITK__ImageSkeleton__h__
+#define __ivq__ITK__ImageSkeleton__h__
+
+#include <vector>
+#include <ivq/ITK/Graph.h>
+#include <ivq/ITK/ImagePath.h>
+
+namespace ivq
+{
+  namespace ITK
+  {
+    /**
+     */
+    template< unsigned int _VDim >
+    class ImageSkeleton
+      : public ivq::ITK::Graph< typename ivq::ITK::ImagePath< _VDim >::TIndex, typename ivq::ITK::ImagePath< _VDim >::Pointer, typename ivq::ITK::ImagePath< _VDim >::TIndex, typename ivq::ITK::ImagePath< _VDim >::TIndex::LexicographicCompare >
+    {
+    public:
+      typedef ivq::ITK::ImagePath< _VDim >          TPath;
+      typedef typename TPath::TIndex                TIndex;
+      typedef typename TIndex::LexicographicCompare TIndexCompare;
+      typedef typename TPath::Pointer               TPathPointer;
+
+      itkStaticConstMacro( Dimension, unsigned int, _VDim );
+
+      typedef ivq::ITK::Graph< TIndex, TPathPointer, TIndex, TIndexCompare > Superclass;
+      typedef ImageSkeleton                   Self;
+      typedef itk::SmartPointer< Self >       Pointer;
+      typedef itk::SmartPointer< const Self > ConstPointer;
+
+    public:
+      itkNewMacro( Self );
+      itkTypeMacro( ImageSkeleton, ivq::ITK::Graph );
+
+    public:
+      void AddBranch( TPath* path );
+      const TPath* GetBranch( const TIndex& a, const TIndex& b ) const;
+
+      std::vector< TIndex > GetEndPoints( ) const;
+      std::vector< TIndex > GetBifurcations( ) const;
+
+    protected:
+      ImageSkeleton( );
+      virtual ~ImageSkeleton( );
+
+    private:
+      // Purposely not implemented
+      ImageSkeleton( const Self& other );
+      Self& operator=( const Self& other );
+    };
+
+  } // ecapseman
+
+} // ecapseman
+
+#ifndef ITK_MANUAL_INSTANTIATION
+#  include <ivq/ITK/ImageSkeleton.hxx>
+#endif // ITK_MANUAL_INSTANTIATION
+#endif // __ivq__ITK__ImageSkeleton__h__
+
+// eof - $RCSfile$
diff --git a/lib/ivq/ITK/ImageSkeleton.hxx b/lib/ivq/ITK/ImageSkeleton.hxx
new file mode 100644 (file)
index 0000000..7e93058
--- /dev/null
@@ -0,0 +1,98 @@
+// =========================================================================
+// @author Leonardo Florez Valencia
+// @email florez-l@javeriana.edu.co
+// =========================================================================
+#ifndef __ivq__ITK__ImageSkeleton__hxx__
+#define __ivq__ITK__ImageSkeleton__hxx__
+
+// -------------------------------------------------------------------------
+template< unsigned int _VDim >
+void ivq::ITK::ImageSkeleton< _VDim >::
+AddBranch( TPath* path )
+{
+  // Check inputs
+  if( path == NULL )
+    return;
+  unsigned long size = path->GetSize( );
+  if( size == 0 )
+    return;
+  TIndex a = path->GetVertex( 0 );
+  TIndex b = path->GetVertex( size - 1 );
+  if( this->HasEdge( a, b ) )
+    return;
+
+  // Add path
+  this->SetVertex( a, a );
+  this->SetVertex( b, b );
+  this->AddEdge( a, b, path );
+  this->AddEdge( b, a, path );
+  this->Modified( );
+}
+
+// -------------------------------------------------------------------------
+template< unsigned int _VDim >
+const typename ivq::ITK::ImageSkeleton< _VDim >::
+TPath* ivq::ITK::ImageSkeleton< _VDim >::
+GetBranch( const TIndex& a, const TIndex& b ) const
+{
+  static const TPath* null_path = NULL;
+  if( this->HasEdge( a, b ) )
+    return( this->GetEdges( a, b ).front( ) );
+  else
+    return( null_path );
+}
+
+// -------------------------------------------------------------------------
+template< unsigned int _VDim >
+std::vector< typename ivq::ITK::ImageSkeleton< _VDim >::TIndex >
+ivq::ITK::ImageSkeleton< _VDim >::
+GetEndPoints( ) const
+{
+  std::vector< TIndex > res;
+  typename Superclass::TMatrix::const_iterator mIt = this->BeginEdgesRows( );
+  for( ; mIt != this->EndEdgesRows( ); ++mIt )
+  {
+    unsigned long count = mIt->second.size( );
+    if( count == 1 )
+      res.push_back( mIt->first );
+
+  } // rof
+  return( res );
+}
+
+// -------------------------------------------------------------------------
+template< unsigned int _VDim >
+std::vector< typename ivq::ITK::ImageSkeleton< _VDim >::TIndex >
+ivq::ITK::ImageSkeleton< _VDim >::
+GetBifurcations( ) const
+{
+  std::vector< TIndex > res;
+  typename Superclass::TMatrix::const_iterator mIt = this->BeginEdgesRows( );
+  for( ; mIt != this->EndEdgesRows( ); ++mIt )
+  {
+    unsigned long count = mIt->second.size( );
+    if( count > 1 )
+      res.push_back( mIt->first );
+
+  } // rof
+  return( res );
+}
+
+// -------------------------------------------------------------------------
+template< unsigned int _VDim >
+ivq::ITK::ImageSkeleton< _VDim >::
+ImageSkeleton( )
+  : Superclass( )
+{
+}
+
+// -------------------------------------------------------------------------
+template< unsigned int _VDim >
+ivq::ITK::ImageSkeleton< _VDim >::
+~ImageSkeleton( )
+{
+}
+
+#endif // __ivq__ITK__ImageSkeleton__hxx__
+
+// eof - $RCSfile$
diff --git a/lib/ivq/ITK/ImageSkeletonReader.h b/lib/ivq/ITK/ImageSkeletonReader.h
new file mode 100644 (file)
index 0000000..3b1652d
--- /dev/null
@@ -0,0 +1,81 @@
+// =========================================================================
+// @author Leonardo Florez Valencia
+// @email florez-l@javeriana.edu.co
+// =========================================================================
+#ifndef __ivq__ITK__ImageSkeletonReader__h__
+#define __ivq__ITK__ImageSkeletonReader__h__
+
+#include <itkProcessObject.h>
+
+namespace ivq
+{
+  namespace ITK
+  {
+    /**
+     */
+    template< class _TSkeleton >
+    class ImageSkeletonReader
+      : public itk::ProcessObject
+    {
+    public:
+      // Basic types
+      typedef ImageSkeletonReader             Self;
+      typedef itk::ProcessObject              Superclass;
+      typedef itk::SmartPointer< Self >       Pointer;
+      typedef itk::SmartPointer< const Self > ConstPointer;
+
+      typedef _TSkeleton TSkeleton;
+
+    public:
+      itkNewMacro( Self );
+      itkTypeMacro( ImageSkeletonReader, itk::ProcessObject );
+
+      itkGetConstMacro( FileName, std::string );
+      itkSetMacro( FileName, std::string );
+
+    public:
+      TSkeleton* GetOutput( );
+      TSkeleton* GetOutput( unsigned int i );
+
+      virtual void GraftOutput( itk::DataObject* out );
+      virtual void GraftOutput(
+        const typename Superclass::DataObjectIdentifierType& key,
+        itk::DataObject* out
+        );
+      virtual void GraftNthOutput( unsigned int i, itk::DataObject* out );
+      virtual itk::DataObject::Pointer MakeOutput(
+        itk::ProcessObject::DataObjectPointerArraySizeType i
+        ) override;
+
+      virtual void Update( ) override
+        { this->GenerateData( ); }
+
+    protected:
+      ImageSkeletonReader( );
+      virtual ~ImageSkeletonReader( );
+
+      virtual void GenerateData( ) override;
+
+      // Do nothing
+      virtual void GenerateOutputInformation( ) override
+        { }
+
+    private:
+      // Purposely not implemented
+      ImageSkeletonReader( const Self& );
+      void operator=( const Self& );
+
+    protected:
+      std::string m_FileName;
+    };
+
+  } // ecapseman
+
+} // ecapseman
+
+#ifndef ITK_MANUAL_INSTANTIATION
+#  include <ivq/ITK/ImageSkeletonReader.hxx>
+#endif // ITK_MANUAL_INSTANTIATION
+#endif // __ivq__ITK__ImageSkeletonReader__h__
+
+// eof - $RCSfile$
diff --git a/lib/ivq/ITK/ImageSkeletonReader.hxx b/lib/ivq/ITK/ImageSkeletonReader.hxx
new file mode 100644 (file)
index 0000000..f8df01d
--- /dev/null
@@ -0,0 +1,208 @@
+// =========================================================================
+// @author Leonardo Florez Valencia
+// @email florez-l@javeriana.edu.co
+// =========================================================================
+#ifndef __ivq__ITK__ImageSkeletonReader__hxx__
+#define __ivq__ITK__ImageSkeletonReader__hxx__
+
+// -------------------------------------------------------------------------
+template< class _TSkeleton >
+_TSkeleton* fpa::ITK::ImageSkeletonReader< _TSkeleton >::
+GetOutput( )
+{
+  return(
+    itkDynamicCastInDebugMode< TSkeleton* >( this->GetPrimaryOutput( ) )
+    );
+}
+
+// -------------------------------------------------------------------------
+template< class _TSkeleton >
+_TSkeleton* fpa::ITK::ImageSkeletonReader< _TSkeleton >::
+GetOutput( unsigned int i )
+{
+  return(
+    itkDynamicCastInDebugMode< TSkeleton* >(
+      this->itk::ProcessObject::GetOutput( i )
+      )
+    );
+}
+
+// -------------------------------------------------------------------------
+template< class _TSkeleton >
+void fpa::ITK::ImageSkeletonReader< _TSkeleton >::
+GraftOutput( itk::DataObject* out )
+{
+  this->GraftNthOutput( 0, out );
+}
+
+// -------------------------------------------------------------------------
+template< class _TSkeleton >
+void fpa::ITK::ImageSkeletonReader< _TSkeleton >::
+GraftOutput(
+  const typename Superclass::DataObjectIdentifierType& key,
+  itk::DataObject* out
+  )
+{
+  if( out == NULL )
+  {
+    itkExceptionMacro(
+      << "Requested to graft output that is a NULL pointer"
+      );
+
+  } // fi
+  itk::DataObject* output = this->itk::ProcessObject::GetOutput( key );
+  output->Graft( out );
+}
+
+// -------------------------------------------------------------------------
+template< class _TSkeleton >
+void fpa::ITK::ImageSkeletonReader< _TSkeleton >::
+GraftNthOutput( unsigned int i, itk::DataObject* out )
+{
+  if( i >= this->GetNumberOfIndexedOutputs( ) )
+  {
+    itkExceptionMacro(
+      << "Requested to graft output " << i
+      << " but this filter only has "
+      << this->GetNumberOfIndexedOutputs( )
+      << " indexed Outputs."
+      );
+
+  } // fi
+  this->GraftOutput( this->MakeNameFromOutputIndex( i ), out );
+}
+
+// -------------------------------------------------------------------------
+template< class _TSkeleton >
+itk::DataObject::Pointer
+fpa::ITK::ImageSkeletonReader< _TSkeleton >::
+MakeOutput( itk::ProcessObject::DataObjectPointerArraySizeType i )
+{
+  return( TSkeleton::New( ).GetPointer( ) );
+}
+
+// -------------------------------------------------------------------------
+template< class _TSkeleton >
+fpa::ITK::ImageSkeletonReader< _TSkeleton >::
+ImageSkeletonReader( )
+  : Superclass( )
+{
+  typename TSkeleton::Pointer out =
+    static_cast< TSkeleton* >( this->MakeOutput( 0 ).GetPointer( ) );
+  this->itk::ProcessObject::SetNumberOfRequiredInputs( 0 );
+  this->itk::ProcessObject::SetNumberOfRequiredOutputs( 1 );
+  this->itk::ProcessObject::SetNthOutput( 0, out.GetPointer( ) );
+}
+
+// -------------------------------------------------------------------------
+template< class _TSkeleton >
+fpa::ITK::ImageSkeletonReader< _TSkeleton >::
+~ImageSkeletonReader( )
+{
+}
+
+// -------------------------------------------------------------------------
+template< class _TSkeleton >
+void fpa::ITK::ImageSkeletonReader< _TSkeleton >::
+GenerateData( )
+{
+  typedef typename TSkeleton::TPath   _TPath;
+  typedef typename _TPath::TIndex     _TIndex;
+  typedef typename _TPath::TSpacing   _TSpacing;
+  typedef typename _TPath::TPoint     _TPoint;
+  typedef typename _TPath::TDirection _TDirection;
+
+  std::string buffer;
+  std::ifstream file_stream( this->m_FileName.c_str( ) );
+  if( !file_stream )
+  {
+    itkExceptionMacro(
+      << "Error reading skeleton from \"" << this->m_FileName << "\""
+      );
+    return;
+
+  } // fi
+  file_stream.seekg( 0, std::ios::end );
+  buffer.reserve( ( unsigned int )( file_stream.tellg( ) ) );
+  file_stream.seekg( 0, std::ios::beg );
+  buffer.assign(
+    ( std::istreambuf_iterator< char >( file_stream ) ),
+    std::istreambuf_iterator< char >( )
+    );
+  file_stream.close( );
+
+  std::istringstream in( buffer );
+  unsigned int dim;
+  in >> dim;
+  if( dim != TSkeleton::Dimension )
+  {
+    itkExceptionMacro(
+      << "Mismatched skeletons dimension: " << dim
+      << " != " << TSkeleton::Dimension
+      );
+    return;
+
+  } // fi
+
+  // Read spatial parameters
+  _TSpacing spa;
+  _TDirection dir;
+  _TPoint ori;
+  for( unsigned int d = 0; d < dim; ++d )
+    in >> spa[ d ];
+  for( unsigned int d = 0; d < dim; ++d )
+    for( unsigned int e = 0; e < dim; ++e )
+      in >> dir[ d ][ e ];
+  for( unsigned int d = 0; d < dim; ++d )
+    in >> ori[ d ];
+
+  // Read end-points, just to ignore
+  unsigned int n;
+  in >> n;
+  for( unsigned int i = 0; i < n; ++i )
+  {
+    _TIndex idx;
+    for( unsigned int d = 0; d < dim; ++d )
+      in >> idx[ d ];
+
+  } // rof
+
+  // Read bifurcations, just to ignore
+  in >> n;
+  for( unsigned int i = 0; i < n; ++i )
+  {
+    _TIndex idx;
+    for( unsigned int d = 0; d < dim; ++d )
+      in >> idx[ d ];
+
+  } // rof
+
+  // Read paths
+  TSkeleton* out = this->GetOutput( );
+  unsigned int nPaths;
+  in >> nPaths;
+  for( unsigned int p = 0; p < nPaths; ++p )
+  {
+    typename _TPath::Pointer path = _TPath::New( );
+    path->SetSpacing( spa );
+    path->SetOrigin( ori );
+    path->SetDirection( dir );
+
+    unsigned long pathSize;
+    in >> pathSize;
+    for( unsigned long id = 0; id < pathSize; ++id )
+    {
+      _TIndex idx;
+      for( unsigned int d = 0; d < dim; ++d )
+        in >> idx[ d ];
+      path->AddVertex( idx );
+
+    } // rof
+    out->AddBranch( path );
+
+  } // rof
+}
+
+#endif // __ivq__ITK__ImageSkeletonReader__hxx__
+
+// eof - $RCSfile$
diff --git a/lib/ivq/ITK/ImageSkeletonWriter.h b/lib/ivq/ITK/ImageSkeletonWriter.h
new file mode 100644 (file)
index 0000000..8c45b47
--- /dev/null
@@ -0,0 +1,70 @@
+// =========================================================================
+// @author Leonardo Florez Valencia
+// @email florez-l@javeriana.edu.co
+// =========================================================================
+#ifndef __ivq__ITK__ImageSkeletonWriter__h__
+#define __ivq__ITK__ImageSkeletonWriter__h__
+
+#include <itkProcessObject.h>
+#include <ivq/Config.h>
+
+namespace ivq
+{
+  namespace ITK
+  {
+    /**
+     */
+    template< class _TSkeleton >
+    class ImageSkeletonWriter
+      : public itk::ProcessObject
+    {
+    public:
+      // Basic types
+      typedef ImageSkeletonWriter             Self;
+      typedef itk::ProcessObject              Superclass;
+      typedef itk::SmartPointer< Self >       Pointer;
+      typedef itk::SmartPointer< const Self > ConstPointer;
+
+      typedef _TSkeleton TSkeleton;
+      typedef typename TSkeleton::TEdges     TEdges;
+      typedef typename TSkeleton::TMatrix    TMatrix;
+      typedef typename TSkeleton::TMatrixRow TMatrixRow;
+      typedef typename TSkeleton::TPath      TPath;
+      typedef typename TSkeleton::TVertex    TVertex;
+
+    public:
+      itkNewMacro( Self );
+      itkTypeMacro( ImageSkeletonWriter, itk::ProcessObject );
+
+      itkGetConstMacro( FileName, std::string );
+      itkSetMacro( FileName, std::string );
+
+      ivqITKInputMacro( Input, TSkeleton );
+
+    public:
+      virtual void Update( ) override;
+
+    protected:
+      ImageSkeletonWriter( );
+      virtual ~ImageSkeletonWriter( );
+
+      virtual void GenerateData( ) override;
+
+    private:
+      // Purposely not implemented
+      ImageSkeletonWriter( const Self& );
+      void operator=( const Self& );
+
+    protected:
+      std::string m_FileName;
+    };
+
+  } // ecapseman
+
+} // ecapseman
+
+#ifndef ITK_MANUAL_INSTANTIATION
+#  include <ivq/ITK/ImageSkeletonWriter.hxx>
+#endif // ITK_MANUAL_INSTANTIATION
+#endif // __ivq__ITK__ImageSkeletonWriter__h__
+// eof - $RCSfile$
diff --git a/lib/ivq/ITK/ImageSkeletonWriter.hxx b/lib/ivq/ITK/ImageSkeletonWriter.hxx
new file mode 100644 (file)
index 0000000..3541bcd
--- /dev/null
@@ -0,0 +1,139 @@
+// =========================================================================
+// @author Leonardo Florez Valencia
+// @email florez-l@javeriana.edu.co
+// =========================================================================
+#ifndef __ivq__ITK__ImageSkeletonWriter__hxx__
+#define __ivq__ITK__ImageSkeletonWriter__hxx__
+
+#include <fstream>
+
+// -------------------------------------------------------------------------
+template< class _TSkeleton >
+void ivq::ITK::ImageSkeletonWriter< _TSkeleton >::
+Update( )
+{
+  TSkeleton* input = const_cast< TSkeleton* >( this->GetInput( ) );
+  if( input != NULL )
+  {
+    input->UpdateOutputInformation( );
+    input->UpdateOutputData( );
+    this->GenerateData( );
+    this->ReleaseInputs( );
+
+  } // fi
+}
+
+// -------------------------------------------------------------------------
+template< class _TSkeleton >
+ivq::ITK::ImageSkeletonWriter< _TSkeleton >::
+ImageSkeletonWriter( )
+  : Superclass( ),
+    m_FileName( "" )
+{
+  ivqITKInputConfigureMacro( Input, TSkeleton );
+}
+
+// -------------------------------------------------------------------------
+template< class _TSkeleton >
+ivq::ITK::ImageSkeletonWriter< _TSkeleton >::
+~ImageSkeletonWriter( )
+{
+}
+
+// -------------------------------------------------------------------------
+template< class _TSkeleton >
+void ivq::ITK::ImageSkeletonWriter< _TSkeleton >::
+GenerateData( )
+{
+  const TSkeleton* sk = this->GetInput( );
+  typename TMatrix::const_iterator mIt = sk->BeginEdgesRows( );
+  typename TMatrixRow::const_iterator rIt = mIt->second.begin( );
+  typename TEdges::const_iterator eIt = rIt->second.begin( );
+  const TPath* path = *eIt;
+
+  // Write base information
+  std::stringstream out1, out2;
+  out1 << TSkeleton::Dimension << std::endl;
+  typename TPath::TSpacing spa = path->GetSpacing( );
+  for( unsigned int d = 0; d < TSkeleton::Dimension; ++d )
+    out1 << spa[ d ] << " ";
+  out1 << std::endl;
+  typename TPath::TDirection dir = path->GetDirection( );
+  for( unsigned int d = 0; d < TSkeleton::Dimension; ++d )
+    for( unsigned int e = 0; e < TSkeleton::Dimension; ++e )
+      out1 << dir[ d ][ e ] << " ";
+  out1 << std::endl;
+  typename TPath::TPoint ori = path->GetOrigin( );
+  for( unsigned int d = 0; d < TSkeleton::Dimension; ++d )
+    out1 << ori[ d ] << " ";
+  out1 << std::endl;
+
+  // End points
+  std::vector< TVertex > end_points = sk->GetEndPoints( );
+  out1 << end_points.size( ) << std::endl;
+  typename std::vector< TVertex >::const_iterator epIt = end_points.begin( );
+  for( ; epIt != end_points.end( ); ++epIt )
+  {
+    for( unsigned int d = 0; d < TSkeleton::Dimension; ++d )
+      out1 << ( *epIt )[ d ] << " ";
+    out1 << std::endl;
+
+  } // rof
+
+  // Bifurcations
+  std::vector< TVertex > bifurcations = sk->GetBifurcations( );
+  out1 << bifurcations.size( ) << std::endl;
+  typename std::vector< TVertex >::const_iterator bIt = bifurcations.begin( );
+  for( ; bIt != bifurcations.end( ); ++bIt )
+  {
+    for( unsigned int d = 0; d < TSkeleton::Dimension; ++d )
+      out1 << ( *bIt )[ d ] << " ";
+    out1 << std::endl;
+
+  } // rof
+
+  // Write paths
+  unsigned long pathCount = 0;
+  mIt = sk->BeginEdgesRows( );
+  for( ; mIt != sk->EndEdgesRows( ); ++mIt )
+  {
+    typename TMatrixRow::const_iterator rIt = mIt->second.begin( );
+    for( ; rIt != mIt->second.end( ); ++rIt )
+    {
+      typename TEdges::const_iterator eIt = rIt->second.begin( );
+      for( ; eIt != rIt->second.end( ); ++eIt )
+      {
+        TPath* path = *eIt;
+        pathCount++;
+        unsigned int size = path->GetSize( );
+        out2 << size << std::endl;
+        for( unsigned int i = 0; i < path->GetSize( ); ++i )
+        {
+          TVertex v = path->GetVertex( i );
+          for( unsigned int d = 0; d < TSkeleton::Dimension; ++d )
+            out2 << v[ d ] << " ";
+
+        } // rof
+        out2 << std::endl;
+
+      } // rof
+
+    } // rof
+
+  } // rof
+  out1 << pathCount << std::endl << out2.str( );
+
+  // Real write
+  std::ofstream file_stream( this->m_FileName.c_str( ), std::ofstream::binary );
+  if( !file_stream )
+    itkExceptionMacro(
+      << "Unable to write skeleton to \""
+      << this->m_FileName
+      << "\""
+      );
+  file_stream.write( out1.str( ).c_str( ), out1.str( ).size( ) );
+}
+
+#endif // __ivq__ITK__ImageSkeletonWriter__hxx__
+
+// eof - $RCSfile$
index c9c24f1b76b8b0f762f98b79e3cd298f3e5cc6e3..ef10e6c764aa8f626d2e181ef7dacd83529c70f9 100644 (file)
@@ -1,9 +1,7 @@
-/* =======================================================================
- * @author: Leonardo Florez-Valencia
- * @email: florez-l@javeriana.edu.co
- * =======================================================================
- */
-
+// =======================================================================
+// @author: Leonardo Florez-Valencia
+// @email: florez-l@javeriana.edu.co
+// =======================================================================
 #ifndef __ivq__ITK__ImageStatisticsFromSeeds__h__
 #define __ivq__ITK__ImageStatisticsFromSeeds__h__
 
@@ -76,7 +74,6 @@ namespace ivq
 #ifndef ITK_MANUAL_INSTANTIATION
 #  include <ivq/ITK/ImageStatisticsFromSeeds.hxx>
 #endif // ITK_MANUAL_INSTANTIATION
-
 #endif // __ivq__ITK__ImageStatisticsFromSeeds__h__
 
 // eof - $RCSfile$
index 2bf9a10cb1a78356d2c5e9c02b80bc1e37c93d0d..9518c545f895eb8b334c064526f69f064f0dada1 100644 (file)
@@ -1,9 +1,7 @@
-/* =======================================================================
- * @author: Leonardo Florez-Valencia
- * @email: florez-l@javeriana.edu.co
- * =======================================================================
- */
-
+// =======================================================================
+// @author: Leonardo Florez-Valencia
+// @email: florez-l@javeriana.edu.co
+// =======================================================================
 #ifndef __ivq__ITK__ImageStatisticsFromSeeds__hxx__
 #define __ivq__ITK__ImageStatisticsFromSeeds__hxx__
 
index 2be71e645f0d24638cdde31dd5f7fd2b6ef434d9..c8a3107a5ff6dd750692f71c5e46296b8359764d 100644 (file)
@@ -1,9 +1,7 @@
-/* =======================================================================
- * @author: Leonardo Florez-Valencia
- * @email: florez-l@javeriana.edu.co
- * =======================================================================
- */
-
+// =======================================================================
+// @author: Leonardo Florez-Valencia
+// @email: florez-l@javeriana.edu.co
+// =======================================================================
 #ifndef __ivq__ITK__ImageUnaryFunctionFilter__h__
 #define __ivq__ITK__ImageUnaryFunctionFilter__h__
 
index b90f73e6f78271478ddb7ade4d337acce75edbd9..0d72de6d34a3bf3d5e3fa57078029d9b5a816266 100644 (file)
@@ -1,9 +1,7 @@
-/* =======================================================================
- * @author: Leonardo Florez-Valencia
- * @email: florez-l@javeriana.edu.co
- * =======================================================================
- */
-
+// =======================================================================
+// @author: Leonardo Florez-Valencia
+// @email: florez-l@javeriana.edu.co
+// =======================================================================
 #ifndef __ivq__ITK__ImageUnaryFunctionFilter__hxx__
 #define __ivq__ITK__ImageUnaryFunctionFilter__hxx__
 
index 39e6c2ec262ae320c0917810a28a9d5e4255b334..6b48c8fc847e8836c61326557735697fb54067f9 100644 (file)
@@ -2,11 +2,10 @@
 // @author Leonardo Florez Valencia
 // @email florez-l@javeriana.edu.co
 // =========================================================================
-
 #ifndef __ivq__ITK__IncrementalMeanAndVariance__h__
 #define __ivq__ITK__IncrementalMeanAndVariance__h__
 
-#include <ivq/ivq_export.h>
+#include <ivq/Config.h>
 
 namespace ivq
 {
index 22b45268ca51dcd049402298f448ff385a807b37..6ddb05a288774c34556c812ad8ccc26dbee1e482 100644 (file)
@@ -1,9 +1,7 @@
-/* =======================================================================
- * @author: Leonardo Florez-Valencia
- * @email: florez-l@javeriana.edu.co
- * =======================================================================
- */
-
+// =======================================================================
+// @author: Leonardo Florez-Valencia
+// @email: florez-l@javeriana.edu.co
+// =======================================================================
 #ifndef __ivq__ITK__IsoImageSlicer__h__
 #define __ivq__ITK__IsoImageSlicer__h__
 
@@ -208,7 +206,6 @@ SetTranslation( const _TOtherVector& t )
 #ifndef ITK_MANUAL_INSTANTIATION
 #  include <ivq/ITK/IsoImageSlicer.hxx>
 #endif // ITK_MANUAL_INSTANTIATION
-
 #endif // __ivq__ITK__IsoImageSlicer__h__
 
 // eof - $RCSfile$
index cfcfc5e2ea912d34e664574f5dbc8e9c3df0ddb3..7bb05320f0a54643afc1f9ce5a2f1fb7e1440cb5 100644 (file)
@@ -1,9 +1,7 @@
-/* =======================================================================
- * @author: Leonardo Florez-Valencia
- * @email: florez-l@javeriana.edu.co
- * =======================================================================
- */
-
+// =======================================================================
+// @author: Leonardo Florez-Valencia
+// @email: florez-l@javeriana.edu.co
+// =======================================================================
 #ifndef __ivq__ITK__IsoImageSlicer__hxx__
 #define __ivq__ITK__IsoImageSlicer__hxx__
 
diff --git a/lib/ivq/ITK/MinimumSpanningTree.h b/lib/ivq/ITK/MinimumSpanningTree.h
new file mode 100644 (file)
index 0000000..7c5c5e2
--- /dev/null
@@ -0,0 +1,74 @@
+// =========================================================================
+// @author Leonardo Florez Valencia
+// @email florez-l@javeriana.edu.co
+// =========================================================================
+#ifndef __ivq__ITK__MinimumSpanningTree__h__
+#define __ivq__ITK__MinimumSpanningTree__h__
+
+#include <vector>
+
+namespace ivq
+{
+  namespace ITK
+  {
+    /**
+     */
+    template< class _TVertex, class _Superclass >
+    class MinimumSpanningTree
+      : public _Superclass
+    {
+    public:
+      typedef MinimumSpanningTree             Self;
+      typedef _Superclass                     Superclass;
+      typedef itk::SmartPointer< Self >       Pointer;
+      typedef itk::SmartPointer< const Self > ConstPointer;
+
+      typedef _TVertex                      TVertex;
+      typedef std::pair< TVertex, bool >    TCollision;
+      typedef std::vector< TCollision >     TCollisionsRow;
+      typedef std::vector< TCollisionsRow > TCollisions;
+      typedef std::vector< TVertex >        TVertices;
+
+    protected:
+      typedef std::vector< unsigned long > _TRow;
+      typedef std::vector< _TRow >         _TMatrix;
+
+    public:
+      itkTypeMacro( ivq::Base::MinimumSpanningTree, _Superclass );
+
+    public:
+      const TCollisions& GetCollisions( ) const;
+      void SetCollisions( const TCollisions& collisions );
+
+      void ClearSeeds( );
+      void AddSeed( const TVertex& seed, unsigned long fId );
+
+      virtual TVertex GetParent( const TVertex& v ) const = 0;
+      virtual void SetParent( const TVertex& v, const TVertex& p ) = 0;
+
+      virtual TVertices GetAxis( const TVertex& a ) const;
+      virtual TVertices GetAxis( const TVertex& a, const TVertex& b ) const;
+
+    protected:
+      MinimumSpanningTree( );
+      virtual ~MinimumSpanningTree( );
+
+    private:
+      MinimumSpanningTree( const Self& other );
+      Self& operator=( const Self& other );
+
+    protected:
+      TCollisions m_Collisions;
+      _TMatrix    m_FrontPaths;
+      std::vector< TVertex > m_Seeds;
+    };
+
+  } // ecapseman
+
+} // ecapseman
+
+#ifndef ITK_MANUAL_INSTANTIATION
+#  include <ivq/ITK/MinimumSpanningTree.hxx>
+#endif // ITK_MANUAL_INSTANTIATION
+#endif // __ivq__ITK__MinimumSpanningTree__h__
+// eof - $RCSfile$
diff --git a/lib/ivq/ITK/MinimumSpanningTree.hxx b/lib/ivq/ITK/MinimumSpanningTree.hxx
new file mode 100644 (file)
index 0000000..5058912
--- /dev/null
@@ -0,0 +1,236 @@
+// =========================================================================
+// @author Leonardo Florez Valencia
+// @email florez-l@javeriana.edu.co
+// =========================================================================
+#ifndef __ivq__ITK__MinimumSpanningTree__hxx__
+#define __ivq__ITK__MinimumSpanningTree__hxx__
+
+// -------------------------------------------------------------------------
+template< class _TVertex, class _Superclass >
+const typename ivq::ITK::MinimumSpanningTree< _TVertex, _Superclass >::
+TCollisions& ivq::ITK::MinimumSpanningTree< _TVertex, _Superclass >::
+GetCollisions( ) const
+{
+  return( this->m_Collisions );
+}
+
+// -------------------------------------------------------------------------
+template< class _TVertex, class _Superclass >
+void ivq::ITK::MinimumSpanningTree< _TVertex, _Superclass >::
+SetCollisions( const TCollisions& collisions )
+{
+  static const unsigned long _inf =
+    std::numeric_limits< unsigned long >::max( );
+  if( this->m_Collisions == collisions )
+    return;
+
+  this->m_Collisions = collisions;
+
+  // Prepare a front graph
+  unsigned long N = this->m_Collisions.size( );
+  _TMatrix dist( N, _TRow( N, _inf ) );
+  this->m_FrontPaths = dist;
+  for( unsigned long i = 0; i < N; ++i )
+  {
+    for( unsigned long j = 0; j < N; ++j )
+    {
+      if( this->m_Collisions[ i ][ j ].second )
+      {
+        dist[ i ][ j ] = 1;
+        dist[ j ][ i ] = 1;
+        this->m_FrontPaths[ i ][ j ] = j;
+        this->m_FrontPaths[ j ][ i ] = i;
+
+      } // fi
+
+    } // rof
+    dist[ i ][ i ] = 0;
+    this->m_FrontPaths[ i ][ i ] = i;
+
+  } // rof
+
+  // Use Floyd-Warshall to compute all possible paths between fronts
+  for( unsigned long k = 0; k < N; ++k )
+  {
+    for( unsigned long i = 0; i < N; ++i )
+    {
+      for( unsigned long j = 0; j < N; ++j )
+      {
+        // WARNING: you don't want a numeric overflow!!!
+        unsigned long dik = dist[ i ][ k ];
+        unsigned long dkj = dist[ k ][ j ];
+        unsigned long sum = _inf;
+        if( dik < _inf && dkj < _inf )
+          sum = dik + dkj;
+
+        // Ok, continue Floyd-Warshall
+        if( sum < dist[ i ][ j ] )
+        {
+          dist[ i ][ j ] = sum;
+          this->m_FrontPaths[ i ][ j ] = this->m_FrontPaths[ i ][ k ];
+
+        } // fi
+
+      } // rof
+
+    } // rof
+
+  } // rof
+  this->m_Seeds.resize( N );
+  this->Modified( );
+}
+
+// -------------------------------------------------------------------------
+template< class _TVertex, class _Superclass >
+void ivq::ITK::MinimumSpanningTree< _TVertex, _Superclass >::
+ClearSeeds( )
+{
+  this->m_Seeds.clear( );
+  this->Modified( );
+}
+
+// -------------------------------------------------------------------------
+template< class _TVertex, class _Superclass >
+void ivq::ITK::MinimumSpanningTree< _TVertex, _Superclass >::
+AddSeed( const _TVertex& seed, unsigned long fId )
+{
+  this->m_Seeds[ fId - 1 ] = seed;
+  this->Modified( );
+}
+
+// -------------------------------------------------------------------------
+template< class _TVertex, class _Superclass >
+typename ivq::ITK::MinimumSpanningTree< _TVertex, _Superclass >::
+TVertices ivq::ITK::MinimumSpanningTree< _TVertex, _Superclass >::
+GetAxis( const _TVertex& a ) const
+{
+  TVertices vertices;
+  _TVertex it = a;
+  _TVertex p = this->GetParent( it );
+  while( it != p )
+  {
+    vertices.push_back( it );
+    it = p;
+    p = this->GetParent( it );
+
+  } // elihw
+  vertices.push_back( it );
+  return( vertices );
+}
+
+// -------------------------------------------------------------------------
+template< class _TVertex, class _Superclass >
+typename ivq::ITK::MinimumSpanningTree< _TVertex, _Superclass >::
+TVertices ivq::ITK::MinimumSpanningTree< _TVertex, _Superclass >::
+GetAxis( const _TVertex& a, const _TVertex& b ) const
+{
+  static const unsigned long _inf =
+    std::numeric_limits< unsigned long >::max( );
+
+  TVertices vertices;
+  TVertices pa = this->GetAxis( a );
+  TVertices pb = this->GetAxis( b );
+  if( pa.size( ) > 0 && pb.size( ) > 0 )
+  {
+    // Find front identifiers
+    unsigned long ia = _inf, ib = _inf;
+    unsigned long N = this->m_Seeds.size( );
+    for( unsigned long i = 0; i < N; ++i )
+    {
+      if( this->m_Seeds[ i ] == pa[ pa.size( ) - 1 ] )
+        ia = i;
+      if( this->m_Seeds[ i ] == pb[ pb.size( ) - 1 ] )
+        ib = i;
+
+    } // rof
+
+    // Check if there is a front-jump between given seeds
+    if( ia != ib )
+    {
+      // Compute front path
+      std::vector< long > fpath;
+      fpath.push_back( ia );
+      while( ia != ib )
+      {
+        ia = this->m_FrontPaths[ ia ][ ib ];
+        fpath.push_back( ia );
+
+      } // elihw
+
+      // Continue only if both fronts are connected
+      unsigned int N = fpath.size( );
+      if( N > 0 )
+      {
+        // First path: from start vertex to first collision
+        vertices = this->GetAxis(
+          a, this->m_Collisions[ fpath[ 0 ] ][ fpath[ 1 ] ].first
+          );
+
+        // Intermediary paths
+        for( unsigned int i = 1; i < N - 1; ++i )
+        {
+          TVertices ipath =
+            this->GetAxis(
+              this->m_Collisions[ fpath[ i - 1 ] ][ fpath[ i ] ].first,
+              this->m_Collisions[ fpath[ i + 1 ] ][ fpath[ i ] ].first
+              );
+          for( long id = 0; id < ipath.size( ); ++id )
+            vertices.push_back( ipath[ id ] );
+
+        } // rof
+
+        // Final path: from last collision to end point
+        TVertices lpath =
+          this->GetAxis(
+            this->m_Collisions[ fpath[ N - 1 ] ][ fpath[ N - 2 ] ].first, b
+            );
+        for( long id = 0; id < lpath.size( ); ++id )
+          vertices.push_back( lpath[ id ] );
+
+      } // fi
+    }
+    else
+    {
+      // Ignore common part: find common ancestor
+      long aIt = pa.size( ) - 1;
+      long bIt = pb.size( ) - 1;
+      bool cont = true;
+      while( aIt >= 0 && bIt >= 0 && cont )
+      {
+        cont = ( pa[ aIt ] == pb[ bIt ] );
+        aIt--;
+        bIt--;
+
+      } // elihw
+      aIt++;
+      bIt++;
+
+      // Glue both parts
+      for( long cIt = 0; cIt <= aIt; ++cIt )
+        vertices.push_back( pa[ cIt ] );
+      for( ; bIt >= 0; --bIt )
+        vertices.push_back( pb[ bIt ] );
+
+    } // fi
+
+  } // fi
+  return( vertices );
+}
+
+// -------------------------------------------------------------------------
+template< class _TVertex, class _Superclass >
+ivq::ITK::MinimumSpanningTree< _TVertex, _Superclass >::
+MinimumSpanningTree( )
+  : Superclass( )
+{
+}
+
+// -------------------------------------------------------------------------
+template< class _TVertex, class _Superclass >
+ivq::ITK::MinimumSpanningTree< _TVertex, _Superclass >::
+~MinimumSpanningTree( )
+{
+}
+
+#endif // __ivq__ITK__MinimumSpanningTree__hxx__
+// eof - $RCSfile$
index 0dfa4940bd5e30390fdcd79e17115e879678ba58..63e02ad64f7f7a6783d88b45a6d78e33e3d5f147 100644 (file)
@@ -2,11 +2,10 @@
 // @author Leonardo Florez Valencia
 // @email florez-l@javeriana.edu.co
 // =========================================================================
-
 #ifndef __ivq__ITK__PeakDetector__h__
 #define __ivq__ITK__PeakDetector__h__
 
-#include <ivq/ivq_export.h>
+#include <ivq/Config.h>
 
 #include <vector>
 #include <ivq/ITK/IncrementalMeanAndVariance.h>
index 2bec6f5b12c2b7f52f61b462a8dd7afb5be58294..62305e0393c595238df48e6894433be658f539ab 100644 (file)
@@ -1,16 +1,13 @@
-/* =======================================================================
- * @author: Leonardo Florez-Valencia
- * @email: florez-l@javeriana.edu.co
- * =======================================================================
- */
-
+// =======================================================================
+// @author: Leonardo Florez-Valencia
+// @email: florez-l@javeriana.edu.co
+// =======================================================================
 #ifndef __ivq__ITK__RasterContourFilter__h__
 #define __ivq__ITK__RasterContourFilter__h__
 
 #include <deque>
 #include <itkImageSource.h>
 
-// -------------------------------------------------------------------------
 namespace ivq
 {
   namespace ITK
index 83eda54f35b67bfb03b4b55daa29253dea9fdb2b..07bad398270572f976151cb9092006e439e8e706 100644 (file)
@@ -1,12 +1,10 @@
-/* =======================================================================
- * @author: Leonardo Florez-Valencia
- * @email: florez-l@javeriana.edu.co
- * =======================================================================
- */
-
+// =======================================================================
+// @author: Leonardo Florez-Valencia
+// @email: florez-l@javeriana.edu.co
+// =======================================================================
 // Inclusion test taken from:
 // https://www.ecse.rpi.edu/Homepages/wrf/Research/Short_Notes/pnpoly.html
-
+// =======================================================================
 #ifndef __ivq__ITK__RasterContourFilter__hxx__
 #define __ivq__ITK__RasterContourFilter__hxx__
 
index 4828d8ffa9010a2adcff8966dfd464ef61cc8f40..8eed890a8a0e595014753d9c57057543c4d60530 100644 (file)
@@ -1,8 +1,7 @@
-/* =======================================================================
- * @author: Leonardo Florez-Valencia
- * @email: florez-l@javeriana.edu.co
- * =======================================================================
- */
+// =======================================================================
+// @author: Leonardo Florez-Valencia
+// @email: florez-l@javeriana.edu.co
+// =======================================================================
 #ifndef __ivq__ITK__RegionOfInterestWithPaddingImageFilter__h__
 #define __ivq__ITK__RegionOfInterestWithPaddingImageFilter__h__
 
index 14d1f0e8b3eea97bc2daeaa648562a28c47bc501..ac86e827aabedb3c24c70cf7be848a322f9649f1 100644 (file)
@@ -1,8 +1,7 @@
-/* =======================================================================
- * @author: Leonardo Florez-Valencia
- * @email: florez-l@javeriana.edu.co
- * =======================================================================
- */
+// =======================================================================
+// @author: Leonardo Florez-Valencia
+// @email: florez-l@javeriana.edu.co
+// =======================================================================
 #ifndef __ivq__ITK__RegionOfInterestWithPaddingImageFilter__hxx__
 #define __ivq__ITK__RegionOfInterestWithPaddingImageFilter__hxx__
 
index e5649d5cbb8f1381d94f0d09c8cdcbb564d8356f..04959318bfdf70a46c8c6163f595f4b5afad984a 100644 (file)
@@ -1,8 +1,7 @@
-/* =======================================================================
- * @author: Leonardo Florez-Valencia
- * @email: florez-l@javeriana.edu.co
- * =======================================================================
- */
+// =======================================================================
+// @author: Leonardo Florez-Valencia
+// @email: florez-l@javeriana.edu.co
+// =======================================================================
 
 #include <ivq/ITK/Simple3DCurve.h>
 
index c01abb9d51d87caab370f8f27b46f8d64a4de5ab..e81feae3722d6895a6fd076bf0dea0bbc8733dd6 100644 (file)
@@ -1,13 +1,11 @@
-/* =======================================================================
- * @author: Leonardo Florez-Valencia
- * @email: florez-l@javeriana.edu.co
- * =======================================================================
- */
-
+// =======================================================================
+// @author: Leonardo Florez-Valencia
+// @email: florez-l@javeriana.edu.co
+// =======================================================================
 #ifndef __ivq__ITK__Simple3DCurve__h__
 #define __ivq__ITK__Simple3DCurve__h__
 
-#include <ivq/ivq_export.h>
+#include <ivq/Config.h>
 
 #include <itkDataObject.h>
 #include <itkObjectFactory.h>
index 690043cbd2a53e2d9d79d7db56de8fdd959afbf3..7fd0134833bd1e7d7206f887bb8e931ff6c8f865 100644 (file)
@@ -1,14 +1,11 @@
-/* =======================================================================
- * @author: Leonardo Florez-Valencia
- * @email: florez-l@javeriana.edu.co
- * =======================================================================
- */
-
+// =======================================================================
+// @author: Leonardo Florez-Valencia
+// @email: florez-l@javeriana.edu.co
+// =======================================================================
 #ifndef __ivq__ITK__ThresholdFunction__h__
 #define __ivq__ITK__ThresholdFunction__h__
 
 #include <set>
-
 #include <itkFunctionBase.h>
 
 namespace ivq
@@ -83,7 +80,6 @@ namespace ivq
 #ifndef ITK_MANUAL_INSTANTIATION
 #  include <ivq/ITK/ThresholdFunction.hxx>
 #endif // ITK_MANUAL_INSTANTIATION
-
 #endif // __ivq__ITK__ThresholdFunction__h__
 
 // eof - $RCSfile$
index 090b278f1e03bc7ccf7689a827ffa75c96168004..5869adffdb31da8a740fe832b460e3c5b152981b 100644 (file)
@@ -1,9 +1,7 @@
-/* =======================================================================
- * @author: Leonardo Florez-Valencia
- * @email: florez-l@javeriana.edu.co
- * =======================================================================
- */
-
+// =======================================================================
+// @author: Leonardo Florez-Valencia
+// @email: florez-l@javeriana.edu.co
+// =======================================================================
 #ifndef __ivq__ITK__ThresholdFunction__hxx__
 #define __ivq__ITK__ThresholdFunction__hxx__