From f762078bd4c0284a3e42ddf0c9e78b2e541afd57 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Leonardo=20Fl=C3=B3rez-Valencia?= Date: Mon, 9 Oct 2017 11:22:19 -0500 Subject: [PATCH] ... --- CMakeLists.txt | 10 - cmake/cpPlgInstallCommands.cmake | 15 + .../cpPlgUninstall.cmake.in | 0 config/install_mxe.sh | 12 +- config/mxe.patch | 11 +- lib/ivq/Config.h.in | 67 +++++ lib/ivq/ITK/BooleanMapSaliencyFunction.h | 11 +- lib/ivq/ITK/BooleanMapSaliencyFunction.hxx | 10 +- lib/ivq/ITK/CPRImageFilter.h | 17 +- lib/ivq/ITK/CPRImageFilter.hxx | 42 +-- lib/ivq/ITK/ExtractLabelFunction.h | 11 +- lib/ivq/ITK/ExtractLabelFunction.hxx | 10 +- lib/ivq/ITK/Graph.h | 167 +++++++++++ lib/ivq/ITK/Graph.hxx | 265 ++++++++++++++++++ lib/ivq/ITK/ImageMinimumSpanningTree.h | 72 +++++ lib/ivq/ITK/ImageMinimumSpanningTree.hxx | 71 +++++ lib/ivq/ITK/ImagePath.h | 92 ++++++ lib/ivq/ITK/ImagePath.hxx | 224 +++++++++++++++ lib/ivq/ITK/ImagePathReader.h | 81 ++++++ lib/ivq/ITK/ImagePathReader.hxx | 172 ++++++++++++ lib/ivq/ITK/ImagePathWriter.h | 65 +++++ lib/ivq/ITK/ImagePathWriter.hxx | 91 ++++++ lib/ivq/ITK/ImageROIFromFunction.h | 11 +- lib/ivq/ITK/ImageROIFromFunction.hxx | 10 +- lib/ivq/ITK/ImageSkeleton.h | 65 +++++ lib/ivq/ITK/ImageSkeleton.hxx | 98 +++++++ lib/ivq/ITK/ImageSkeletonReader.h | 81 ++++++ lib/ivq/ITK/ImageSkeletonReader.hxx | 208 ++++++++++++++ lib/ivq/ITK/ImageSkeletonWriter.h | 70 +++++ lib/ivq/ITK/ImageSkeletonWriter.hxx | 139 +++++++++ lib/ivq/ITK/ImageStatisticsFromSeeds.h | 11 +- lib/ivq/ITK/ImageStatisticsFromSeeds.hxx | 10 +- lib/ivq/ITK/ImageUnaryFunctionFilter.h | 10 +- lib/ivq/ITK/ImageUnaryFunctionFilter.hxx | 10 +- lib/ivq/ITK/IncrementalMeanAndVariance.h | 3 +- lib/ivq/ITK/IsoImageSlicer.h | 11 +- lib/ivq/ITK/IsoImageSlicer.hxx | 10 +- lib/ivq/ITK/MinimumSpanningTree.h | 74 +++++ lib/ivq/ITK/MinimumSpanningTree.hxx | 236 ++++++++++++++++ lib/ivq/ITK/PeakDetector.h | 3 +- lib/ivq/ITK/RasterContourFilter.h | 11 +- lib/ivq/ITK/RasterContourFilter.hxx | 12 +- .../RegionOfInterestWithPaddingImageFilter.h | 9 +- ...RegionOfInterestWithPaddingImageFilter.hxx | 9 +- lib/ivq/ITK/Simple3DCurve.cxx | 9 +- lib/ivq/ITK/Simple3DCurve.h | 12 +- lib/ivq/ITK/ThresholdFunction.h | 12 +- lib/ivq/ITK/ThresholdFunction.hxx | 10 +- 48 files changed, 2463 insertions(+), 197 deletions(-) rename cmake_uninstall.cmake.in => cmake/cpPlgUninstall.cmake.in (100%) create mode 100644 lib/ivq/ITK/Graph.h create mode 100644 lib/ivq/ITK/Graph.hxx create mode 100644 lib/ivq/ITK/ImageMinimumSpanningTree.h create mode 100644 lib/ivq/ITK/ImageMinimumSpanningTree.hxx create mode 100644 lib/ivq/ITK/ImagePath.h create mode 100644 lib/ivq/ITK/ImagePath.hxx create mode 100644 lib/ivq/ITK/ImagePathReader.h create mode 100644 lib/ivq/ITK/ImagePathReader.hxx create mode 100644 lib/ivq/ITK/ImagePathWriter.h create mode 100644 lib/ivq/ITK/ImagePathWriter.hxx create mode 100644 lib/ivq/ITK/ImageSkeleton.h create mode 100644 lib/ivq/ITK/ImageSkeleton.hxx create mode 100644 lib/ivq/ITK/ImageSkeletonReader.h create mode 100644 lib/ivq/ITK/ImageSkeletonReader.hxx create mode 100644 lib/ivq/ITK/ImageSkeletonWriter.h create mode 100644 lib/ivq/ITK/ImageSkeletonWriter.hxx create mode 100644 lib/ivq/ITK/MinimumSpanningTree.h create mode 100644 lib/ivq/ITK/MinimumSpanningTree.hxx diff --git a/CMakeLists.txt b/CMakeLists.txt index c343188..c601431 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -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$ diff --git a/cmake/cpPlgInstallCommands.cmake b/cmake/cpPlgInstallCommands.cmake index fe30b48..e62ede7 100644 --- a/cmake/cpPlgInstallCommands.cmake +++ b/cmake/cpPlgInstallCommands.cmake @@ -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$ diff --git a/cmake_uninstall.cmake.in b/cmake/cpPlgUninstall.cmake.in similarity index 100% rename from cmake_uninstall.cmake.in rename to cmake/cpPlgUninstall.cmake.in diff --git a/config/install_mxe.sh b/config/install_mxe.sh index e43c7dd..e23f5ac 100755 --- a/config/install_mxe.sh +++ b/config/install_mxe.sh @@ -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 diff --git a/config/mxe.patch b/config/mxe.patch index 1a354af..cdf60f1 100644 --- a/config/mxe.patch +++ b/config/mxe.patch @@ -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 \ diff --git a/lib/ivq/Config.h.in b/lib/ivq/Config.h.in index 46a0144..35b65ad 100644 --- a/lib/ivq/Config.h.in +++ b/lib/ivq/Config.h.in @@ -6,6 +6,7 @@ #define __ivq__Config__h__ #include +#include #if @cpPlugins_USE_VTK@ == 1 # define ivq_USE_VTK @@ -15,6 +16,72 @@ # 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$ diff --git a/lib/ivq/ITK/BooleanMapSaliencyFunction.h b/lib/ivq/ITK/BooleanMapSaliencyFunction.h index ce39ede..f5a1f9d 100644 --- a/lib/ivq/ITK/BooleanMapSaliencyFunction.h +++ b/lib/ivq/ITK/BooleanMapSaliencyFunction.h @@ -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 #endif // ITK_MANUAL_INSTANTIATION - #endif // __ivq__ITK__BooleanMapSaliencyFunction__h__ // eof - $RCSfile$ diff --git a/lib/ivq/ITK/BooleanMapSaliencyFunction.hxx b/lib/ivq/ITK/BooleanMapSaliencyFunction.hxx index 8084ac1..3733182 100644 --- a/lib/ivq/ITK/BooleanMapSaliencyFunction.hxx +++ b/lib/ivq/ITK/BooleanMapSaliencyFunction.hxx @@ -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__ diff --git a/lib/ivq/ITK/CPRImageFilter.h b/lib/ivq/ITK/CPRImageFilter.h index 6d42fa0..aa8bbb7 100644 --- a/lib/ivq/ITK/CPRImageFilter.h +++ b/lib/ivq/ITK/CPRImageFilter.h @@ -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 #include +#include #include 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 #endif // ITK_MANUAL_INSTANTIATION - #endif // __ivq__ITK__CPRImageFilter__h__ // eof - $RCSfile$ diff --git a/lib/ivq/ITK/CPRImageFilter.hxx b/lib/ivq/ITK/CPRImageFilter.hxx index 346cc0a..b07ee85 100644 --- a/lib/ivq/ITK/CPRImageFilter.hxx +++ b/lib/ivq/ITK/CPRImageFilter.hxx @@ -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 -// ------------------------------------------------------------------------- -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 diff --git a/lib/ivq/ITK/ExtractLabelFunction.h b/lib/ivq/ITK/ExtractLabelFunction.h index bd9f70b..3dcfa6f 100644 --- a/lib/ivq/ITK/ExtractLabelFunction.h +++ b/lib/ivq/ITK/ExtractLabelFunction.h @@ -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 #endif // ITK_MANUAL_INSTANTIATION - #endif // __ivq__ITK__ExtractLabelFunction__h__ // eof - $RCSfile$ diff --git a/lib/ivq/ITK/ExtractLabelFunction.hxx b/lib/ivq/ITK/ExtractLabelFunction.hxx index 1f009cf..5c84fac 100644 --- a/lib/ivq/ITK/ExtractLabelFunction.hxx +++ b/lib/ivq/ITK/ExtractLabelFunction.hxx @@ -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 index 0000000..7ea6094 --- /dev/null +++ b/lib/ivq/ITK/Graph.h @@ -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 +#include +#include +#include +#include + +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 +#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 index 0000000..4331ce0 --- /dev/null +++ b/lib/ivq/ITK/Graph.hxx @@ -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 index 0000000..6e18212 --- /dev/null +++ b/lib/ivq/ITK/ImageMinimumSpanningTree.h @@ -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 +#include +#include + +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 +#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 index 0000000..23b5c31 --- /dev/null +++ b/lib/ivq/ITK/ImageMinimumSpanningTree.hxx @@ -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 index 0000000..d5318f5 --- /dev/null +++ b/lib/ivq/ITK/ImagePath.h @@ -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 +#include + +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 +#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 index 0000000..81ac1d6 --- /dev/null +++ b/lib/ivq/ITK/ImagePath.hxx @@ -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 +#include + +// ------------------------------------------------------------------------- +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 index 0000000..af3575d --- /dev/null +++ b/lib/ivq/ITK/ImagePathReader.h @@ -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 + +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 +#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 index 0000000..43d0f69 --- /dev/null +++ b/lib/ivq/ITK/ImagePathReader.hxx @@ -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 index 0000000..20e5bdd --- /dev/null +++ b/lib/ivq/ITK/ImagePathWriter.h @@ -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 +#include + +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 +#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 index 0000000..af5b3c6 --- /dev/null +++ b/lib/ivq/ITK/ImagePathWriter.hxx @@ -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 + +// ------------------------------------------------------------------------- +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$ diff --git a/lib/ivq/ITK/ImageROIFromFunction.h b/lib/ivq/ITK/ImageROIFromFunction.h index 6aef0f9..3a50e64 100644 --- a/lib/ivq/ITK/ImageROIFromFunction.h +++ b/lib/ivq/ITK/ImageROIFromFunction.h @@ -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 #endif // ITK_MANUAL_INSTANTIATION - #endif // __ivq__ITK__ImageROIFromFunction__h__ // eof - $RCSfile$ diff --git a/lib/ivq/ITK/ImageROIFromFunction.hxx b/lib/ivq/ITK/ImageROIFromFunction.hxx index d7ba4e3..6c01510 100644 --- a/lib/ivq/ITK/ImageROIFromFunction.hxx +++ b/lib/ivq/ITK/ImageROIFromFunction.hxx @@ -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 index 0000000..e479df6 --- /dev/null +++ b/lib/ivq/ITK/ImageSkeleton.h @@ -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 +#include +#include + +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 +#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 index 0000000..7e93058 --- /dev/null +++ b/lib/ivq/ITK/ImageSkeleton.hxx @@ -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 index 0000000..3b1652d --- /dev/null +++ b/lib/ivq/ITK/ImageSkeletonReader.h @@ -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 + +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 +#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 index 0000000..f8df01d --- /dev/null +++ b/lib/ivq/ITK/ImageSkeletonReader.hxx @@ -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 index 0000000..8c45b47 --- /dev/null +++ b/lib/ivq/ITK/ImageSkeletonWriter.h @@ -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 +#include + +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 +#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 index 0000000..3541bcd --- /dev/null +++ b/lib/ivq/ITK/ImageSkeletonWriter.hxx @@ -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 + +// ------------------------------------------------------------------------- +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$ diff --git a/lib/ivq/ITK/ImageStatisticsFromSeeds.h b/lib/ivq/ITK/ImageStatisticsFromSeeds.h index c9c24f1..ef10e6c 100644 --- a/lib/ivq/ITK/ImageStatisticsFromSeeds.h +++ b/lib/ivq/ITK/ImageStatisticsFromSeeds.h @@ -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 #endif // ITK_MANUAL_INSTANTIATION - #endif // __ivq__ITK__ImageStatisticsFromSeeds__h__ // eof - $RCSfile$ diff --git a/lib/ivq/ITK/ImageStatisticsFromSeeds.hxx b/lib/ivq/ITK/ImageStatisticsFromSeeds.hxx index 2bf9a10..9518c54 100644 --- a/lib/ivq/ITK/ImageStatisticsFromSeeds.hxx +++ b/lib/ivq/ITK/ImageStatisticsFromSeeds.hxx @@ -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__ diff --git a/lib/ivq/ITK/ImageUnaryFunctionFilter.h b/lib/ivq/ITK/ImageUnaryFunctionFilter.h index 2be71e6..c8a3107 100644 --- a/lib/ivq/ITK/ImageUnaryFunctionFilter.h +++ b/lib/ivq/ITK/ImageUnaryFunctionFilter.h @@ -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__ diff --git a/lib/ivq/ITK/ImageUnaryFunctionFilter.hxx b/lib/ivq/ITK/ImageUnaryFunctionFilter.hxx index b90f73e..0d72de6 100644 --- a/lib/ivq/ITK/ImageUnaryFunctionFilter.hxx +++ b/lib/ivq/ITK/ImageUnaryFunctionFilter.hxx @@ -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__ diff --git a/lib/ivq/ITK/IncrementalMeanAndVariance.h b/lib/ivq/ITK/IncrementalMeanAndVariance.h index 39e6c2e..6b48c8f 100644 --- a/lib/ivq/ITK/IncrementalMeanAndVariance.h +++ b/lib/ivq/ITK/IncrementalMeanAndVariance.h @@ -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 +#include namespace ivq { diff --git a/lib/ivq/ITK/IsoImageSlicer.h b/lib/ivq/ITK/IsoImageSlicer.h index 22b4526..6ddb05a 100644 --- a/lib/ivq/ITK/IsoImageSlicer.h +++ b/lib/ivq/ITK/IsoImageSlicer.h @@ -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 #endif // ITK_MANUAL_INSTANTIATION - #endif // __ivq__ITK__IsoImageSlicer__h__ // eof - $RCSfile$ diff --git a/lib/ivq/ITK/IsoImageSlicer.hxx b/lib/ivq/ITK/IsoImageSlicer.hxx index cfcfc5e..7bb0532 100644 --- a/lib/ivq/ITK/IsoImageSlicer.hxx +++ b/lib/ivq/ITK/IsoImageSlicer.hxx @@ -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 index 0000000..7c5c5e2 --- /dev/null +++ b/lib/ivq/ITK/MinimumSpanningTree.h @@ -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 + +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 +#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 index 0000000..5058912 --- /dev/null +++ b/lib/ivq/ITK/MinimumSpanningTree.hxx @@ -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$ diff --git a/lib/ivq/ITK/PeakDetector.h b/lib/ivq/ITK/PeakDetector.h index 0dfa494..63e02ad 100644 --- a/lib/ivq/ITK/PeakDetector.h +++ b/lib/ivq/ITK/PeakDetector.h @@ -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 +#include #include #include diff --git a/lib/ivq/ITK/RasterContourFilter.h b/lib/ivq/ITK/RasterContourFilter.h index 2bec6f5..62305e0 100644 --- a/lib/ivq/ITK/RasterContourFilter.h +++ b/lib/ivq/ITK/RasterContourFilter.h @@ -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 #include -// ------------------------------------------------------------------------- namespace ivq { namespace ITK diff --git a/lib/ivq/ITK/RasterContourFilter.hxx b/lib/ivq/ITK/RasterContourFilter.hxx index 83eda54..07bad39 100644 --- a/lib/ivq/ITK/RasterContourFilter.hxx +++ b/lib/ivq/ITK/RasterContourFilter.hxx @@ -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__ diff --git a/lib/ivq/ITK/RegionOfInterestWithPaddingImageFilter.h b/lib/ivq/ITK/RegionOfInterestWithPaddingImageFilter.h index 4828d8f..8eed890 100644 --- a/lib/ivq/ITK/RegionOfInterestWithPaddingImageFilter.h +++ b/lib/ivq/ITK/RegionOfInterestWithPaddingImageFilter.h @@ -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__ diff --git a/lib/ivq/ITK/RegionOfInterestWithPaddingImageFilter.hxx b/lib/ivq/ITK/RegionOfInterestWithPaddingImageFilter.hxx index 14d1f0e..ac86e82 100644 --- a/lib/ivq/ITK/RegionOfInterestWithPaddingImageFilter.hxx +++ b/lib/ivq/ITK/RegionOfInterestWithPaddingImageFilter.hxx @@ -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__ diff --git a/lib/ivq/ITK/Simple3DCurve.cxx b/lib/ivq/ITK/Simple3DCurve.cxx index e5649d5..0495931 100644 --- a/lib/ivq/ITK/Simple3DCurve.cxx +++ b/lib/ivq/ITK/Simple3DCurve.cxx @@ -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 diff --git a/lib/ivq/ITK/Simple3DCurve.h b/lib/ivq/ITK/Simple3DCurve.h index c01abb9..e81feae 100644 --- a/lib/ivq/ITK/Simple3DCurve.h +++ b/lib/ivq/ITK/Simple3DCurve.h @@ -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 +#include #include #include diff --git a/lib/ivq/ITK/ThresholdFunction.h b/lib/ivq/ITK/ThresholdFunction.h index 690043c..7fd0134 100644 --- a/lib/ivq/ITK/ThresholdFunction.h +++ b/lib/ivq/ITK/ThresholdFunction.h @@ -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 - #include namespace ivq @@ -83,7 +80,6 @@ namespace ivq #ifndef ITK_MANUAL_INSTANTIATION # include #endif // ITK_MANUAL_INSTANTIATION - #endif // __ivq__ITK__ThresholdFunction__h__ // eof - $RCSfile$ diff --git a/lib/ivq/ITK/ThresholdFunction.hxx b/lib/ivq/ITK/ThresholdFunction.hxx index 090b278..5869adf 100644 --- a/lib/ivq/ITK/ThresholdFunction.hxx +++ b/lib/ivq/ITK/ThresholdFunction.hxx @@ -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__ -- 2.45.1