## == 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$
)
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$
prefix="$2"
shift
;;
- -suffix)
- suffix="$2"
- shift
- ;;
-cores)
cores="$2"
shift
## -- 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
if [ -z "$cores" ] ; then
cores="1"
fi
-if [ ! -z "$suffix" ] ; then
- qt_suffix="-qtlibinfix $suffix"
-fi
curr_dir=`pwd`
## -- Get mxe
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
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 \
#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$
-/* =======================================================================
- * @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__
#ifndef ITK_MANUAL_INSTANTIATION
# include <ivq/ITK/BooleanMapSaliencyFunction.hxx>
#endif // ITK_MANUAL_INSTANTIATION
-
#endif // __ivq__ITK__BooleanMapSaliencyFunction__h__
// eof - $RCSfile$
-/* =======================================================================
- * @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__
-/* =======================================================================
- * @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__
#include <itkImageToImageFilter.h>
#include <itkJoinSeriesImageFilter.h>
+#include <ivq/Config.h>
#include <ivq/ITK/IsoImageSlicer.h>
namespace ivq
itkSetMacro( SliceRadius, double );
itkSetObjectMacro( Interpolator, TInterpolateFunction );
- public:
- _TCurve* GetCurve( );
- const _TCurve* GetCurve( ) const;
- void SetCurve( _TCurve* curve );
+ ivqITKInputMacro( InputCurve, _TCurve );
protected:
CPRImageFilter( );
#ifndef ITK_MANUAL_INSTANTIATION
# include <ivq/ITK/CPRImageFilter.hxx>
#endif // ITK_MANUAL_INSTANTIATION
-
#endif // __ivq__ITK__CPRImageFilter__h__
// eof - $RCSfile$
-/* =======================================================================
- * @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 >::
: Superclass( ),
m_SliceRadius( 0 )
{
- this->Superclass::SetNumberOfRequiredInputs( 2 );
+ ivqITKInputConfigureMacro( InputCurve, _TCurve );
}
// -------------------------------------------------------------------------
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
-/* =======================================================================
- * @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__
#ifndef ITK_MANUAL_INSTANTIATION
# include <ivq/ITK/ExtractLabelFunction.hxx>
#endif // ITK_MANUAL_INSTANTIATION
-
#endif // __ivq__ITK__ExtractLabelFunction__h__
// eof - $RCSfile$
-/* =======================================================================
- * @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__
--- /dev/null
+// =========================================================================
+// @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$
--- /dev/null
+// =========================================================================
+// @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$
--- /dev/null
+// =========================================================================
+// @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$
--- /dev/null
+// =========================================================================
+// @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$
--- /dev/null
+// =========================================================================
+// @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$
--- /dev/null
+// =========================================================================
+// @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$
--- /dev/null
+// =========================================================================
+// @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$
--- /dev/null
+// =========================================================================
+// @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$
--- /dev/null
+// =========================================================================
+// @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$
--- /dev/null
+// =========================================================================
+// @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$
-/* =======================================================================
- * @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__
#ifndef ITK_MANUAL_INSTANTIATION
# include <ivq/ITK/ImageROIFromFunction.hxx>
#endif // ITK_MANUAL_INSTANTIATION
-
#endif // __ivq__ITK__ImageROIFromFunction__h__
// eof - $RCSfile$
-/* =======================================================================
- * @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__
--- /dev/null
+// =========================================================================
+// @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$
--- /dev/null
+// =========================================================================
+// @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$
--- /dev/null
+// =========================================================================
+// @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$
--- /dev/null
+// =========================================================================
+// @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$
--- /dev/null
+// =========================================================================
+// @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$
--- /dev/null
+// =========================================================================
+// @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$
-/* =======================================================================
- * @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__
#ifndef ITK_MANUAL_INSTANTIATION
# include <ivq/ITK/ImageStatisticsFromSeeds.hxx>
#endif // ITK_MANUAL_INSTANTIATION
-
#endif // __ivq__ITK__ImageStatisticsFromSeeds__h__
// eof - $RCSfile$
-/* =======================================================================
- * @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__
-/* =======================================================================
- * @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__
-/* =======================================================================
- * @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__
// @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
{
-/* =======================================================================
- * @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__
#ifndef ITK_MANUAL_INSTANTIATION
# include <ivq/ITK/IsoImageSlicer.hxx>
#endif // ITK_MANUAL_INSTANTIATION
-
#endif // __ivq__ITK__IsoImageSlicer__h__
// eof - $RCSfile$
-/* =======================================================================
- * @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__
--- /dev/null
+// =========================================================================
+// @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$
--- /dev/null
+// =========================================================================
+// @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$
// @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>
-/* =======================================================================
- * @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
-/* =======================================================================
- * @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__
-/* =======================================================================
- * @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__
-/* =======================================================================
- * @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__
-/* =======================================================================
- * @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>
-/* =======================================================================
- * @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>
-/* =======================================================================
- * @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
#ifndef ITK_MANUAL_INSTANTIATION
# include <ivq/ITK/ThresholdFunction.hxx>
#endif // ITK_MANUAL_INSTANTIATION
-
#endif // __ivq__ITK__ThresholdFunction__h__
// eof - $RCSfile$
-/* =======================================================================
- * @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__