--- /dev/null
+## =========================================================================
+## @author Leonardo Florez Valencia
+## @email florez-l@javeriana.edu.co
+## =========================================================================
+
+include_directories(
+ ${CMAKE_CURRENT_SOURCE_DIR}
+ ${CMAKE_CURRENT_BINARY_DIR}
+ )
+subdirs(fpa)
+
+## eof - $RCSfile$
--- /dev/null
+## =========================================================================
+## @author Leonardo Florez Valencia
+## @email florez-l@javeriana.edu.co
+## =========================================================================
+
+configure_file(Version.cxx.in "${CMAKE_CURRENT_BINARY_DIR}/Version.cxx" @ONLY)
+configure_file(Config.h.in "${CMAKE_CURRENT_BINARY_DIR}/Config.h" @ONLY)
+file(GLOB_RECURSE _common_src "${CMAKE_CURRENT_SOURCE_DIR}/Common/*.cxx")
+file(GLOB_RECURSE _filters_src "${CMAKE_CURRENT_SOURCE_DIR}/Filters/*.cxx")
+file(GLOB_RECURSE _functors_src "${CMAKE_CURRENT_SOURCE_DIR}/Functors/*.cxx")
+file(GLOB_RECURSE _common_hdr "${CMAKE_CURRENT_SOURCE_DIR}/Common/*.h")
+file(GLOB_RECURSE _filters_hdr "${CMAKE_CURRENT_SOURCE_DIR}/Filters/*.h")
+file(GLOB_RECURSE _functors_hdr "${CMAKE_CURRENT_SOURCE_DIR}/Functors/*.h")
+file(GLOB_RECURSE _common_hrc "${CMAKE_CURRENT_SOURCE_DIR}/Common/*.hxx")
+file(GLOB_RECURSE _filters_hrc "${CMAKE_CURRENT_SOURCE_DIR}/Filters/*.hxx")
+file(GLOB_RECURSE _functors_hrc "${CMAKE_CURRENT_SOURCE_DIR}/Functors/*.hxx")
+if(VTK_FOUND)
+ file(GLOB_RECURSE _vtk_src "${CMAKE_CURRENT_SOURCE_DIR}/VTK/*.cxx")
+ file(GLOB_RECURSE _vtk_hdr "${CMAKE_CURRENT_SOURCE_DIR}/VTK/*.h")
+ file(GLOB_RECURSE _vtk_hrc "${CMAKE_CURRENT_SOURCE_DIR}/VTK/*.hxx")
+endif(VTK_FOUND)
+
+## =====================
+## == Compile library ==
+## =====================
+
+add_library(
+ fpa SHARED
+ "${CMAKE_CURRENT_BINARY_DIR}/Version.cxx"
+ "${CMAKE_CURRENT_BINARY_DIR}/Config.h"
+ ${_common_src}
+ ${_filters_src}
+ ${_functors_src}
+ ${_vtk_src}
+ )
+generate_export_header(fpa)
+set_property(TARGET fpa PROPERTY VERSION ${prj_VERSION})
+set_property(TARGET fpa PROPERTY SOVERSION ${prj_SHORT_VERSION})
+set_property(
+ TARGET fpa PROPERTY INTERFACE_fpa_MAJOR_VERSION ${prj_MAJ_VERSION}
+ )
+set_property(
+ TARGET fpa APPEND PROPERTY COMPATIBLE_INTERFACE_STRING ${prj_MAJ_VERSION}
+ )
+target_link_libraries(fpa PUBLIC ${ITK_LIBRARIES})
+
+## ========================
+## == Installation rules ==
+## ========================
+
+install(
+ TARGETS fpa
+ EXPORT "${targets_export_name}"
+ LIBRARY DESTINATION "lib"
+ ARCHIVE DESTINATION "lib"
+ RUNTIME DESTINATION "bin"
+ INCLUDES DESTINATION "${include_install_dir}"
+ )
+install(
+ DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
+ DESTINATION "${include_install_dir}"
+ FILES_MATCHING PATTERN "*.h"
+ )
+install(
+ DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
+ DESTINATION "${include_install_dir}"
+ FILES_MATCHING PATTERN "*.hxx"
+ )
+install(
+ FILES "${CMAKE_CURRENT_BINARY_DIR}/fpa_export.h"
+ DESTINATION "${include_install_dir}/fpa"
+ )
+install(
+ FILES "${CMAKE_CURRENT_BINARY_DIR}/Config.h"
+ DESTINATION "${include_install_dir}/fpa"
+ )
+
+## eof - $RCSfile$
--- /dev/null
+// =========================================================================
+// @author Leonardo Florez Valencia
+// @email florez-l@javeriana.edu.co
+// =========================================================================
+#ifndef __fpa__Common__Image__PolyLineParametricPathReader__h__
+#define __fpa__Common__Image__PolyLineParametricPathReader__h__
+
+#include <itkProcessObject.h>
+
+namespace fpa
+{
+ namespace Common
+ {
+ namespace Image
+ {
+ /**
+ */
+ template< class _TPath >
+ class PolyLineParametricPathReader
+ : public itk::ProcessObject
+ {
+ public:
+ // Basic types
+ typedef PolyLineParametricPathReader Self;
+ typedef itk::ProcessObject Superclass;
+ typedef itk::SmartPointer< Self > Pointer;
+ typedef itk::SmartPointer< const Self > ConstPointer;
+
+ typedef _TPath TPath;
+
+ public:
+ itkNewMacro( Self );
+ itkTypeMacro( PolyLineParametricPathReader, 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:
+ PolyLineParametricPathReader( );
+ virtual ~PolyLineParametricPathReader( );
+
+ virtual void GenerateData( ) override;
+
+ // Do nothing
+ virtual void GenerateOutputInformation( ) override
+ { }
+
+ private:
+ // Purposely not implemented
+ PolyLineParametricPathReader( const Self& );
+ void operator=( const Self& );
+
+ protected:
+ std::string m_FileName;
+ };
+
+ } // ecapseman
+
+ } // ecapseman
+
+} // ecapseman
+
+#ifndef ITK_MANUAL_INSTANTIATION
+# include <fpa/Common/Image/PolyLineParametricPathReader.hxx>
+#endif // ITK_MANUAL_INSTANTIATION
+#endif // __fpa__Common__Image__PolyLineParametricPathReader__h__
+
+// eof - $RCSfile$
--- /dev/null
+// =========================================================================
+// @author Leonardo Florez Valencia
+// @email florez-l@javeriana.edu.co
+// =========================================================================
+#ifndef __fpa__Common__Image__PolyLineParametricPathReader__hxx__
+#define __fpa__Common__Image__PolyLineParametricPathReader__hxx__
+
+// -------------------------------------------------------------------------
+template< class _TPath >
+_TPath* fpa::Common::Image::PolyLineParametricPathReader< _TPath >::
+GetOutput( )
+{
+ return(
+ itkDynamicCastInDebugMode< TPath* >( this->GetPrimaryOutput( ) )
+ );
+}
+
+// -------------------------------------------------------------------------
+template< class _TPath >
+_TPath* fpa::Common::Image::PolyLineParametricPathReader< _TPath >::
+GetOutput( unsigned int i )
+{
+ return(
+ itkDynamicCastInDebugMode< TPath* >(
+ this->itk::ProcessObject::GetOutput( i )
+ )
+ );
+}
+
+// -------------------------------------------------------------------------
+template< class _TPath >
+void fpa::Common::Image::PolyLineParametricPathReader< _TPath >::
+GraftOutput( itk::DataObject* out )
+{
+ this->GraftNthOutput( 0, out );
+}
+
+// -------------------------------------------------------------------------
+template< class _TPath >
+void fpa::Common::Image::PolyLineParametricPathReader< _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 fpa::Common::Image::PolyLineParametricPathReader< _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
+fpa::Common::Image::PolyLineParametricPathReader< _TPath >::
+MakeOutput( itk::ProcessObject::DataObjectPointerArraySizeType i )
+{
+ return( TPath::New( ).GetPointer( ) );
+}
+
+// -------------------------------------------------------------------------
+template< class _TPath >
+fpa::Common::Image::PolyLineParametricPathReader< _TPath >::
+PolyLineParametricPathReader( )
+ : 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 >
+fpa::Common::Image::PolyLineParametricPathReader< _TPath >::
+~PolyLineParametricPathReader( )
+{
+}
+
+// -------------------------------------------------------------------------
+template< class _TPath >
+void fpa::Common::Image::PolyLineParametricPathReader< _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 // __fpa__Common__Image__PolyLineParametricPathReader__hxx__
+
+// eof - $RCSfile$
--- /dev/null
+// =========================================================================
+// @author Leonardo Florez Valencia
+// @email florez-l@javeriana.edu.co
+// =========================================================================
+#ifndef __fpa__Common__Image__PolyLineParametricPathWriter__h__
+#define __fpa__Common__Image__PolyLineParametricPathWriter__h__
+
+#include <itkProcessObject.h>
+
+namespace fpa
+{
+ namespace Common
+ {
+ namespace Image
+ {
+ /**
+ */
+ template< class _TPath >
+ class PolyLineParametricPathWriter
+ : public itk::ProcessObject
+ {
+ public:
+ // Basic types
+ typedef PolyLineParametricPathWriter Self;
+ typedef itk::ProcessObject Superclass;
+ typedef itk::SmartPointer< Self > Pointer;
+ typedef itk::SmartPointer< const Self > ConstPointer;
+
+ typedef _TPath TPath;
+
+ public:
+ itkNewMacro( Self );
+ itkTypeMacro( PolyLineParametricPathWriter, itk::ProcessObject );
+
+ itkGetConstMacro( FileName, std::string );
+ itkSetMacro( FileName, std::string );
+
+ public:
+ const TPath* GetInput( ) const;
+ void SetInput( const TPath* path );
+ virtual void Update( ) override;
+
+ protected:
+ PolyLineParametricPathWriter( );
+ virtual ~PolyLineParametricPathWriter( );
+
+ virtual void GenerateData( ) override;
+
+ private:
+ // Purposely not implemented
+ PolyLineParametricPathWriter( const Self& );
+ void operator=( const Self& );
+
+ protected:
+ std::string m_FileName;
+ };
+
+ } // ecapseman
+
+ } // ecapseman
+
+} // ecapseman
+
+#ifndef ITK_MANUAL_INSTANTIATION
+# include <fpa/Common/Image/PolyLineParametricPathWriter.hxx>
+#endif // ITK_MANUAL_INSTANTIATION
+#endif // __fpa__Common__Image__PolyLineParametricPathWriter__h__
+
+// eof - $RCSfile$
--- /dev/null
+// =========================================================================
+// @author Leonardo Florez Valencia
+// @email florez-l@javeriana.edu.co
+// =========================================================================
+#ifndef __fpa__Common__Image__PolyLineParametricPathWriter__hxx__
+#define __fpa__Common__Image__PolyLineParametricPathWriter__hxx__
+
+#include <fstream>
+
+// -------------------------------------------------------------------------
+template< class _TPath >
+const _TPath* fpa::Common::Image::PolyLineParametricPathWriter< _TPath >::
+GetInput( ) const
+{
+ return(
+ dynamic_cast< const TPath* >(
+ this->itk::ProcessObject::GetInput( 0 )
+ )
+ );
+}
+
+// -------------------------------------------------------------------------
+template< class _TPath >
+void fpa::Common::Image::PolyLineParametricPathWriter< _TPath >::
+SetInput( const _TPath* path )
+{
+ this->itk::ProcessObject::SetNthInput( 0, const_cast< TPath* >( path ) );
+}
+
+// -------------------------------------------------------------------------
+template< class _TPath >
+void fpa::Common::Image::PolyLineParametricPathWriter< _TPath >::
+Update( )
+{
+ TPath* input = const_cast< TPath* >( this->GetInput( ) );
+ if( input != NULL )
+ {
+ input->UpdateOutputInformation( );
+ input->UpdateOutputData( );
+ this->GenerateData( );
+ this->ReleaseInputs( );
+
+ } // fi
+}
+
+// -------------------------------------------------------------------------
+template< class _TPath >
+fpa::Common::Image::PolyLineParametricPathWriter< _TPath >::
+PolyLineParametricPathWriter( )
+ : Superclass( ),
+ m_FileName( "" )
+{
+ this->SetNumberOfRequiredInputs( 1 );
+}
+
+// -------------------------------------------------------------------------
+template< class _TPath >
+fpa::Common::Image::PolyLineParametricPathWriter< _TPath >::
+~PolyLineParametricPathWriter( )
+{
+}
+
+// -------------------------------------------------------------------------
+template< class _TPath >
+void fpa::Common::Image::PolyLineParametricPathWriter< _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 // __fpa__Common__Image__PolyLineParametricPathWriter__hxx__
+
+// eof - $RCSfile$
--- /dev/null
+// =========================================================================
+// @author Leonardo Florez Valencia
+// @email florez-l@javeriana.edu.co
+// =========================================================================
+#ifndef __fpa__Common__Image__SkeletonReader__h__
+#define __fpa__Common__Image__SkeletonReader__h__
+
+#include <itkProcessObject.h>
+
+namespace fpa
+{
+ namespace Common
+ {
+ namespace Image
+ {
+ /**
+ */
+ template< class _TSkeleton >
+ class SkeletonReader
+ : public itk::ProcessObject
+ {
+ public:
+ // Basic types
+ typedef SkeletonReader Self;
+ typedef itk::ProcessObject Superclass;
+ typedef itk::SmartPointer< Self > Pointer;
+ typedef itk::SmartPointer< const Self > ConstPointer;
+
+ typedef _TSkeleton TSkeleton;
+
+ public:
+ itkNewMacro( Self );
+ itkTypeMacro( SkeletonReader, 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:
+ SkeletonReader( );
+ virtual ~SkeletonReader( );
+
+ virtual void GenerateData( ) override;
+
+ // Do nothing
+ virtual void GenerateOutputInformation( ) override
+ { }
+
+ private:
+ // Purposely not implemented
+ SkeletonReader( const Self& );
+ void operator=( const Self& );
+
+ protected:
+ std::string m_FileName;
+ };
+
+ } // ecapseman
+
+ } // ecapseman
+
+} // ecapseman
+
+#ifndef ITK_MANUAL_INSTANTIATION
+# include <fpa/Common/Image/SkeletonReader.hxx>
+#endif // ITK_MANUAL_INSTANTIATION
+#endif // __fpa__Common__Image__SkeletonReader__h__
+
+// eof - $RCSfile$
--- /dev/null
+// =========================================================================
+// @author Leonardo Florez Valencia
+// @email florez-l@javeriana.edu.co
+// =========================================================================
+#ifndef __fpa__Common__Image__SkeletonReader__hxx__
+#define __fpa__Common__Image__SkeletonReader__hxx__
+
+// -------------------------------------------------------------------------
+template< class _TSkeleton >
+_TSkeleton* fpa::Common::Image::SkeletonReader< _TSkeleton >::
+GetOutput( )
+{
+ return(
+ itkDynamicCastInDebugMode< TSkeleton* >( this->GetPrimaryOutput( ) )
+ );
+}
+
+// -------------------------------------------------------------------------
+template< class _TSkeleton >
+_TSkeleton* fpa::Common::Image::SkeletonReader< _TSkeleton >::
+GetOutput( unsigned int i )
+{
+ return(
+ itkDynamicCastInDebugMode< TSkeleton* >(
+ this->itk::ProcessObject::GetOutput( i )
+ )
+ );
+}
+
+// -------------------------------------------------------------------------
+template< class _TSkeleton >
+void fpa::Common::Image::SkeletonReader< _TSkeleton >::
+GraftOutput( itk::DataObject* out )
+{
+ this->GraftNthOutput( 0, out );
+}
+
+// -------------------------------------------------------------------------
+template< class _TSkeleton >
+void fpa::Common::Image::SkeletonReader< _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::Common::Image::SkeletonReader< _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::Common::Image::SkeletonReader< _TSkeleton >::
+MakeOutput( itk::ProcessObject::DataObjectPointerArraySizeType i )
+{
+ return( TSkeleton::New( ).GetPointer( ) );
+}
+
+// -------------------------------------------------------------------------
+template< class _TSkeleton >
+fpa::Common::Image::SkeletonReader< _TSkeleton >::
+SkeletonReader( )
+ : 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::Common::Image::SkeletonReader< _TSkeleton >::
+~SkeletonReader( )
+{
+}
+
+// -------------------------------------------------------------------------
+template< class _TSkeleton >
+void fpa::Common::Image::SkeletonReader< _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 // __fpa__Common__Image__SkeletonReader__hxx__
+
+// eof - $RCSfile$
--- /dev/null
+// =========================================================================
+// @author Leonardo Florez Valencia
+// @email florez-l@javeriana.edu.co
+// =========================================================================
+#ifndef __fpa__Common__Image__SkeletonWriter__h__
+#define __fpa__Common__Image__SkeletonWriter__h__
+
+#include <itkProcessObject.h>
+
+namespace fpa
+{
+ namespace Common
+ {
+ namespace Image
+ {
+ /**
+ */
+ template< class _TSkeleton >
+ class SkeletonWriter
+ : public itk::ProcessObject
+ {
+ public:
+ // Basic types
+ typedef SkeletonWriter 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( SkeletonWriter, itk::ProcessObject );
+
+ itkGetConstMacro( FileName, std::string );
+ itkSetMacro( FileName, std::string );
+
+ public:
+ const TSkeleton* GetInput( ) const;
+ void SetInput( const TSkeleton* skeleton );
+ virtual void Update( ) override;
+
+ protected:
+ SkeletonWriter( );
+ virtual ~SkeletonWriter( );
+
+ virtual void GenerateData( ) override;
+
+ private:
+ // Purposely not implemented
+ SkeletonWriter( const Self& );
+ void operator=( const Self& );
+
+ protected:
+ std::string m_FileName;
+ };
+
+ } // ecapseman
+
+ } // ecapseman
+
+} // ecapseman
+
+#ifndef ITK_MANUAL_INSTANTIATION
+# include <fpa/Common/Image/SkeletonWriter.hxx>
+#endif // ITK_MANUAL_INSTANTIATION
+#endif // __fpa__Common__Image__SkeletonWriter__h__
+
+// eof - $RCSfile$
--- /dev/null
+// =========================================================================
+// @author Leonardo Florez Valencia
+// @email florez-l@javeriana.edu.co
+// =========================================================================
+#ifndef __fpa__Common__Image__SkeletonWriter__hxx__
+#define __fpa__Common__Image__SkeletonWriter__hxx__
+
+#include <fstream>
+
+// -------------------------------------------------------------------------
+template< class _TSkeleton >
+const _TSkeleton* fpa::Common::Image::SkeletonWriter< _TSkeleton >::
+GetInput( ) const
+{
+ return(
+ dynamic_cast< const TSkeleton* >(
+ this->itk::ProcessObject::GetInput( 0 )
+ )
+ );
+}
+
+// -------------------------------------------------------------------------
+template< class _TSkeleton >
+void fpa::Common::Image::SkeletonWriter< _TSkeleton >::
+SetInput( const _TSkeleton* skeleton )
+{
+ this->itk::ProcessObject::SetNthInput(
+ 0, const_cast< TSkeleton* >( skeleton )
+ );
+}
+
+// -------------------------------------------------------------------------
+template< class _TSkeleton >
+void fpa::Common::Image::SkeletonWriter< _TSkeleton >::
+Update( )
+{
+ TSkeleton* input = const_cast< TSkeleton* >( this->GetInput( ) );
+ if( input != NULL )
+ {
+ input->UpdateOutputInformation( );
+ input->UpdateOutputData( );
+ this->GenerateData( );
+ this->ReleaseInputs( );
+
+ } // fi
+}
+
+// -------------------------------------------------------------------------
+template< class _TSkeleton >
+fpa::Common::Image::SkeletonWriter< _TSkeleton >::
+SkeletonWriter( )
+ : Superclass( ),
+ m_FileName( "" )
+{
+ this->SetNumberOfRequiredInputs( 1 );
+}
+
+// -------------------------------------------------------------------------
+template< class _TSkeleton >
+fpa::Common::Image::SkeletonWriter< _TSkeleton >::
+~SkeletonWriter( )
+{
+}
+
+// -------------------------------------------------------------------------
+template< class _TSkeleton >
+void fpa::Common::Image::SkeletonWriter< _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 // __fpa__Common__Image__SkeletonWriter__hxx__
+
+// eof - $RCSfile$
--- /dev/null
+// =========================================================================
+// @author Leonardo Florez Valencia
+// @email florez-l@javeriana.edu.co
+// =========================================================================
+#include <fpa/Common/IncrementalMeanAndVariance.h>
+#include <cmath>
+
+// -------------------------------------------------------------------------
+fpa::Common::IncrementalMeanAndVariance::
+IncrementalMeanAndVariance( )
+{
+ this->Clear( );
+}
+
+// -------------------------------------------------------------------------
+fpa::Common::IncrementalMeanAndVariance::
+~IncrementalMeanAndVariance( )
+{
+}
+
+// -------------------------------------------------------------------------
+double fpa::Common::IncrementalMeanAndVariance::
+GetMean( ) const
+{
+ return( this->m_M );
+}
+
+// -------------------------------------------------------------------------
+double fpa::Common::IncrementalMeanAndVariance::
+GetVariance( ) const
+{
+ return( this->m_V );
+}
+
+// -------------------------------------------------------------------------
+double fpa::Common::IncrementalMeanAndVariance::
+GetDeviation( ) const
+{
+ return( std::sqrt( this->m_V ) );
+}
+
+// -------------------------------------------------------------------------
+unsigned long fpa::Common::IncrementalMeanAndVariance::
+GetNumberOfSamples( ) const
+{
+ return( ( unsigned long )( this->m_N ) );
+}
+
+// -------------------------------------------------------------------------
+void fpa::Common::IncrementalMeanAndVariance::
+Clear( )
+{
+ this->m_M = double( 0 );
+ this->m_V = double( 0 );
+ this->m_N = double( 0 );
+}
+
+// -------------------------------------------------------------------------
+void fpa::Common::IncrementalMeanAndVariance::
+AddValue( double v )
+{
+ this->m_N += double( 1 );
+ double d = v - this->m_M;
+ if( this->m_N > double( 1 ) )
+ {
+ double o = ( this->m_N - double( 2 ) ) / ( this->m_N - double( 1 ) );
+ this->m_V = ( o * this->m_V ) + ( ( d * d ) / this->m_N );
+ }
+ else
+ this->m_V = double( 0 );
+ this->m_M += d / this->m_N;
+}
+
+// eof - $RCSfile$
--- /dev/null
+// =========================================================================
+// @author Leonardo Florez Valencia
+// @email florez-l@javeriana.edu.co
+// =========================================================================
+#ifndef __fpa__Common__IncrementalMeanAndVariance__h__
+#define __fpa__Common__IncrementalMeanAndVariance__h__
+
+#include <fpa/fpa_export.h>
+
+namespace fpa
+{
+ namespace Common
+ {
+ /**
+ */
+ class FPA_EXPORT IncrementalMeanAndVariance
+ {
+ public:
+ typedef IncrementalMeanAndVariance Self;
+
+ public:
+ IncrementalMeanAndVariance( );
+ virtual ~IncrementalMeanAndVariance( );
+
+ double GetMean( ) const;
+ double GetVariance( ) const;
+ double GetDeviation( ) const;
+ unsigned long GetNumberOfSamples( ) const;
+
+ void Clear( );
+ void AddValue( double v );
+
+ protected:
+ double m_M;
+ double m_V;
+ double m_N;
+ };
+
+ } // ecapseman
+
+} // ecapseman
+
+#endif // __fpa__Common__IncrementalMeanAndVariance__h__
+// eof - $RCSfile$
--- /dev/null
+// =========================================================================
+// @author Leonardo Florez Valencia
+// @email florez-l@javeriana.edu.co
+// =========================================================================
+#include <fpa/Common/PeakDetector.h>
+#include <cmath>
+
+// -------------------------------------------------------------------------
+fpa::Common::PeakDetector::
+PeakDetector( )
+ : m_K( 3 ),
+ m_T( 3.5 ),
+ m_I( 0.5 )
+{
+}
+
+// -------------------------------------------------------------------------
+fpa::Common::PeakDetector::
+~PeakDetector( )
+{
+}
+
+// -------------------------------------------------------------------------
+unsigned long fpa::Common::PeakDetector::
+GetKernelSize( ) const
+{
+ return( this->m_K );
+}
+
+// -------------------------------------------------------------------------
+double fpa::Common::PeakDetector::
+GetThreshold( ) const
+{
+ return( this->m_T );
+}
+
+// -------------------------------------------------------------------------
+double fpa::Common::PeakDetector::
+GetInfluence( ) const
+{
+ return( this->m_I );
+}
+
+// -------------------------------------------------------------------------
+void fpa::Common::PeakDetector::
+SetKernelSize( unsigned long k )
+{
+ this->m_K = k;
+ this->Clear( );
+}
+
+// -------------------------------------------------------------------------
+void fpa::Common::PeakDetector::
+SetThreshold( double t )
+{
+ this->m_T = t;
+ this->Clear( );
+}
+
+// -------------------------------------------------------------------------
+void fpa::Common::PeakDetector::
+SetInfluence( double i )
+{
+ this->m_I = i;
+ this->Clear( );
+}
+
+// -------------------------------------------------------------------------
+void fpa::Common::PeakDetector::
+Clear( )
+{
+ this->m_X.clear( );
+ this->m_Y.clear( );
+ this->m_YF.clear( );
+ this->m_Avg.clear( );
+ this->m_STD.clear( );
+ this->m_Peaks.clear( );
+ this->m_MeanAndVar.Clear( );
+}
+
+// -------------------------------------------------------------------------
+const std::vector< double >& fpa::Common::PeakDetector::
+GetXValues( ) const
+{
+ return( this->m_X );
+}
+
+// -------------------------------------------------------------------------
+const std::vector< double >& fpa::Common::PeakDetector::
+GetYValues( ) const
+{
+ return( this->m_Y );
+}
+
+// -------------------------------------------------------------------------
+const std::vector< double >& fpa::Common::PeakDetector::
+GetFilteredYValues( ) const
+{
+ return( this->m_YF );
+}
+
+// -------------------------------------------------------------------------
+const std::vector< double >& fpa::Common::PeakDetector::
+GetAverages( ) const
+{
+ return( this->m_Avg );
+}
+
+// -------------------------------------------------------------------------
+const std::vector< double >& fpa::Common::PeakDetector::
+GetDeviations( ) const
+{
+ return( this->m_STD );
+}
+
+// -------------------------------------------------------------------------
+const std::vector< fpa::Common::PeakDetector::TPeak >& fpa::Common::
+PeakDetector::GetPeaks( ) const
+{
+ return( this->m_Peaks );
+}
+
+// -------------------------------------------------------------------------
+unsigned long fpa::Common::PeakDetector::
+GetNumberOfSamples( ) const
+{
+ return( this->m_X.size( ) );
+}
+
+// -------------------------------------------------------------------------
+fpa::Common::PeakDetector::
+TPeak fpa::Common::PeakDetector::
+AddValue( double x, double y )
+{
+ this->m_X.push_back( x );
+ this->m_Y.push_back( y );
+
+ if( this->m_YF.size( ) < this->m_K )
+ {
+ this->m_YF.push_back( y );
+ this->m_Avg.push_back( double( 0 ) );
+ this->m_STD.push_back( double( 0 ) );
+ this->m_Peaks.push_back( Self::NoPeak );
+
+ this->m_MeanAndVar.AddValue( y );
+ if( this->m_YF.size( ) == this->m_K )
+ {
+ this->m_Avg.push_back( this->m_MeanAndVar.GetMean( ) );
+ this->m_STD.push_back( this->m_MeanAndVar.GetDeviation( ) );
+
+ } // fi
+ }
+ else
+ {
+ unsigned long i = this->m_X.size( ) - 1;
+ if(
+ ( std::fabs( y - this->m_Avg[ i - 1 ] ) ) >
+ ( this->m_T * this->m_STD[ i - 1 ] )
+ )
+ {
+ this->m_Peaks.push_back(
+ ( y > this->m_Avg[ i - 1 ] )? Self::PosPeak: Self::NegPeak
+ );
+ this->m_YF.push_back(
+ ( this->m_I * y ) +
+ ( ( double( 1 ) - this->m_I ) * this->m_YF[ i - 1 ] )
+ );
+ }
+ else
+ {
+ this->m_Peaks.push_back( Self::NoPeak );
+ this->m_YF.push_back( y );
+
+ } // fi
+
+ this->m_MeanAndVar.Clear( );
+ unsigned long k = 0;
+ for( unsigned long j = i - this->m_K; j <= i; ++j, ++k )
+ this->m_MeanAndVar.AddValue( this->m_YF[ j ] );
+ this->m_Avg.push_back( this->m_MeanAndVar.GetMean( ) );
+ this->m_STD.push_back( this->m_MeanAndVar.GetDeviation( ) );
+
+ } // fi
+ return( this->m_Peaks.back( ) );
+}
+
+// eof - $RCSfile$
--- /dev/null
+// =========================================================================
+// @author Leonardo Florez Valencia
+// @email florez-l@javeriana.edu.co
+// =========================================================================
+#ifndef __fpa__Common__PeakDetector__h__
+#define __fpa__Common__PeakDetector__h__
+
+#include <vector>
+#include <fpa/fpa_export.h>
+#include <fpa/Common/IncrementalMeanAndVariance.h>
+
+namespace fpa
+{
+ namespace Common
+ {
+ /**
+ */
+ /**
+ * https://stackoverflow.com/questions/22583391/peak-signal-detection-in-realtime-timeseries-data
+ */
+ class FPA_EXPORT PeakDetector
+ {
+ public:
+ typedef PeakDetector Self;
+
+ enum TPeak
+ {
+ NoPeak = 0,
+ PosPeak,
+ NegPeak
+ };
+
+ public:
+ PeakDetector( );
+ virtual ~PeakDetector( );
+
+ unsigned long GetKernelSize( ) const;
+ double GetThreshold( ) const;
+ double GetInfluence( ) const;
+
+ void SetKernelSize( unsigned long k );
+ void SetThreshold( double t );
+ void SetInfluence( double i );
+
+ const std::vector< double >& GetXValues( ) const;
+ const std::vector< double >& GetYValues( ) const;
+ const std::vector< double >& GetFilteredYValues( ) const;
+ const std::vector< double >& GetAverages( ) const;
+ const std::vector< double >& GetDeviations( ) const;
+ const std::vector< TPeak >& GetPeaks( ) const;
+
+ void Clear( );
+ unsigned long GetNumberOfSamples( ) const;
+ TPeak AddValue( double x, double y );
+
+ protected:
+ unsigned long m_K;
+ double m_T;
+ double m_I;
+
+ std::vector< double > m_X;
+ std::vector< double > m_Y;
+ std::vector< double > m_YF;
+ std::vector< double > m_Avg;
+ std::vector< double > m_STD;
+ std::vector< TPeak > m_Peaks;
+ fpa::Common::IncrementalMeanAndVariance m_MeanAndVar;
+ };
+
+ } // ecapseman
+
+} // ecapseman
+
+#endif // __fpa__Common__PeakDetector__h__
+// eof - $RCSfile$
--- /dev/null
+// =========================================================================
+// @author Leonardo Florez Valencia
+// @email florez-l@javeriana.edu.co
+// =========================================================================
+#ifndef __fpa__Config__h__
+#define __fpa__Config__h__
+
+#include <itkMacro.h>
+
+#define VTK_FOUND @VTK_FOUND@
+#if VTK_FOUND == 1
+# define USE_VTK
+#else
+# undef USE_VTK
+#endif
+
+// -------------------------------------------------------------------------
+#define fpaTraitsMacro( __p__, __t__ ) \
+ typedef __p__ __t__::TFilter TFilter; \
+ typedef __p__ __t__::TMarksInterface TMarksInterface; \
+ typedef __p__ __t__::TSeedsInterface TSeedsInterface; \
+ typedef __p__ __t__::TInternalTraits::TInputValue TInputValue; \
+ typedef __p__ __t__::TInternalTraits::TMark TMark; \
+ typedef __p__ __t__::TInternalTraits::TNeighborhood TNeighborhood; \
+ typedef __p__ __t__::TInternalTraits::TNode TNode; \
+ typedef __p__ __t__::TInternalTraits::TNodes TNodes; \
+ typedef __p__ __t__::TInternalTraits::TOutputValue TOutputValue; \
+ typedef __p__ __t__::TInternalTraits::TPoint TPoint; \
+ typedef __p__ __t__::TInternalTraits::TSeed TSeed; \
+ typedef __p__ __t__::TInternalTraits::TSeeds TSeeds; \
+ typedef __p__ __t__::TInternalTraits::TVertex TVertex; \
+ itkStaticConstMacro( \
+ Dimension, unsigned int, __t__::TInternalTraits::Dimension \
+ )
+
+// -------------------------------------------------------------------------
+#define fpaInternalTraitsMacro( __p__, __t__ ) \
+ typedef __p__ __t__::TInputValue TInputValue; \
+ typedef __p__ __t__::TMark TMark; \
+ typedef __p__ __t__::TNeighborhood TNeighborhood; \
+ typedef __p__ __t__::TNode TNode; \
+ typedef __p__ __t__::TNodes TNodes; \
+ typedef __p__ __t__::TOutputValue TOutputValue; \
+ typedef __p__ __t__::TPoint TPoint; \
+ typedef __p__ __t__::TSeed TSeed; \
+ typedef __p__ __t__::TSeeds TSeeds; \
+ typedef __p__ __t__::TVertex TVertex; \
+ itkStaticConstMacro( Dimension, unsigned int, __t__::Dimension )
+
+// -------------------------------------------------------------------------
+#define fpaFilterInputMacro( __n__, __t__ ) \
+ __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__( __t__* i ) \
+ { \
+ this->itk::ProcessObject::SetNthInput( this->m_##__n__##Idx, i ); \
+ }
+
+// -------------------------------------------------------------------------
+#define fpaFilterInputConfigureMacro( __n__, __t__ ) \
+ this->m_##__n__##Idx = this->GetNumberOfRequiredInputs( ); \
+ this->itk::ProcessObject::SetNumberOfRequiredInputs( \
+ this->m_##__n__##Idx + 1 \
+ )
+
+// -------------------------------------------------------------------------
+#define fpaFilterOutputMacro( __n__, __t__ ) \
+ __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 fpaFilterOutputConfigureMacro( __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 // __fpa__Config__h__
+// eof - $RCSfile$
--- /dev/null
+// =========================================================================
+// @author Leonardo Florez Valencia
+// @email florez-l@javeriana.edu.co
+// =========================================================================
+
+#ifndef __fpa__DataStructures__Graph__h__
+#define __fpa__DataStructures__Graph__h__
+
+#include <map>
+#include <set>
+#include <vector>
+#include <itkDataObject.h>
+#include <itkObjectFactory.h>
+
+namespace fpa
+{
+ namespace DataStructures
+ {
+ /** \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 <fpa/DataStructures/Graph.hxx>
+#endif // ITK_MANUAL_INSTANTIATION
+#endif // __fpa__DataStructures__Graph__h__
+
+// eof - $RCSfile$
--- /dev/null
+// =========================================================================
+// @author Leonardo Florez Valencia
+// @email florez-l@javeriana.edu.co
+// =========================================================================
+#ifndef __fpa__DataStructures__Graph__hxx__
+#define __fpa__DataStructures__Graph__hxx__
+
+// -------------------------------------------------------------------------
+template< class _TVertex, class _TCost, class _TIndex, class _TIndexCompare >
+void fpa::DataStructures::Graph< _TVertex, _TCost, _TIndex, _TIndexCompare >::
+Clear( )
+{
+ this->m_Vertices.clear( );
+ this->m_Matrix.clear( );
+}
+
+// -------------------------------------------------------------------------
+template< class _TVertex, class _TCost, class _TIndex, class _TIndexCompare >
+bool fpa::DataStructures::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 fpa::DataStructures::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
+fpa::DataStructures::Graph< _TVertex, _TCost, _TIndex, _TIndexCompare >::
+TEdges&
+fpa::DataStructures::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
+fpa::DataStructures::Graph< _TVertex, _TCost, _TIndex, _TIndexCompare >::
+TEdges&
+fpa::DataStructures::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 fpa::DataStructures::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 fpa::DataStructures::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 fpa::DataStructures::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 >
+fpa::DataStructures::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 >
+fpa::DataStructures::Graph< _TVertex, _TCost, _TIndex, _TIndexCompare >::
+Graph( )
+ : Superclass( )
+{
+}
+
+// -------------------------------------------------------------------------
+template< class _TVertex, class _TCost, class _TIndex, class _TIndexCompare >
+fpa::DataStructures::Graph< _TVertex, _TCost, _TIndex, _TIndexCompare >::
+~Graph( )
+{
+}
+
+#endif // __fpa__DataStructures__Graph__hxx__
+// eof - $RCSfile$
--- /dev/null
+// =========================================================================
+// @author Leonardo Florez Valencia
+// @email florez-l@javeriana.edu.co
+// =========================================================================
+#ifndef __fpa__DataStructures__Image__MinimumSpanningTree__h__
+#define __fpa__DataStructures__Image__MinimumSpanningTree__h__
+
+#include <fpa/DataStructures/MinimumSpanningTree.h>
+#include <itkImage.h>
+#include <fpa/DataStructures/Image/PolyLineParametricPath.h>
+
+namespace fpa
+{
+ namespace DataStructures
+ {
+ namespace Image
+ {
+ /**
+ */
+ template< unsigned int _VDim >
+ class MinimumSpanningTree
+ : public fpa::DataStructures::MinimumSpanningTree< itk::Index< _VDim >, itk::Image< itk::Offset< _VDim >, _VDim > >
+ {
+ public:
+ typedef itk::Index< _VDim > TVertex;
+ typedef itk::Image< itk::Offset< _VDim >, _VDim > TDataStructuresImage;
+
+ typedef MinimumSpanningTree Self;
+ typedef itk::SmartPointer< Self > Pointer;
+ typedef itk::SmartPointer< const Self > ConstPointer;
+ typedef fpa::DataStructures::MinimumSpanningTree< TVertex, TDataStructuresImage > Superclass;
+
+ typedef typename Superclass::TCollision TCollision;
+ typedef typename Superclass::TCollisionsRow TCollisionsRow;
+ typedef typename Superclass::TCollisions TCollisions;
+ typedef typename Superclass::TVertices TVertices;
+
+ typedef fpa::DataStructures::Image::PolyLineParametricPath< _VDim > TPolyLineParametricPath;
+
+ public:
+ itkNewMacro( Self );
+ itkTypeMacro(
+ fpa::DataStructures::Image::MinimumSpanningTree,
+ fpa::DataStructures::MinimumSpanningTree
+ );
+
+ public:
+ virtual TVertex GetParent( const TVertex& v ) const override;
+ virtual void SetParent( const TVertex& v, const TVertex& p ) override;
+
+ void GetPolyLineParametricPath(
+ typename TPolyLineParametricPath::Pointer& path,
+ const TVertex& a
+ ) const;
+ void GetPolyLineParametricPath(
+ typename TPolyLineParametricPath::Pointer& path,
+ const TVertex& a, const TVertex& b
+ ) const;
+
+ protected:
+ MinimumSpanningTree( );
+ virtual ~MinimumSpanningTree( );
+
+ private:
+ MinimumSpanningTree( const Self& other );
+ Self& operator=( const Self& other );
+ };
+
+ } // ecapseman
+
+ } // ecapseman
+
+} // ecapseman
+
+#ifndef ITK_MANUAL_INSTANTIATION
+# include <fpa/DataStructures/Image/MinimumSpanningTree.hxx>
+#endif // ITK_MANUAL_INSTANTIATION
+#endif // __fpa__DataStructures__Image__MinimumSpanningTree__h__
+
+// eof - $RCSfile$
--- /dev/null
+// =========================================================================
+// @author Leonardo Florez Valencia
+// @email florez-l@javeriana.edu.co
+// =========================================================================
+#ifndef __fpa__DataStructures__Image__MinimumSpanningTree__hxx__
+#define __fpa__DataStructures__Image__MinimumSpanningTree__hxx__
+
+// -------------------------------------------------------------------------
+template< unsigned int _VDim >
+typename fpa::DataStructures::Image::MinimumSpanningTree< _VDim >::
+TVertex fpa::DataStructures::Image::MinimumSpanningTree< _VDim >::
+GetParent( const TVertex& v ) const
+{
+ return( v + this->GetPixel( v ) );
+}
+
+// -------------------------------------------------------------------------
+template< unsigned int _VDim >
+void fpa::DataStructures::Image::MinimumSpanningTree< _VDim >::
+SetParent( const TVertex& v, const TVertex& p )
+{
+ this->SetPixel( v, p - v );
+}
+
+// -------------------------------------------------------------------------
+template< unsigned int _VDim >
+void fpa::DataStructures::Image::MinimumSpanningTree< _VDim >::
+GetPolyLineParametricPath(
+ typename TPolyLineParametricPath::Pointer& path,
+ const TVertex& a
+ ) const
+{
+ TVertices v = this->GetPath( a );
+ if( path.IsNull( ) )
+ path = TPolyLineParametricPath::New( );
+ path->SetReferenceImage( this );
+ typename TVertices::const_iterator vIt = v.begin( );
+ for( ; vIt != v.end( ); ++vIt )
+ path->AddVertex( *vIt );
+}
+
+// -------------------------------------------------------------------------
+template< unsigned int _VDim >
+void fpa::DataStructures::Image::MinimumSpanningTree< _VDim >::
+GetPolyLineParametricPath(
+ typename TPolyLineParametricPath::Pointer& path,
+ const TVertex& a, const TVertex& b
+ ) const
+{
+ TVertices v = this->GetPath( a, b );
+ if( path.IsNull( ) )
+ path = TPolyLineParametricPath::New( );
+ path->SetReferenceImage( this );
+ typename TVertices::const_iterator vIt = v.begin( );
+ for( ; vIt != v.end( ); ++vIt )
+ path->AddVertex( *vIt );
+}
+
+// -------------------------------------------------------------------------
+template< unsigned int _VDim >
+fpa::DataStructures::Image::MinimumSpanningTree< _VDim >::
+MinimumSpanningTree( )
+ : Superclass( )
+{
+}
+
+// -------------------------------------------------------------------------
+template< unsigned int _VDim >
+fpa::DataStructures::Image::MinimumSpanningTree< _VDim >::
+~MinimumSpanningTree( )
+{
+}
+
+#endif // __fpa__DataStructures__Image__MinimumSpanningTree__hxx__
+// eof - $RCSfile$
--- /dev/null
+// =========================================================================
+// @author Leonardo Florez Valencia
+// @email florez-l@javeriana.edu.co
+// =========================================================================
+#ifndef __fpa__DataStructures__Image__PolyLineParametricPath__h__
+#define __fpa__DataStructures__Image__PolyLineParametricPath__h__
+
+#include <itkPolyLineParametricPath.h>
+#include <itkImageBase.h>
+
+namespace fpa
+{
+ namespace DataStructures
+ {
+ namespace Image
+ {
+ /**
+ */
+ template< unsigned int _VDim >
+ class PolyLineParametricPath
+ : public itk::PolyLineParametricPath< _VDim >
+ {
+ public:
+ typedef PolyLineParametricPath 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( PolyLineParametricPath, 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 );
+
+ template< class _TRefImage >
+ inline void SetReferenceImage( const _TRefImage* image )
+ {
+ this->SetSpacing( image->GetSpacing( ) );
+ this->SetOrigin( image->GetOrigin( ) );
+ this->SetDirection( image->GetDirection( ) );
+ }
+
+ virtual void Graft( itk::DataObject* o );
+
+ protected:
+ PolyLineParametricPath( );
+ virtual ~PolyLineParametricPath( );
+
+ virtual void _ComputeIndexToPhysicalPointMatrices( );
+
+ private:
+ // Purposely not implemented
+ PolyLineParametricPath( 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
+
+} // ecapseman
+
+#ifndef ITK_MANUAL_INSTANTIATION
+# include <fpa/DataStructures/Image/PolyLineParametricPath.hxx>
+#endif // ITK_MANUAL_INSTANTIATION
+
+#endif // __fpa__DataStructures__Image__PolyLineParametricPath__h__
+
+// eof - $RCSfile$
--- /dev/null
+// =========================================================================
+// @author Leonardo Florez Valencia
+// @email florez-l@javeriana.edu.co
+// =========================================================================
+
+#ifndef __fpa__DataStructures__Image__PolyLineParametricPath__hxx__
+#define __fpa__DataStructures__Image__PolyLineParametricPath__hxx__
+
+#include <itkMath.h>
+#include <itkNumericTraits.h>
+
+// -------------------------------------------------------------------------
+template< unsigned int _VDim >
+unsigned long fpa::DataStructures::Image::PolyLineParametricPath< _VDim >::
+GetSize( ) const
+{
+ return( this->GetVertexList( )->Size( ) );
+}
+
+// -------------------------------------------------------------------------
+template< unsigned int _VDim >
+typename fpa::DataStructures::Image::PolyLineParametricPath< _VDim >::
+TContinuousIndex
+fpa::DataStructures::Image::PolyLineParametricPath< _VDim >::
+GetContinuousVertex( unsigned long i ) const
+{
+ return( this->GetVertexList( )->GetElement( i ) );
+}
+
+// -------------------------------------------------------------------------
+template< unsigned int _VDim >
+typename fpa::DataStructures::Image::PolyLineParametricPath< _VDim >::
+TIndex fpa::DataStructures::Image::PolyLineParametricPath< _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 fpa::DataStructures::Image::PolyLineParametricPath< _VDim >::
+TPoint fpa::DataStructures::Image::PolyLineParametricPath< _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 fpa::DataStructures::Image::PolyLineParametricPath< _VDim >::
+SetSpacing( const TSpacing& spac )
+{
+ if( this->m_Spacing != spac )
+ {
+ this->m_Spacing = spac;
+ this->_ComputeIndexToPhysicalPointMatrices( );
+ this->Modified( );
+
+ } // fi
+}
+
+// -------------------------------------------------------------------------
+template< unsigned int _VDim >
+void fpa::DataStructures::Image::PolyLineParametricPath< _VDim >::
+SetSpacing( const double spac[ _VDim ] )
+{
+ this->SetSpacing( TSpacing( spac ) );
+}
+
+// -------------------------------------------------------------------------
+template< unsigned int _VDim >
+void fpa::DataStructures::Image::PolyLineParametricPath< _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 fpa::DataStructures::Image::PolyLineParametricPath< _VDim >::
+SetOrigin( const double ori[ _VDim ] )
+{
+ this->SetOrigin( TPoint( ori ) );
+}
+
+// -------------------------------------------------------------------------
+template< unsigned int _VDim >
+void fpa::DataStructures::Image::PolyLineParametricPath< _VDim >::
+SetOrigin( const float ori[ _VDim ] )
+{
+ this->SetOrigin( TPoint( ori ) );
+}
+
+// -------------------------------------------------------------------------
+template< unsigned int _VDim >
+void fpa::DataStructures::Image::PolyLineParametricPath< _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 fpa::DataStructures::Image::PolyLineParametricPath< _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 >
+fpa::DataStructures::Image::PolyLineParametricPath< _VDim >::
+PolyLineParametricPath( )
+ : 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 >
+fpa::DataStructures::Image::PolyLineParametricPath< _VDim >::
+~PolyLineParametricPath( )
+{
+}
+
+// -------------------------------------------------------------------------
+template< unsigned int _VDim >
+void fpa::DataStructures::Image::PolyLineParametricPath< _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 // __fpa__DataStructures__Image__PolyLineParametricPath__hxx__
+// eof - $RCSfile$
--- /dev/null
+// =========================================================================
+// @author Leonardo Florez Valencia
+// @email florez-l@javeriana.edu.co
+// =========================================================================
+
+#ifndef __fpa__DataStructures__Image__Skeleton__h__
+#define __fpa__DataStructures__Image__Skeleton__h__
+
+#include <vector>
+#include <fpa/DataStructures/Graph.h>
+#include <fpa/DataStructures/Image/PolyLineParametricPath.h>
+
+namespace fpa
+{
+ namespace DataStructures
+ {
+ namespace Image
+ {
+ /**
+ */
+ template< unsigned int _VDim >
+ class Skeleton
+ : public fpa::DataStructures::Graph< typename fpa::DataStructures::Image::PolyLineParametricPath< _VDim >::TIndex, typename fpa::DataStructures::Image::PolyLineParametricPath< _VDim >::Pointer, typename fpa::DataStructures::Image::PolyLineParametricPath< _VDim >::TIndex, typename fpa::DataStructures::Image::PolyLineParametricPath< _VDim >::TIndex::LexicographicCompare >
+ {
+ public:
+ typedef fpa::DataStructures::Image::PolyLineParametricPath< _VDim > TPath;
+ typedef typename TPath::TIndex TIndex;
+ typedef typename TIndex::LexicographicCompare TIndexCompare;
+ typedef typename TPath::Pointer TPathPointer;
+
+ itkStaticConstMacro( Dimension, unsigned int, _VDim );
+
+ typedef fpa::DataStructures::Graph< TIndex, TPathPointer, TIndex, TIndexCompare > Superclass;
+ typedef Skeleton Self;
+ typedef itk::SmartPointer< Self > Pointer;
+ typedef itk::SmartPointer< const Self > ConstPointer;
+
+ public:
+ itkNewMacro( Self );
+ itkTypeMacro( Skeleton, fpa::Image::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:
+ Skeleton( );
+ virtual ~Skeleton( );
+
+ private:
+ // Purposely not implemented
+ Skeleton( const Self& other );
+ Self& operator=( const Self& other );
+ };
+
+ } // ecapseman
+
+ } // ecapseman
+
+} // ecapseman
+
+#ifndef ITK_MANUAL_INSTANTIATION
+# include <fpa/DataStructures/Image/Skeleton.hxx>
+#endif // ITK_MANUAL_INSTANTIATION
+#endif // __fpa__DataStructures__Image__Skeleton__h__
+
+// eof - $RCSfile$
--- /dev/null
+// =========================================================================
+// @author Leonardo Florez Valencia
+// @email florez-l@javeriana.edu.co
+// =========================================================================
+#ifndef __fpa__DataStructures__Image__Skeleton__hxx__
+#define __fpa__DataStructures__Image__Skeleton__hxx__
+
+// -------------------------------------------------------------------------
+template< unsigned int _VDim >
+void fpa::DataStructures::Image::Skeleton< _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 fpa::DataStructures::Image::Skeleton< _VDim >::
+TPath* fpa::DataStructures::Image::Skeleton< _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 fpa::DataStructures::Image::Skeleton< _VDim >::TIndex >
+fpa::DataStructures::Image::Skeleton< _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 fpa::DataStructures::Image::Skeleton< _VDim >::TIndex >
+fpa::DataStructures::Image::Skeleton< _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 >
+fpa::DataStructures::Image::Skeleton< _VDim >::
+Skeleton( )
+ : Superclass( )
+{
+}
+
+// -------------------------------------------------------------------------
+template< unsigned int _VDim >
+fpa::DataStructures::Image::Skeleton< _VDim >::
+~Skeleton( )
+{
+}
+
+#endif // __fpa__DataStructures__Image__Skeleton__hxx__
+
+// eof - $RCSfile$
--- /dev/null
+// =========================================================================
+// @author Leonardo Florez Valencia
+// @email florez-l@javeriana.edu.co
+// =========================================================================
+#ifndef __fpa__DataStructures__MinimumSpanningTree__h__
+#define __fpa__DataStructures__MinimumSpanningTree__h__
+
+#include <vector>
+
+namespace fpa
+{
+ namespace DataStructures
+ {
+ /**
+ */
+ 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( fpa::Base::MinimumSpanningTree, _Superclass );
+
+ public:
+ const TCollisions& GetCollisions( ) const;
+ void SetCollisions( const TCollisions& collisions );
+
+ void ClearSeeds( );
+ void AddSeed( const TVertex& seed );
+
+ virtual TVertex GetParent( const TVertex& v ) const = 0;
+ virtual void SetParent( const TVertex& v, const TVertex& p ) = 0;
+
+ virtual TVertices GetPath( const TVertex& a ) const;
+ virtual TVertices GetPath( 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 <fpa/DataStructures/MinimumSpanningTree.hxx>
+#endif // ITK_MANUAL_INSTANTIATION
+#endif // __fpa__DataStructures__MinimumSpanningTree__h__
+
+// eof - $RCSfile$
--- /dev/null
+// =========================================================================
+// @author Leonardo Florez Valencia
+// @email florez-l@javeriana.edu.co
+// =========================================================================
+#ifndef __fpa__DataStructures__MinimumSpanningTree__hxx__
+#define __fpa__DataStructures__MinimumSpanningTree__hxx__
+
+// -------------------------------------------------------------------------
+template< class _TVertex, class _Superclass >
+const typename fpa::DataStructures::MinimumSpanningTree< _TVertex, _Superclass >::
+TCollisions& fpa::DataStructures::MinimumSpanningTree< _TVertex, _Superclass >::
+GetCollisions( ) const
+{
+ return( this->m_Collisions );
+}
+
+// -------------------------------------------------------------------------
+template< class _TVertex, class _Superclass >
+void fpa::DataStructures::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->Modified( );
+}
+
+// -------------------------------------------------------------------------
+template< class _TVertex, class _Superclass >
+void fpa::DataStructures::MinimumSpanningTree< _TVertex, _Superclass >::
+ClearSeeds( )
+{
+ this->m_Seeds.clear( );
+ this->Modified( );
+}
+
+// -------------------------------------------------------------------------
+template< class _TVertex, class _Superclass >
+void fpa::DataStructures::MinimumSpanningTree< _TVertex, _Superclass >::
+AddSeed( const _TVertex& seed )
+{
+ this->m_Seeds.push_back( seed );
+ this->Modified( );
+}
+
+// -------------------------------------------------------------------------
+template< class _TVertex, class _Superclass >
+typename fpa::DataStructures::MinimumSpanningTree< _TVertex, _Superclass >::
+TVertices fpa::DataStructures::MinimumSpanningTree< _TVertex, _Superclass >::
+GetPath( 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 fpa::DataStructures::MinimumSpanningTree< _TVertex, _Superclass >::
+TVertices fpa::DataStructures::MinimumSpanningTree< _TVertex, _Superclass >::
+GetPath( const _TVertex& a, const _TVertex& b ) const
+{
+ static const unsigned long _inf =
+ std::numeric_limits< unsigned long >::max( );
+
+ TVertices vertices;
+ TVertices pa = this->GetPath( a );
+ TVertices pb = this->GetPath( 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->GetPath(
+ a, this->m_Collisions[ fpath[ 0 ] ][ fpath[ 1 ] ].first
+ );
+
+ // Intermediary paths
+ for( unsigned int i = 1; i < N - 1; ++i )
+ {
+ TVertices ipath =
+ this->GetPath(
+ 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->GetPath(
+ 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 >
+fpa::DataStructures::MinimumSpanningTree< _TVertex, _Superclass >::
+MinimumSpanningTree( )
+ : Superclass( )
+{
+}
+
+// -------------------------------------------------------------------------
+template< class _TVertex, class _Superclass >
+fpa::DataStructures::MinimumSpanningTree< _TVertex, _Superclass >::
+~MinimumSpanningTree( )
+{
+}
+
+#endif // __fpa__DataStructures__MinimumSpanningTree__hxx__
+// eof - $RCSfile$
--- /dev/null
+// =========================================================================
+// @author Leonardo Florez Valencia
+// @email florez-l@javeriana.edu.co
+// =========================================================================
+#ifndef __fpa__Filters__Algorithm__h__
+#define __fpa__Filters__Algorithm__h__
+
+#include <set>
+#include <itkConceptChecking.h>
+#include <fpa/Config.h>
+#include <fpa/Filters/Event.h>
+
+namespace fpa
+{
+ namespace Filters
+ {
+ /**
+ */
+ template< class _TTraits >
+ class Algorithm
+ : public _TTraits::TFilter,
+ public _TTraits::TMarksInterface,
+ public _TTraits::TSeedsInterface
+ {
+ public:
+ typedef _TTraits TTraits;
+ fpaTraitsMacro( typename, TTraits );
+
+ typedef TFilter Superclass;
+ typedef Algorithm Self;
+ typedef itk::SmartPointer< Self > Pointer;
+ typedef itk::SmartPointer< const Self > ConstPointer;
+
+ typedef fpa::Filters::Event< TVertex > TEvent;
+
+ protected:
+ itkConceptMacro(
+ Check_Marks,
+ ( itk::Concept::IsUnsignedInteger< TMark > )
+ );
+
+ public:
+ itkTypeMacro( fpa::Filters::Image::Algorithm, TFilter );
+
+ itkBooleanMacro( VisualDebug );
+ itkGetConstMacro( VisualDebug, bool );
+ itkSetMacro( VisualDebug, bool );
+
+ itkGetConstMacro( InitValue, TOutputValue );
+ itkSetMacro( InitValue, TOutputValue );
+
+ public:
+ virtual itk::ModifiedTimeType GetMTime( ) const override;
+ virtual void InvokeEvent( const itk::EventObject& e );
+ virtual void InvokeEvent( const itk::EventObject& e ) const;
+
+ protected:
+ Algorithm( );
+ virtual ~Algorithm( );
+
+ virtual void GenerateData( ) override;
+
+ // Object association
+ void _Associate( itk::Object* o );
+ void _Deassociate( itk::Object* o );
+ void _DeassociateAll( );
+
+ // Preparation and termination
+ virtual void _BeforeGenerateData( );
+ virtual void _AfterGenerateData( );
+ virtual void _Reinitialize( );
+
+ // Memory allocation
+ virtual void _ConfigureOutputs( ) = 0;
+
+ // Value assignation/recuperation
+ virtual const itk::DataObject* _GetReferenceInput( ) const;
+ virtual TInputValue _GetInputValue( const TVertex& v ) const = 0;
+ virtual TInputValue _GetInputValue( const TNode& n ) const;
+ virtual TOutputValue _GetOutputValue( const TVertex& v ) const = 0;
+ virtual TOutputValue _GetOutputValue( const TNode& n ) const;
+ virtual TNeighborhood _GetNeighbors( const TVertex& v ) const = 0;
+ virtual void _UpdateOutputValue( TNode& n ) = 0;
+
+ // Queue management
+ virtual void _QueueClear( ) = 0;
+ virtual TNode _QueuePop( ) = 0;
+ virtual void _QueuePush( const TNode& n ) = 0;
+ virtual unsigned long _QueueSize( ) const = 0;
+
+ // Value update according to the particular algorithm
+ virtual void _ComputeOutputValue( TNode& n ) = 0;
+
+ private:
+ // Purposely not implemented.
+ Algorithm( const Self& other );
+ Self& operator=( const Self& other );
+
+ protected:
+ bool m_VisualDebug;
+ TOutputValue m_InitValue;
+
+ std::set< itk::Object* > m_AssociatedObjects;
+ };
+
+ } // ecapseman
+
+} // ecapseman
+
+#ifndef ITK_MANUAL_INSTANTIATION
+# include <fpa/Filters/Algorithm.hxx>
+#endif // ITK_MANUAL_INSTANTIATION
+
+#endif // __fpa__Filters__Algorithm__h__
+// eof - $RCSfile$
--- /dev/null
+// =========================================================================
+// @author Leonardo Florez Valencia
+// @email florez-l@javeriana.edu.co
+// =========================================================================
+#ifndef __fpa__Filters__Algorithm__hxx__
+#define __fpa__Filters__Algorithm__hxx__
+
+#include <itkDataObject.h>
+#include <fpa/Functors/BaseVertexFunction.h>
+
+// -------------------------------------------------------------------------
+template< class _TTraits >
+itk::ModifiedTimeType fpa::Filters::Algorithm< _TTraits >::
+GetMTime( ) const
+{
+ itk::ModifiedTimeType q = this->Superclass::GetMTime( );
+ itk::ModifiedTimeType t;
+ for( itk::Object* o: this->m_AssociatedObjects )
+ {
+ if( o != NULL )
+ {
+ t = o->GetMTime( );
+ q = ( q < t )? q: t;
+
+ } // fi
+
+ } // rof
+ return( q );
+}
+
+// -------------------------------------------------------------------------
+template< class _TTraits >
+void fpa::Filters::Algorithm< _TTraits >::
+InvokeEvent( const itk::EventObject& e )
+{
+ TEvent a;
+ if( a.CheckEvent( &e ) )
+ {
+ if( this->m_VisualDebug )
+ this->Superclass::InvokeEvent( e );
+ }
+ else
+ this->Superclass::InvokeEvent( e );
+}
+
+// -------------------------------------------------------------------------
+template< class _TTraits >
+void fpa::Filters::Algorithm< _TTraits >::
+InvokeEvent( const itk::EventObject& e ) const
+{
+ TEvent a;
+ if( a.CheckEvent( &e ) )
+ {
+ if( this->m_VisualDebug )
+ this->Superclass::InvokeEvent( e );
+ }
+ else
+ this->Superclass::InvokeEvent( e );
+}
+
+// -------------------------------------------------------------------------
+template< class _TTraits >
+fpa::Filters::Algorithm< _TTraits >::
+Algorithm( )
+ : Superclass( ),
+ TMarksInterface( this ),
+ TSeedsInterface( this ),
+ m_VisualDebug( false ),
+ m_InitValue( TOutputValue( 0 ) )
+{
+}
+
+// -------------------------------------------------------------------------
+template< class _TTraits >
+fpa::Filters::Algorithm< _TTraits >::
+~Algorithm( )
+{
+}
+
+// -------------------------------------------------------------------------
+template< class _TTraits >
+void fpa::Filters::Algorithm< _TTraits >::
+GenerateData( )
+{
+ // Init algorithm
+ this->InvokeEvent( itk::StartEvent( ) );
+ this->_BeforeGenerateData( );
+ this->_ConfigureOutputs( );
+ this->_PrepareSeeds( this->_GetReferenceInput( ) );
+ this->_InitCollisions( this->GetSeeds( ).size( ) );
+
+ // Init queue
+ for( TNode seed: this->GetSeeds( ) )
+ {
+ seed.Value = this->m_InitValue;
+ this->_QueuePush( seed );
+ this->InvokeEvent( TEvent( seed.Vertex, seed.FrontId, true ) );
+
+ } // rof
+
+ // Main loop
+ while( this->_QueueSize( ) > 0 )
+ {
+ // Get next candidate
+ TNode node = this->_QueuePop( );
+ this->InvokeEvent( TEvent( node.Vertex, node.FrontId, false ) );
+
+ if( !( this->_IsMarked( node ) ) )
+ {
+ // Update output value and mark vertex
+ this->_UpdateOutputValue( node );
+ this->_Mark( node );
+
+ // The actual node was effectively marked?
+ if( node.FrontId > 0 )
+ {
+ // Add neighborhood
+ TNeighborhood neighbors = this->_GetNeighbors( node.Vertex );
+ typename TNeighborhood::const_iterator nIt = neighbors.begin( );
+ bool coll = false;
+ while( nIt != neighbors.end( ) && !coll )
+ {
+ if( this->_IsMarked( *nIt ) )
+ {
+ // Invoke stop at collisions
+ if( this->_Collisions( node.Vertex, *nIt ) )
+ {
+ this->_QueueClear( );
+ coll = true;
+
+ } // fi
+ }
+ else
+ {
+ TNode nnode;
+ nnode.Vertex = *nIt;
+ nnode.Parent = node.Vertex;
+ nnode.FrontId = node.FrontId;
+ this->_ComputeOutputValue( nnode );
+ this->_QueuePush( nnode );
+ this->InvokeEvent( TEvent( nnode.Vertex, nnode.FrontId, true ) );
+
+ } // fi
+ ++nIt;
+
+ } // elihw
+
+ } // fi
+
+ } // fi
+ this->_Reinitialize( );
+
+ } // elihw
+
+ // Finish algorithm
+ this->_AfterGenerateData( );
+ this->InvokeEvent( itk::EndEvent( ) );
+}
+
+// -------------------------------------------------------------------------
+template< class _TTraits >
+void fpa::Filters::Algorithm< _TTraits >::
+_Associate( itk::Object* o )
+{
+ if( this->m_AssociatedObjects.insert( o ).second )
+ this->Modified( );
+}
+
+// -------------------------------------------------------------------------
+template< class _TTraits >
+void fpa::Filters::Algorithm< _TTraits >::
+_Deassociate( itk::Object* o )
+{
+ std::set< itk::Object* >::iterator i = this->m_AssociatedObjects.find( o );
+ if( i != this->m_AssociatedObjects.end( ) )
+ {
+ this->m_AssociatedObjects.erase( i );
+ this->Modified( );
+
+ } // fi
+}
+
+// -------------------------------------------------------------------------
+template< class _TTraits >
+void fpa::Filters::Algorithm< _TTraits >::
+_DeassociateAll( )
+{
+ if( this->m_AssociatedObjects.size( ) > 0 )
+ this->Modified( );
+ this->m_AssociatedObjects.clear( );
+}
+
+// -------------------------------------------------------------------------
+template< class _TTraits >
+void fpa::Filters::Algorithm< _TTraits >::
+_BeforeGenerateData( )
+{
+ typedef fpa::Functors::LightBaseVertexFunction< TVertex > _TVertexFunc;
+ const itk::DataObject* input = this->GetInput( );
+ for( itk::Object* o: this->m_AssociatedObjects )
+ {
+ _TVertexFunc* f = dynamic_cast< _TVertexFunc* >( o );
+ if( f != NULL )
+ f->SetDataObject( input );
+
+ } // rof
+}
+
+// -------------------------------------------------------------------------
+template< class _TTraits >
+void fpa::Filters::Algorithm< _TTraits >::
+_AfterGenerateData( )
+{
+}
+
+// -------------------------------------------------------------------------
+template< class _TTraits >
+void fpa::Filters::Algorithm< _TTraits >::
+_Reinitialize( )
+{
+}
+
+// -------------------------------------------------------------------------
+template< class _TTraits >
+const itk::DataObject* fpa::Filters::Algorithm< _TTraits >::
+_GetReferenceInput( ) const
+{
+ return( this->GetInput( ) );
+}
+
+// -------------------------------------------------------------------------
+template< class _TTraits >
+typename fpa::Filters::Algorithm< _TTraits >::
+TInputValue fpa::Filters::Algorithm< _TTraits >::
+_GetInputValue( const TNode& n ) const
+{
+ return( this->_GetInputValue( n.Vertex ) );
+}
+
+// -------------------------------------------------------------------------
+template< class _TTraits >
+typename fpa::Filters::Algorithm< _TTraits >::
+TOutputValue fpa::Filters::Algorithm< _TTraits >::
+_GetOutputValue( const TNode& n ) const
+{
+ return( this->_GetOutputValue( n.Vertex ) );
+}
+
+#endif // __fpa__Filters__Algorithm__hxx__
+// eof - $RCSfile$
--- /dev/null
+// =========================================================================
+// @author Leonardo Florez Valencia
+// @email florez-l@javeriana.edu.co
+// =========================================================================
+#ifndef __fpa__Filters__Dijkstra__h__
+#define __fpa__Filters__Dijkstra__h__
+
+#include <fpa/Filters/DijkstraBase.h>
+
+namespace fpa
+{
+ namespace Filters
+ {
+ /**
+ */
+ template< class _TTraits, class _TMST >
+ class Dijkstra
+ : public fpa::Filters::DijkstraBase< _TTraits >
+ {
+ public:
+ typedef _TTraits TTraits;
+ typedef _TMST TMST;
+ fpaTraitsMacro( typename, TTraits );
+
+ typedef fpa::Filters::DijkstraBase< _TTraits > Superclass;
+ typedef Dijkstra Self;
+ typedef itk::SmartPointer< Self > Pointer;
+ typedef itk::SmartPointer< const Self > ConstPointer;
+
+ typedef typename Superclass::TScalarWeight TScalarWeight;
+ typedef typename Superclass::TVertexWeight TVertexWeight;
+
+ public:
+ itkTypeMacro( fpa::Filters::Dijkstra, fpa::Filters::DijkstraBase );
+
+ fpaFilterOutputMacro( MinimumSpanningTree, TMST );
+
+
+ protected:
+ Dijkstra( );
+ virtual ~Dijkstra( );
+
+ virtual void _AfterGenerateData( ) override;
+ virtual void _UpdateOutputValue( TNode& n ) override;
+
+ private:
+ // Purposely not implemented.
+ Dijkstra( const Self& other );
+ Self& operator=( const Self& other );
+
+ protected:
+ unsigned int m_MinimumSpanningTreeIdx;
+ };
+
+ } // ecapseman
+
+} // ecapseman
+
+#ifndef ITK_MANUAL_INSTANTIATION
+# include <fpa/Filters/Dijkstra.hxx>
+#endif // ITK_MANUAL_INSTANTIATION
+
+#endif // __fpa__Filters__Dijkstra__h__
+// eof - $RCSfile$
--- /dev/null
+// =========================================================================
+// @author Leonardo Florez Valencia
+// @email florez-l@javeriana.edu.co
+// =========================================================================
+#ifndef __fpa__Filters__Dijkstra__hxx__
+#define __fpa__Filters__Dijkstra__hxx__
+
+// -------------------------------------------------------------------------
+template< class _TTraits, class _TMST >
+fpa::Filters::Dijkstra< _TTraits, _TMST >::
+Dijkstra( )
+ : Superclass( )
+{
+ fpaFilterOutputConfigureMacro( MinimumSpanningTree, TMST );
+}
+
+// -------------------------------------------------------------------------
+template< class _TTraits, class _TMST >
+fpa::Filters::Dijkstra< _TTraits, _TMST >::
+~Dijkstra( )
+{
+}
+
+// -------------------------------------------------------------------------
+template< class _TTraits, class _TMST >
+void fpa::Filters::Dijkstra< _TTraits, _TMST >::
+_AfterGenerateData( )
+{
+ this->Superclass::_AfterGenerateData( );
+
+ TMST* mst = this->GetMinimumSpanningTree( );
+ mst->ClearSeeds( );
+ mst->SetCollisions( this->m_Collisions );
+ for( TNode n: this->GetSeeds( ) )
+ mst->AddSeed( n.Vertex );
+}
+
+// -------------------------------------------------------------------------
+template< class _TTraits, class _TMST >
+void fpa::Filters::Dijkstra< _TTraits, _TMST >::
+_UpdateOutputValue( TNode& n )
+{
+ this->Superclass::_UpdateOutputValue( n );
+ this->GetMinimumSpanningTree( )->SetParent( n.Vertex, n.Parent );
+}
+
+#endif // __fpa__Filters__Dijkstra__hxx__
+// eof - $RCSfile$
--- /dev/null
+// =========================================================================
+// @author Leonardo Florez Valencia
+// @email florez-l@javeriana.edu.co
+// =========================================================================
+#ifndef __fpa__Filters__DijkstraBase__h__
+#define __fpa__Filters__DijkstraBase__h__
+
+#include <vector>
+#include <itkConceptChecking.h>
+#include <itkFunctionBase.h>
+#include <fpa/Filters/Algorithm.h>
+#include <fpa/Functors/BaseVertexFunction.h>
+
+namespace fpa
+{
+ namespace Filters
+ {
+ /**
+ */
+ template< class _TTraits >
+ class DijkstraBase
+ : public fpa::Filters::Algorithm< _TTraits >
+ {
+ public:
+ typedef _TTraits TTraits;
+ fpaTraitsMacro( typename, TTraits );
+
+ typedef fpa::Filters::Algorithm< TTraits > Superclass;
+ typedef DijkstraBase Self;
+ typedef itk::SmartPointer< Self > Pointer;
+ typedef itk::SmartPointer< const Self > ConstPointer;
+
+ typedef std::vector< TNode > TQueue;
+ struct TQueueOrder
+ {
+ bool operator()( const TNode& a, const TNode& b ) const
+ {
+ return( b.Value < a.Value );
+ }
+ };
+
+ typedef itk::FunctionBase< TOutputValue, TOutputValue > TScalarWeight;
+ typedef fpa::Functors::BaseVertexFunction< TVertex, TOutputValue > TVertexWeight;
+
+ protected:
+ itkConceptMacro(
+ Check_TOutputValue,
+ ( itk::Concept::IsFloatingPoint< TOutputValue > )
+ );
+
+ public:
+ itkTypeMacro( fpa::Filters::DijkstraBase, fpa::Filters::Algorithm );
+
+ itkGetConstObjectMacro( ScalarWeight, TScalarWeight );
+ itkGetObjectMacro( ScalarWeight, TScalarWeight );
+
+ itkGetConstObjectMacro( VertexWeight, TVertexWeight );
+ itkGetObjectMacro( VertexWeight, TVertexWeight );
+
+ public:
+ void SetWeightFunction( TScalarWeight* w );
+ void SetWeightFunction( TVertexWeight* w );
+
+ protected:
+ DijkstraBase( );
+ virtual ~DijkstraBase( );
+
+ virtual void _UpdateOutputValue( TNode& n ) override;
+ virtual void _QueueClear( ) override;
+ virtual TNode _QueuePop( ) override;
+ virtual void _QueuePush( const TNode& n ) override;
+ virtual unsigned long _QueueSize( ) const override;
+ virtual void _ComputeOutputValue( TNode& n ) override;
+
+ private:
+ // Purposely not implemented.
+ DijkstraBase( const Self& other );
+ Self& operator=( const Self& other );
+
+ protected:
+ typename TScalarWeight::Pointer m_ScalarWeight;
+ typename TVertexWeight::Pointer m_VertexWeight;
+
+ TQueue m_Queue;
+ TQueueOrder m_QueueOrder;
+ };
+
+ } // ecapseman
+
+} // ecapseman
+
+#ifndef ITK_MANUAL_INSTANTIATION
+# include <fpa/Filters/DijkstraBase.hxx>
+#endif // ITK_MANUAL_INSTANTIATION
+
+#endif // __fpa__Filters__DijkstraBase__h__
+// eof - $RCSfile$
--- /dev/null
+// =========================================================================
+// @author Leonardo Florez Valencia
+// @email florez-l@javeriana.edu.co
+// =========================================================================
+#ifndef __fpa__Filters__DijkstraBase__hxx__
+#define __fpa__Filters__DijkstraBase__hxx__
+
+#include <algorithm>
+#include <limits>
+
+// -------------------------------------------------------------------------
+template< class _TTraits >
+void fpa::Filters::DijkstraBase< _TTraits >::
+SetWeightFunction( TScalarWeight* w )
+{
+ if( this->m_ScalarWeight.GetPointer( ) != w )
+ {
+ this->_Deassociate( this->m_ScalarWeight );
+ this->m_ScalarWeight = w;
+ this->_Associate( this->m_ScalarWeight );
+ this->Modified( );
+
+ } // fi
+}
+
+// -------------------------------------------------------------------------
+template< class _TTraits >
+void fpa::Filters::DijkstraBase< _TTraits >::
+SetWeightFunction( TVertexWeight* w )
+{
+ if( this->m_VertexWeight.GetPointer( ) != w )
+ {
+ this->_Deassociate( this->m_VertexWeight );
+ this->m_VertexWeight = w;
+ this->_Associate( this->m_VertexWeight );
+ this->Modified( );
+
+ } // fi
+}
+
+// -------------------------------------------------------------------------
+template< class _TTraits >
+fpa::Filters::DijkstraBase< _TTraits >::
+DijkstraBase( )
+ : Superclass( )
+{
+ this->SetInitValue( TOutputValue( 0 ) );
+}
+
+// -------------------------------------------------------------------------
+template< class _TTraits >
+fpa::Filters::DijkstraBase< _TTraits >::
+~DijkstraBase( )
+{
+}
+
+// -------------------------------------------------------------------------
+template< class _TTraits >
+void fpa::Filters::DijkstraBase< _TTraits >::
+_UpdateOutputValue( TNode& n )
+{
+ // Do nothing
+}
+
+// -------------------------------------------------------------------------
+template< class _TTraits >
+void fpa::Filters::DijkstraBase< _TTraits >::
+_QueueClear( )
+{
+ this->m_Queue.clear( );
+}
+
+// -------------------------------------------------------------------------
+template< class _TTraits >
+typename fpa::Filters::DijkstraBase< _TTraits >::
+TNode fpa::Filters::DijkstraBase< _TTraits >::
+_QueuePop( )
+{
+ std::pop_heap(
+ this->m_Queue.begin( ), this->m_Queue.end( ), this->m_QueueOrder
+ );
+ TNode n = this->m_Queue.back( );
+ this->m_Queue.pop_back( );
+ return( n );
+}
+
+// -------------------------------------------------------------------------
+template< class _TTraits >
+void fpa::Filters::DijkstraBase< _TTraits >::
+_QueuePush( const TNode& n )
+{
+ bool push_needed = ( n.Parent == n.Vertex );
+ push_needed |= !( n.Value < this->_GetOutputValue( n.Parent ) );
+ if( push_needed )
+ {
+ this->m_Queue.push_back( n );
+ std::push_heap(
+ this->m_Queue.begin( ), this->m_Queue.end( ), this->m_QueueOrder
+ );
+
+ } // fi
+}
+
+// -------------------------------------------------------------------------
+template< class _TTraits >
+unsigned long fpa::Filters::DijkstraBase< _TTraits >::
+_QueueSize( ) const
+{
+ return( this->m_Queue.size( ) );
+}
+
+// -------------------------------------------------------------------------
+template< class _TTraits >
+void fpa::Filters::DijkstraBase< _TTraits >::
+_ComputeOutputValue( TNode& n )
+{
+ if( this->m_VertexWeight.IsNotNull( ) )
+ {
+ TOutputValue c = this->m_VertexWeight->Evaluate( n.Vertex, n.Parent );
+ if( this->m_ScalarWeight.IsNotNull( ) )
+ c = this->m_ScalarWeight->Evaluate( c );
+ n.Value = c + this->_GetOutputValue( n.Parent );
+ }
+ else
+ n.Value = TOutputValue( -1 );
+}
+
+#endif // __fpa__Filters__DijkstraBase__hxx__
+// eof - $RCSfile$
--- /dev/null
+// =========================================================================
+// @author Leonardo Florez Valencia
+// @email florez-l@javeriana.edu.co
+// =========================================================================
+#ifndef __fpa__Filters__Event__h__
+#define __fpa__Filters__Event__h__
+
+#include <itkEventObject.h>
+
+namespace fpa
+{
+ namespace Filters
+ {
+ /**
+ */
+ template< class _TVertex >
+ class Event
+ : public itk::EventObject
+ {
+ public:
+ typedef Event Self;
+ typedef itk::EventObject Superclass;
+ typedef _TVertex TVertex;
+
+ public:
+ Event( );
+ Event( const TVertex& v, unsigned long fid, bool intoq );
+ virtual ~Event( );
+ virtual const char* GetEventName( ) const override;
+ virtual bool CheckEvent( const itk::EventObject* e ) const override;
+ virtual itk::EventObject* MakeObject( ) const override;
+
+ private:
+ // Purposely not implemented.
+ Self& operator=( const Self& other );
+
+ public:
+ TVertex Vertex;
+ unsigned long FrontId;
+ bool IntoQueue;
+ };
+
+ } // ecapseman
+
+} // ecapseman
+
+#ifndef ITK_MANUAL_INSTANTIATION
+# include <fpa/Filters/Event.hxx>
+#endif // ITK_MANUAL_INSTANTIATION
+#endif // __fpa__Filters__Event__h__
+
+// eof - $RCSfile$
--- /dev/null
+// =========================================================================
+// @author Leonardo Florez Valencia
+// @email florez-l@javeriana.edu.co
+// =========================================================================
+#ifndef __fpa__Filters__Event__hxx__
+#define __fpa__Filters__Event__hxx__
+
+// -------------------------------------------------------------------------
+template< class _TVertex >
+fpa::Filters::Event< _TVertex >::
+Event( )
+ : Superclass( )
+{
+}
+
+// -------------------------------------------------------------------------
+template< class _TVertex >
+fpa::Filters::Event< _TVertex >::
+Event( const TVertex& v, unsigned long fid, bool intoq )
+ : Superclass( ),
+ Vertex( v ),
+ FrontId( fid ),
+ IntoQueue( intoq )
+{
+}
+
+// -------------------------------------------------------------------------
+template< class _TVertex >
+fpa::Filters::Event< _TVertex >::
+~Event( )
+{
+}
+
+// -------------------------------------------------------------------------
+template< class _TVertex >
+const char* fpa::Filters::Event< _TVertex >::
+GetEventName( ) const
+{
+ return( "fpa::Filters::Event< _TVertex >" );
+}
+
+// -------------------------------------------------------------------------
+template< class _TVertex >
+bool fpa::Filters::Event< _TVertex >::
+CheckEvent( const itk::EventObject* e ) const
+{
+ return( dynamic_cast< const Self* >( e ) != NULL );
+}
+
+// -------------------------------------------------------------------------
+template< class _TVertex >
+itk::EventObject* fpa::Filters::Event< _TVertex >::
+MakeObject( ) const
+{
+ return( new Self );
+}
+
+#endif // __fpa__Filters__Event__hxx__
+// eof - $RCSfile$
--- /dev/null
+// =========================================================================
+// @author Leonardo Florez Valencia
+// @email florez-l@javeriana.edu.co
+// =========================================================================
+#ifndef __fpa__Filters__Image__Algorithm__h__
+#define __fpa__Filters__Image__Algorithm__h__
+
+#include <itkImage.h>
+
+namespace fpa
+{
+ namespace Filters
+ {
+ namespace Image
+ {
+ /**
+ */
+ template< class _TBaseAlgorithm >
+ class Algorithm
+ : public _TBaseAlgorithm
+ {
+ public:
+ typedef _TBaseAlgorithm TBaseAlgorithm;
+ typedef typename TBaseAlgorithm::TTraits TTraits;
+ fpaTraitsMacro( typename, TTraits );
+
+ typedef TBaseAlgorithm Superclass;
+ typedef Algorithm Self;
+ typedef itk::SmartPointer< Self > Pointer;
+ typedef itk::SmartPointer< const Self > ConstPointer;
+
+ typedef typename TTraits::TInputImage TInputImage;
+ typedef typename TTraits::TOutputImage TOutputImage;
+ typedef itk::Image< TMark, Self::Dimension > TMarksImage;
+
+ public:
+ itkTypeMacro( fpa::Filters::Image::Algorithm, TBaseAlgorithm );
+
+ itkGetConstMacro( NeighborhoodOrder, unsigned int );
+ itkSetMacro( NeighborhoodOrder, unsigned int );
+
+ fpaFilterOutputMacro( Marks, TMarksImage );
+
+ protected:
+ Algorithm( );
+ virtual ~Algorithm( );
+
+ virtual void _ConfigureOutputs( ) override;
+ virtual TInputValue _GetInputValue( const TVertex& v ) const override;
+ virtual TOutputValue _GetOutputValue( const TVertex& v ) const override;
+ virtual TNeighborhood _GetNeighbors( const TVertex& v ) const override;
+ virtual void _UpdateOutputValue( TNode& n ) override;
+ virtual unsigned long _GetMark( const TVertex& v ) const override;
+ virtual bool _IsMarked( const TVertex& v ) const override;
+ virtual void _Mark( const TVertex& v, unsigned long m ) override;
+
+ private:
+ // Purposely not implemented.
+ Algorithm( const Self& other );
+ Self& operator=( const Self& other );
+
+ protected:
+ unsigned int m_MarksIdx;
+ unsigned int m_NeighborhoodOrder;
+ };
+
+ } // ecapseman
+
+ } // ecapseman
+
+} // ecapseman
+
+#ifndef ITK_MANUAL_INSTANTIATION
+# include <fpa/Filters/Image/Algorithm.hxx>
+#endif // ITK_MANUAL_INSTANTIATION
+#endif // __fpa__Filters__Image__Algorithm__h__
+// eof - $RCSfile$
--- /dev/null
+// =========================================================================
+// @author Leonardo Florez Valencia
+// @email florez-l@javeriana.edu.co
+// =========================================================================
+#ifndef __fpa__Filters__Image__Algorithm__hxx__
+#define __fpa__Filters__Image__Algorithm__hxx__
+
+// -------------------------------------------------------------------------
+template< class _TBaseAlgorithm >
+fpa::Filters::Image::Algorithm< _TBaseAlgorithm >::
+Algorithm( )
+ : Superclass( ),
+ m_NeighborhoodOrder( 1 )
+{
+ fpaFilterOutputConfigureMacro( Marks, TMarksImage );
+}
+
+// -------------------------------------------------------------------------
+template< class _TBaseAlgorithm >
+fpa::Filters::Image::Algorithm< _TBaseAlgorithm >::
+~Algorithm( )
+{
+}
+
+// -------------------------------------------------------------------------
+template< class _TBaseAlgorithm >
+void fpa::Filters::Image::Algorithm< _TBaseAlgorithm >::
+_ConfigureOutputs( )
+{
+ const TInputImage* in = this->GetInput( );
+
+ TOutputImage* out = this->GetOutput( );
+ out->SetLargestPossibleRegion( in->GetLargestPossibleRegion( ) );
+ out->SetRequestedRegion( in->GetRequestedRegion( ) );
+ out->SetBufferedRegion( in->GetBufferedRegion( ) );
+ out->SetSpacing( in->GetSpacing( ) );
+ out->SetOrigin( in->GetOrigin( ) );
+ out->SetDirection( in->GetDirection( ) );
+ out->Allocate( );
+ out->FillBuffer( this->GetInitValue( ) );
+
+ TMarksImage* marks = this->GetMarks( );
+ marks->SetLargestPossibleRegion( in->GetLargestPossibleRegion( ) );
+ marks->SetRequestedRegion( in->GetRequestedRegion( ) );
+ marks->SetBufferedRegion( in->GetBufferedRegion( ) );
+ marks->SetSpacing( in->GetSpacing( ) );
+ marks->SetOrigin( in->GetOrigin( ) );
+ marks->SetDirection( in->GetDirection( ) );
+ marks->Allocate( );
+ marks->FillBuffer( TMark( 0 ) );
+}
+
+// -------------------------------------------------------------------------
+template< class _TBaseAlgorithm >
+typename fpa::Filters::Image::Algorithm< _TBaseAlgorithm >::
+TInputValue fpa::Filters::Image::Algorithm< _TBaseAlgorithm >::
+_GetInputValue( const TVertex& v ) const
+{
+ return( this->GetInput( )->GetPixel( v ) );
+}
+
+// -------------------------------------------------------------------------
+template< class _TBaseAlgorithm >
+typename fpa::Filters::Image::Algorithm< _TBaseAlgorithm >::
+TOutputValue fpa::Filters::Image::Algorithm< _TBaseAlgorithm >::
+_GetOutputValue( const TVertex& v ) const
+{
+ return( this->GetOutput( )->GetPixel( v ) );
+}
+
+// -------------------------------------------------------------------------
+template< class _TBaseAlgorithm >
+typename fpa::Filters::Image::Algorithm< _TBaseAlgorithm >::
+TNeighborhood fpa::Filters::Image::Algorithm< _TBaseAlgorithm >::
+_GetNeighbors( const TVertex& v ) const
+{
+ typename TInputImage::RegionType region =
+ this->GetInput( )->GetRequestedRegion( );
+ TNeighborhood neighborhood;
+ if( this->m_NeighborhoodOrder == 1 )
+ {
+ for( unsigned int d = 0; d < Self::Dimension; ++d )
+ {
+ for( int s = -1; s <= 1; s += 2 )
+ {
+ TVertex n = v;
+ n[ d ] += s;
+ if( region.IsInside( n ) )
+ neighborhood.push_back( n );
+
+ } // rof
+
+ } // rof
+ }
+ else if( this->m_NeighborhoodOrder == 2 )
+ {
+ // TODO
+
+ } // fi
+ return( neighborhood );
+}
+
+// -------------------------------------------------------------------------
+template< class _TBaseAlgorithm >
+void fpa::Filters::Image::Algorithm< _TBaseAlgorithm >::
+_UpdateOutputValue( TNode& n )
+{
+ this->Superclass::_UpdateOutputValue( n );
+ this->GetOutput( )->SetPixel( n.Vertex, n.Value );
+}
+
+// -------------------------------------------------------------------------
+template< class _TBaseAlgorithm >
+unsigned long fpa::Filters::Image::Algorithm< _TBaseAlgorithm >::
+_GetMark( const TVertex& v ) const
+{
+ return( ( unsigned long )( this->GetMarks( )->GetPixel( v ) ) );
+}
+
+// -------------------------------------------------------------------------
+template< class _TBaseAlgorithm >
+bool fpa::Filters::Image::Algorithm< _TBaseAlgorithm >::
+_IsMarked( const TVertex& v ) const
+{
+ return( this->GetMarks( )->GetPixel( v ) != TMark( 0 ) );
+}
+
+// -------------------------------------------------------------------------
+template< class _TBaseAlgorithm >
+void fpa::Filters::Image::Algorithm< _TBaseAlgorithm >::
+_Mark( const TVertex& v, unsigned long m )
+{
+ this->GetMarks( )->SetPixel( v, TMark( m ) );
+}
+
+#endif // __fpa__Filters__Image__Algorithm__hxx__
+// eof - $RCSfile$
--- /dev/null
+// =========================================================================
+// @author Leonardo Florez Valencia
+// @email florez-l@javeriana.edu.co
+// =========================================================================
+#ifndef __fpa__Filters__Image__DefaultTraits__h__
+#define __fpa__Filters__Image__DefaultTraits__h__
+
+#include <set>
+#include <vector>
+#include <itkConceptChecking.h>
+#include <itkImageToImageFilter.h>
+#include <fpa/Filters/MarksWithCollisionsInterface.h>
+#include <fpa/Filters/SeedsInterface.h>
+
+namespace fpa
+{
+ namespace Filters
+ {
+ namespace Image
+ {
+ /**
+ */
+ template< class _TInputImage, class _TOutputImage, class _TMark >
+ class DefaultTraits
+ {
+ public:
+ typedef _TInputImage TInputImage;
+ typedef _TOutputImage TOutputImage;
+
+ class TInternalTraits
+ {
+ public:
+ typedef _TMark TMark;
+ typedef typename TInputImage::IndexType TVertex;
+ typedef typename TInputImage::PixelType TInputValue;
+ typedef typename TInputImage::PointType TPoint;
+ typedef typename TOutputImage::PixelType TOutputValue;
+ typedef typename TVertex::LexicographicCompare TVertexCompare;
+ itkStaticConstMacro(
+ Dimension, unsigned int, _TInputImage::ImageDimension
+ );
+
+ typedef std::vector< TVertex > TNeighborhood;
+ struct TSeed
+ {
+ TVertex Vertex;
+ TPoint Point;
+ bool IsPoint;
+ TMark FrontId;
+ TSeed( const TMark& fid = 0 )
+ : FrontId( fid )
+ { }
+ };
+ typedef std::vector< TSeed > TSeeds;
+
+ struct TNode
+ {
+ TVertex Vertex;
+ TVertex Parent;
+ TMark FrontId;
+
+ // Hack to hide the fact that nodes need to be (re-)initialized
+ mutable TOutputValue Value;
+ };
+ struct TNodeCompare
+ {
+ bool operator()( const TNode& a, const TNode& b ) const
+ {
+ static TVertexCompare c;
+ return( c( a.Vertex, b.Vertex ) );
+ }
+ };
+ typedef std::set< TNode, TNodeCompare > TNodes;
+ };
+
+ typedef itk::ImageToImageFilter< TInputImage, TOutputImage > TFilter;
+ typedef fpa::Filters::MarksWithCollisionsInterface< TInternalTraits > TMarksInterface;
+ typedef fpa::Filters::SeedsInterface< TInternalTraits > TSeedsInterface;
+
+ protected:
+ itkConceptMacro(
+ Check_Dimensions,
+ ( itk::Concept::SameDimension< TInputImage::ImageDimension, TOutputImage::ImageDimension > )
+ );
+ };
+
+ } // ecapseman
+
+ } // ecapseman
+
+} // ecapseman
+
+#endif // __fpa__Filters__Image__DefaultTraits__h__
+// eof - $RCSfile$
--- /dev/null
+// =========================================================================
+// @author Leonardo Florez Valencia
+// @email florez-l@javeriana.edu.co
+// =========================================================================
+#ifndef __fpa__Filters__Image__Dijkstra__h__
+#define __fpa__Filters__Image__Dijkstra__h__
+
+#include <fpa/Filters/Dijkstra.h>
+#include <fpa/Filters/Image/Algorithm.h>
+#include <fpa/Filters/Image/DefaultTraits.h>
+#include <fpa/DataStructures/Image/MinimumSpanningTree.h>
+
+namespace fpa
+{
+ namespace Filters
+ {
+ namespace Image
+ {
+ /**
+ */
+ template< class _TInputImage, class _TOutputImage, class _TMark = unsigned char, class _TTraits = fpa::Filters::Image::DefaultTraits< _TInputImage, _TOutputImage, _TMark >, class _TMST = fpa::DataStructures::Image::MinimumSpanningTree< _TTraits::TInternalTraits::Dimension > >
+ class Dijkstra
+ : public fpa::Filters::Image::Algorithm< fpa::Filters::Dijkstra< _TTraits, _TMST > >
+ {
+ public:
+ typedef _TInputImage TInputImage;
+ typedef _TOutputImage TOutputImage;
+ typedef _TTraits TTraits;
+ typedef _TMST TMST;
+ fpaTraitsMacro( typename, TTraits );
+
+ typedef fpa::Filters::Dijkstra< TTraits, TMST > TAlgorithm;
+ typedef fpa::Filters::Image::Algorithm< TAlgorithm > Superclass;
+ typedef Dijkstra Self;
+ typedef itk::SmartPointer< Self > Pointer;
+ typedef itk::SmartPointer< const Self > ConstPointer;
+
+ public:
+ itkNewMacro( Self );
+ itkTypeMacro(
+ fpa::Filters::Image::Dijkstra, fpa::Filters::Image::Algorithm
+ );
+
+ protected:
+ Dijkstra( );
+ virtual ~Dijkstra( );
+
+ virtual void _ConfigureOutputs( ) override;
+
+ private:
+ // Purposely not implemented.
+ Dijkstra( const Self& other );
+ Self& operator=( const Self& other );
+ };
+
+ } // ecapseman
+
+ } // ecapseman
+
+} // ecapseman
+
+#ifndef ITK_MANUAL_INSTANTIATION
+# include <fpa/Filters/Image/Dijkstra.hxx>
+#endif // ITK_MANUAL_INSTANTIATION
+#endif // __fpa__Filters__Image__Dijkstra__h__
+// eof - $RCSfile$
--- /dev/null
+// =========================================================================
+// @author Leonardo Florez Valencia
+// @email florez-l@javeriana.edu.co
+// =========================================================================
+#ifndef __fpa__Filters__Image__Dijkstra__hxx__
+#define __fpa__Filters__Image__Dijkstra__hxx__
+
+#include <fpa/Functors/Dijkstra/Image/Identity.h>
+
+// -------------------------------------------------------------------------
+template< class _TInputImage, class _TOutputImage, class _TMark, class _TTraits, class _TMST >
+fpa::Filters::Image::Dijkstra< _TInputImage, _TOutputImage, _TMark, _TTraits, _TMST >::
+Dijkstra( )
+ : Superclass( )
+{
+ typedef fpa::Functors::Dijkstra::Image::Identity< TInputImage, TOutputValue > _TFunc;
+
+ this->SetWeightFunction( _TFunc::New( ) );
+}
+
+// -------------------------------------------------------------------------
+template< class _TInputImage, class _TOutputImage, class _TMark, class _TTraits, class _TMST >
+fpa::Filters::Image::Dijkstra< _TInputImage, _TOutputImage, _TMark, _TTraits, _TMST >::
+~Dijkstra( )
+{
+}
+
+// -------------------------------------------------------------------------
+template< class _TInputImage, class _TOutputImage, class _TMark, class _TTraits, class _TMST >
+void fpa::Filters::Image::Dijkstra< _TInputImage, _TOutputImage, _TMark, _TTraits, _TMST >::
+_ConfigureOutputs( )
+{
+ this->Superclass::_ConfigureOutputs( );
+
+ const TInputImage* in = this->GetInput( );
+ TMST* mst = this->GetMinimumSpanningTree( );
+ mst->SetLargestPossibleRegion( in->GetLargestPossibleRegion( ) );
+ mst->SetRequestedRegion( in->GetRequestedRegion( ) );
+ mst->SetBufferedRegion( in->GetBufferedRegion( ) );
+ mst->SetSpacing( in->GetSpacing( ) );
+ mst->SetOrigin( in->GetOrigin( ) );
+ mst->SetDirection( in->GetDirection( ) );
+ mst->Allocate( );
+
+ typename TVertex::OffsetType o;
+ o.Fill( 0 );
+ mst->FillBuffer( o );
+}
+
+#endif // __fpa__Filters__Image__Dijkstra__hxx__
+// eof - $RCSfile$
--- /dev/null
+// =========================================================================
+// @author Leonardo Florez Valencia
+// @email florez-l@javeriana.edu.co
+// =========================================================================
+#ifndef __fpa__Filters__Image__ExtractAxis__h__
+#define __fpa__Filters__Image__ExtractAxis__h__
+
+#include <itkProcessObject.h>
+#include <itkImageToImageFilter.h>
+#include <fpa/DataStructures/Image/PolyLineParametricPath.h>
+#include <fpa/Filters/Image/Dijkstra.h>
+
+namespace fpa
+{
+ namespace Filters
+ {
+ namespace Image
+ {
+ /**
+ */
+ template< class _TInputImage, class _TScalar >
+ class ExtractAxis
+ : public itk::ProcessObject
+ {
+ public:
+ typedef ExtractAxis Self;
+ typedef itk::ProcessObject Superclass;
+ typedef itk::SmartPointer< Self > Pointer;
+ typedef itk::SmartPointer< const Self > ConstPointer;
+
+ typedef _TInputImage TInputImage;
+ typedef _TScalar TScalar;
+ typedef typename TInputImage::IndexType TIndex;
+ typedef typename TInputImage::PointType TPoint;
+
+ itkStaticConstMacro(
+ Dimension,
+ unsigned int,
+ TInputImage::ImageDimension
+ );
+
+ typedef itk::Image< TScalar, Self::Dimension > TScalarImage;
+ typedef itk::ImageToImageFilter< TInputImage, TScalarImage > TCenterness;
+
+ typedef fpa::DataStructures::Image::PolyLineParametricPath< Self::Dimension > TPath;
+ typedef fpa::Filters::Image::Dijkstra< TScalarImage, TScalarImage > TDijkstra;
+
+ public:
+ itkNewMacro( Self );
+ itkTypeMacro( fpa::Image::ExtractAxis, itk::ProcessObject );
+
+ itkGetConstObjectMacro( Centerness, TCenterness );
+ itkGetObjectMacro( Centerness, TCenterness );
+ itkSetObjectMacro( Centerness, TCenterness );
+
+ itkGetConstMacro( StartIndex, TIndex );
+ itkSetMacro( StartIndex, TIndex );
+
+ itkGetConstMacro( EndIndex, TIndex );
+ itkSetMacro( EndIndex, TIndex );
+
+ public:
+ virtual itk::ModifiedTimeType GetMTime( ) const override;
+
+ virtual void AddSeed( const TIndex& seed );
+ virtual void AddSeed( const TPoint& seed );
+ virtual void ClearSeeds( );
+
+ void SetInput( TInputImage* input );
+ TInputImage* GetInput( );
+ const TInputImage* GetInput( ) const;
+
+ TPath* GetOutput( );
+ const TPath* GetOutput( ) const;
+
+ protected:
+ ExtractAxis( );
+ virtual ~ExtractAxis( );
+
+ virtual void GenerateData( ) override;
+
+ private:
+ // Purposely not implemented.
+ ExtractAxis( const Self& other );
+ Self& operator=( const Self& other );
+
+ protected:
+ typename TCenterness::Pointer m_Centerness;
+ typename TDijkstra::Pointer m_Dijkstra;
+
+ TIndex m_StartIndex;
+ TIndex m_EndIndex;
+ };
+
+ } // ecapseman
+
+ } // ecapseman
+
+} // ecapseman
+
+#ifndef ITK_MANUAL_INSTANTIATION
+# include <fpa/Filters/Image/ExtractAxis.hxx>
+#endif // ITK_MANUAL_INSTANTIATION
+#endif // __fpa__Filters__Image__ExtractAxis__h__
+
+// eof - $RCSfile$
--- /dev/null
+// =========================================================================
+// @author Leonardo Florez Valencia
+// @email florez-l@javeriana.edu.co
+// =========================================================================
+#ifndef __fpa__Filters__Image__ExtractAxis__hxx__
+#define __fpa__Filters__Image__ExtractAxis__hxx__
+
+#include <itkSignedMaurerDistanceMapImageFilter.h>
+#include <fpa/Functors/Dijkstra/Invert.h>
+
+// -------------------------------------------------------------------------
+template< class _TInputImage, class _TScalar >
+itk::ModifiedTimeType
+fpa::Filters::Image::ExtractAxis< _TInputImage, _TScalar >::
+GetMTime( ) const
+{
+ itk::ModifiedTimeType a = this->Superclass::GetMTime( );
+ itk::ModifiedTimeType b = this->m_Centerness->GetMTime( );
+ itk::ModifiedTimeType c = this->m_Dijkstra->GetMTime( );
+ a = ( a < b )? a: b;
+ return( ( a < c )? a: c );
+}
+
+// -------------------------------------------------------------------------
+template< class _TInputImage, class _TScalar >
+void fpa::Filters::Image::ExtractAxis< _TInputImage, _TScalar >::
+AddSeed( const TIndex& seed )
+{
+ this->m_Dijkstra->AddSeed( seed );
+}
+
+// -------------------------------------------------------------------------
+template< class _TInputImage, class _TScalar >
+void fpa::Filters::Image::ExtractAxis< _TInputImage, _TScalar >::
+AddSeed( const TPoint& seed )
+{
+ this->m_Dijkstra->AddSeed( seed );
+}
+
+// -------------------------------------------------------------------------
+template< class _TInputImage, class _TScalar >
+void fpa::Filters::Image::ExtractAxis< _TInputImage, _TScalar >::
+ClearSeeds( )
+{
+ this->m_Dijkstra->ClearSeeds( );
+}
+
+// -------------------------------------------------------------------------
+template< class _TInputImage, class _TScalar >
+void fpa::Filters::Image::ExtractAxis< _TInputImage, _TScalar >::
+SetInput( TInputImage* input )
+{
+ this->Superclass::SetNthInput( 0, input );
+}
+
+// -------------------------------------------------------------------------
+template< class _TInputImage, class _TScalar >
+typename fpa::Filters::Image::ExtractAxis< _TInputImage, _TScalar >::
+TInputImage* fpa::Filters::Image::ExtractAxis< _TInputImage, _TScalar >::
+GetInput( )
+{
+ return( dynamic_cast< TInputImage* >( this->Superclass::GetInput( 0 ) ) );
+}
+
+// -------------------------------------------------------------------------
+template< class _TInputImage, class _TScalar >
+const typename fpa::Filters::Image::ExtractAxis< _TInputImage, _TScalar >::
+TInputImage* fpa::Filters::Image::ExtractAxis< _TInputImage, _TScalar >::
+GetInput( ) const
+{
+ return(
+ dynamic_cast< const TInputImage* >( this->Superclass::GetInput( 0 ) )
+ );
+}
+
+// -------------------------------------------------------------------------
+template< class _TInputImage, class _TScalar >
+typename fpa::Filters::Image::ExtractAxis< _TInputImage, _TScalar >::
+TPath* fpa::Filters::Image::ExtractAxis< _TInputImage, _TScalar >::
+GetOutput( )
+{
+ return( dynamic_cast< TPath* >( this->Superclass::GetOutput( 0 ) ) );
+}
+
+// -------------------------------------------------------------------------
+template< class _TInputImage, class _TScalar >
+const typename fpa::Filters::Image::ExtractAxis< _TInputImage, _TScalar >::
+TPath* fpa::Filters::Image::ExtractAxis< _TInputImage, _TScalar >::
+GetOutput( ) const
+{
+ return( dynamic_cast< const TPath* >( this->Superclass::GetOutput( 0 ) ) );
+}
+
+// -------------------------------------------------------------------------
+template< class _TInputImage, class _TScalar >
+fpa::Filters::Image::ExtractAxis< _TInputImage, _TScalar >::
+ExtractAxis( )
+ : Superclass( )
+{
+ // I/O configuration
+ this->SetNumberOfRequiredInputs( 1 );
+ this->SetNumberOfRequiredOutputs( 1 );
+ this->SetNthOutput( 0, TPath::New( ) );
+
+ // Prepare weight function
+ typedef fpa::Functors::Dijkstra::Invert< TScalar > _TWeight;
+ typename _TWeight::Pointer weight = _TWeight::New( );
+ weight->SetAlpha( 1 );
+ weight->SetBeta( 1 );
+
+ // Filters
+ typedef itk::SignedMaurerDistanceMapImageFilter< TInputImage, TScalarImage > _TDefaultCenterness;
+ typename _TDefaultCenterness::Pointer dc = _TDefaultCenterness::New( );
+ dc->InsideIsPositiveOn( );
+ dc->SquaredDistanceOn( );
+ dc->UseImageSpacingOn( );
+ this->m_Centerness = dc;
+
+ // Axis extractor
+ this->m_Dijkstra = TDijkstra::New( );
+ this->m_Dijkstra->SetWeightFunction( weight );
+ this->m_Dijkstra->StopAtOneFront( );
+}
+
+// -------------------------------------------------------------------------
+template< class _TInputImage, class _TScalar >
+fpa::Filters::Image::ExtractAxis< _TInputImage, _TScalar >::
+~ExtractAxis( )
+{
+}
+
+// -------------------------------------------------------------------------
+template< class _TInputImage, class _TScalar >
+void fpa::Filters::Image::ExtractAxis< _TInputImage, _TScalar >::
+GenerateData( )
+{
+ // Execute minipipeline
+ this->m_Centerness->SetInput( this->GetInput( ) );
+ this->m_Dijkstra->SetInput( this->m_Centerness->GetOutput( ) );
+ this->m_Dijkstra->Update( );
+
+ // Extract axis
+ typename TPath::Pointer out = this->GetOutput( );
+ this->m_Dijkstra->GetMinimumSpanningTree( )->GetPolyLineParametricPath(
+ out, this->m_StartIndex, this->m_EndIndex
+ );
+}
+
+#endif // __fpa__Filters__Image__ExtractAxis__hxx__
+// eof - $RCSfile$
--- /dev/null
+// =========================================================================
+// @author Leonardo Florez Valencia
+// @email florez-l@javeriana.edu.co
+// =========================================================================
+#ifndef __fpa__Filters__Image__LabelsSeedInterface__h__
+#define __fpa__Filters__Image__LabelsSeedInterface__h__
+
+namespace fpa
+{
+ namespace Filters
+ {
+ namespace Image
+ {
+ /**
+ */
+ template< class _TTraits >
+ class LabelsSeedInterface
+ {
+ public:
+ typedef LabelsSeedInterface Self;
+ typedef _TTraits TTraits;
+ fpaInternalTraitsMacro( typename, TTraits );
+
+ public:
+ LabelsSeedInterface( itk::ProcessObject* f )
+ : m_Filter( f )
+ {
+ }
+
+ virtual ~LabelsSeedInterface( )
+ {
+ }
+
+ const TNodes& GetSeeds( ) const
+ {
+ return( this->m_UnifiedSeeds );
+ }
+
+ protected:
+ virtual void _PrepareSeeds( const itk::DataObject* input ) = 0;
+
+ protected:
+ TNodes m_UnifiedSeeds;
+ itk::ProcessObject::Pointer m_Filter;
+ };
+
+ } // ecapseman
+
+ } // ecapseman
+
+} // ecapseman
+
+#endif // __fpa__Filters__Image__LabelsSeedInterface__h__
+// eof - $RCSfile$
--- /dev/null
+// =========================================================================
+// @author Leonardo Florez Valencia
+// @email florez-l@javeriana.edu.co
+// =========================================================================
+#ifndef __fpa__Filters__Image__Mori__h__
+#define __fpa__Filters__Image__Mori__h__
+
+#include <fpa/Filters/Mori.h>
+#include <fpa/Filters/Image/Algorithm.h>
+#include <fpa/Filters/Image/DefaultTraits.h>
+#include <fpa/Filters/MarksInterface.h>
+#include <fpa/Filters/SingleSeedInterface.h>
+
+namespace fpa
+{
+ namespace Filters
+ {
+ namespace Image
+ {
+ /**
+ */
+ template< class _TInputImage, class _TOutputImage >
+ class MoriTraits
+ : public fpa::Filters::Image::DefaultTraits< _TInputImage, _TOutputImage, unsigned long >
+ {
+ public:
+ typedef _TInputImage TInputImage;
+ typedef _TOutputImage TOutputImage;
+ typedef fpa::Filters::Image::DefaultTraits< TInputImage, TOutputImage, unsigned long > Superclass;
+
+ typedef typename Superclass::TInternalTraits TInternalTraits;
+ typedef typename Superclass::TFilter TFilter;
+ typedef fpa::Filters::MarksInterface< TInternalTraits > TMarksInterface;
+ typedef fpa::Filters::SingleSeedInterface< TInternalTraits > TSeedsInterface;
+ };
+
+ /**
+ */
+ template< class _TInputImage, class _TOutputImage, class _TTraits = fpa::Filters::Image::MoriTraits< _TInputImage, _TOutputImage > >
+ class Mori
+ : public fpa::Filters::Image::Algorithm< fpa::Filters::Mori< _TTraits > >
+ {
+ public:
+ typedef _TInputImage TInputImage;
+ typedef _TOutputImage TOutputImage;
+ typedef _TTraits TTraits;
+ fpaTraitsMacro( typename, TTraits );
+
+ typedef fpa::Filters::Mori< TTraits > TAlgorithm;
+ typedef fpa::Filters::Image::Algorithm< TAlgorithm > Superclass;
+ typedef Mori Self;
+ typedef itk::SmartPointer< Self > Pointer;
+ typedef itk::SmartPointer< const Self > ConstPointer;
+
+ public:
+ itkNewMacro( Self );
+ itkTypeMacro(
+ fpa::Filters::Image::Mori, fpa::Filters::Image::Algorithm
+ );
+
+ protected:
+ Mori( )
+ : Superclass( )
+ {
+ }
+ virtual ~Mori( )
+ {
+ }
+
+ private:
+ // Purposely not implemented.
+ Mori( const Self& other );
+ Self& operator=( const Self& other );
+ };
+
+ } // ecapseman
+
+ } // ecapseman
+
+} // ecapseman
+
+#endif // __fpa__Filters__Image__Mori__h__
+// eof - $RCSfile$
--- /dev/null
+// =========================================================================
+// @author Leonardo Florez Valencia
+// @email florez-l@javeriana.edu.co
+// =========================================================================
+#ifndef __fpa__Filters__Image__RandomWalker__h__
+#define __fpa__Filters__Image__RandomWalker__h__
+
+#include <itkImage.h>
+#include <fpa/Filters/DijkstraBase.h>
+#include <fpa/Filters/Image/Algorithm.h>
+#include <fpa/Filters/Image/DefaultTraits.h>
+#include <fpa/Filters/MarksInterface.h>
+#include <fpa/Filters/Image/LabelsSeedInterface.h>
+
+namespace fpa
+{
+ namespace Filters
+ {
+ namespace Image
+ {
+ /**
+ */
+ template< class _TInputImage, class _TInputLabels, class _TCostsImage >
+ class RandomWalkerTraits
+ : public fpa::Filters::Image::DefaultTraits< _TInputImage, _TCostsImage, typename _TInputLabels::PixelType >
+ {
+ public:
+ typedef _TInputImage TInputImage;
+ typedef _TInputLabels TInputLabels;
+ typedef _TCostsImage TCostsImage;
+ typedef fpa::Filters::Image::DefaultTraits< TInputImage, TCostsImage, typename _TInputLabels::PixelType > Superclass;
+
+ typedef typename Superclass::TInternalTraits TInternalTraits;
+ typedef typename Superclass::TFilter TFilter;
+ typedef fpa::Filters::MarksInterface< TInternalTraits > TMarksInterface;
+ typedef fpa::Filters::Image::LabelsSeedInterface< TInternalTraits > TSeedsInterface;
+ };
+
+ /**
+ */
+ template< class _TInputImage, class _TInputLabels, class _TCostsImage = itk::Image< float, _TInputImage::ImageDimension >, class _TTraits = fpa::Filters::Image::RandomWalkerTraits< _TInputImage, _TInputLabels, _TCostsImage > >
+ class RandomWalker
+ : public fpa::Filters::Image::Algorithm< fpa::Filters::DijkstraBase< _TTraits > >
+ {
+ public:
+ typedef _TInputImage TInputImage;
+ typedef _TInputLabels TInputLabels;
+ typedef _TCostsImage TCostsImage;
+ typedef _TTraits TTraits;
+ fpaTraitsMacro( typename, TTraits );
+
+ typedef fpa::Filters::DijkstraBase< TTraits > TAlgorithm;
+ typedef fpa::Filters::Image::Algorithm< TAlgorithm > Superclass;
+ typedef RandomWalker Self;
+ typedef itk::SmartPointer< Self > Pointer;
+ typedef itk::SmartPointer< const Self > ConstPointer;
+
+ typedef typename Superclass::TMarksImage TOutputLabels;
+
+ public:
+ itkNewMacro( Self );
+ itkTypeMacro(
+ fpa::Filters::Image::RandomWalker, fpa::Filters::Image::Algorithm
+ );
+
+ fpaFilterInputMacro( InputLabels, TInputLabels );
+
+ public:
+ TCostsImage* GetOutputCosts( );
+ const TCostsImage* GetOutputCosts( ) const;
+
+ TOutputLabels* GetOutputLabels( );
+ const TOutputLabels* GetOutputLabels( ) const;
+
+ TInputImage* GetInputImage( );
+ const TInputImage* GetInputImage( ) const;
+ void SetInputImage( TInputImage* image );
+
+ protected:
+ RandomWalker( );
+ virtual ~RandomWalker( );
+
+ virtual const itk::DataObject* _GetReferenceInput( ) const override;
+ virtual void _PrepareSeeds( const itk::DataObject* input ) override;
+
+ private:
+ // Purposely not implemented.
+ RandomWalker( const Self& other );
+ Self& operator=( const Self& other );
+
+ protected:
+ unsigned int m_InputLabelsIdx;
+ };
+
+ } // ecapseman
+
+ } // ecapseman
+
+} // ecapseman
+
+#ifndef ITK_MANUAL_INSTANTIATION
+# include <fpa/Filters/Image/RandomWalker.hxx>
+#endif // ITK_MANUAL_INSTANTIATION
+#endif // __fpa__Filters__Image__RandomWalker__h__
+// eof - $RCSfile$
--- /dev/null
+// =========================================================================
+// @author Leonardo Florez Valencia
+// @email florez-l@javeriana.edu.co
+// =========================================================================
+#ifndef __fpa__Filters__Image__RandomWalker__hxx__
+#define __fpa__Filters__Image__RandomWalker__hxx__
+
+#include <itkImageRegionConstIteratorWithIndex.h>
+
+// -------------------------------------------------------------------------
+template< class _TInputImage, class _TInputLabels, class _TCostsImage, class _TTraits >
+typename
+fpa::Filters::Image::RandomWalker< _TInputImage, _TInputLabels, _TCostsImage, _TTraits >::
+TCostsImage*
+fpa::Filters::Image::RandomWalker< _TInputImage, _TInputLabels, _TCostsImage, _TTraits >::
+GetOutputCosts( )
+{
+ return( this->GetOutput( ) );
+}
+
+// -------------------------------------------------------------------------
+template< class _TInputImage, class _TInputLabels, class _TCostsImage, class _TTraits >
+const typename
+fpa::Filters::Image::RandomWalker< _TInputImage, _TInputLabels, _TCostsImage, _TTraits >::
+TCostsImage*
+fpa::Filters::Image::RandomWalker< _TInputImage, _TInputLabels, _TCostsImage, _TTraits >::
+GetOutputCosts( ) const
+{
+ return( this->GetOutput( ) );
+}
+
+// -------------------------------------------------------------------------
+template< class _TInputImage, class _TInputLabels, class _TCostsImage, class _TTraits >
+typename
+fpa::Filters::Image::RandomWalker< _TInputImage, _TInputLabels, _TCostsImage, _TTraits >::
+TOutputLabels*
+fpa::Filters::Image::RandomWalker< _TInputImage, _TInputLabels, _TCostsImage, _TTraits >::
+GetOutputLabels( )
+{
+ return( this->GetMarks( ) );
+}
+
+// -------------------------------------------------------------------------
+template< class _TInputImage, class _TInputLabels, class _TCostsImage, class _TTraits >
+const typename
+fpa::Filters::Image::RandomWalker< _TInputImage, _TInputLabels, _TCostsImage, _TTraits >::
+TOutputLabels*
+fpa::Filters::Image::RandomWalker< _TInputImage, _TInputLabels, _TCostsImage, _TTraits >::
+GetOutputLabels( ) const
+{
+ return( this->GetMarks( ) );
+}
+
+// -------------------------------------------------------------------------
+template< class _TInputImage, class _TInputLabels, class _TCostsImage, class _TTraits >
+typename
+fpa::Filters::Image::RandomWalker< _TInputImage, _TInputLabels, _TCostsImage, _TTraits >::
+TInputImage*
+fpa::Filters::Image::RandomWalker< _TInputImage, _TInputLabels, _TCostsImage, _TTraits >::
+GetInputImage( )
+{
+ return( this->GetInput( ) );
+}
+
+// -------------------------------------------------------------------------
+template< class _TInputImage, class _TInputLabels, class _TCostsImage, class _TTraits >
+const typename
+fpa::Filters::Image::RandomWalker< _TInputImage, _TInputLabels, _TCostsImage, _TTraits >::
+TInputImage*
+fpa::Filters::Image::RandomWalker< _TInputImage, _TInputLabels, _TCostsImage, _TTraits >::
+GetInputImage( ) const
+{
+ return( this->GetInput( ) );
+}
+
+// -------------------------------------------------------------------------
+template< class _TInputImage, class _TInputLabels, class _TCostsImage, class _TTraits >
+void
+fpa::Filters::Image::RandomWalker< _TInputImage, _TInputLabels, _TCostsImage, _TTraits >::
+SetInputImage( TInputImage* image )
+{
+ this->SetInput( image );
+}
+
+// -------------------------------------------------------------------------
+template< class _TInputImage, class _TInputLabels, class _TCostsImage, class _TTraits >
+fpa::Filters::Image::RandomWalker< _TInputImage, _TInputLabels, _TCostsImage, _TTraits >::
+RandomWalker( )
+ : Superclass( )
+{
+ fpaFilterInputConfigureMacro( InputLabels, TInputLabels );
+}
+
+// -------------------------------------------------------------------------
+template< class _TInputImage, class _TInputLabels, class _TCostsImage, class _TTraits >
+fpa::Filters::Image::RandomWalker< _TInputImage, _TInputLabels, _TCostsImage, _TTraits >::
+~RandomWalker( )
+{
+}
+
+// -------------------------------------------------------------------------
+template< class _TInputImage, class _TInputLabels, class _TCostsImage, class _TTraits >
+const itk::DataObject*
+fpa::Filters::Image::RandomWalker< _TInputImage, _TInputLabels, _TCostsImage, _TTraits >::
+_GetReferenceInput( ) const
+{
+ return( this->GetInputLabels( ) );
+}
+
+// -------------------------------------------------------------------------
+template< class _TInputImage, class _TInputLabels, class _TCostsImage, class _TTraits >
+void
+fpa::Filters::Image::RandomWalker< _TInputImage, _TInputLabels, _TCostsImage, _TTraits >::
+_PrepareSeeds( const itk::DataObject* input )
+{
+ // Input object is a labelled image?
+ const TInputLabels* labels = dynamic_cast< const TInputLabels* >( input );
+ if( labels != NULL )
+ {
+ this->m_UnifiedSeeds.clear( );
+
+ // Iterate over labels
+ typedef itk::ImageRegionConstIteratorWithIndex< TInputLabels > _TIt;
+ typename TInputLabels::RegionType reg = labels->GetRequestedRegion( );
+ _TIt lIt( labels, reg );
+ for( lIt.GoToBegin( ); !lIt.IsAtEnd( ); ++lIt )
+ {
+ if( lIt.Get( ) > 0 )
+ {
+ bool is_seed = false;
+ for( unsigned int d = 0; d < Self::Dimension; ++d )
+ {
+ for( int s = -1; s <= 1; s += 2 )
+ {
+ TVertex neigh = lIt.GetIndex( );
+ neigh[ d ] += s;
+ if( reg.IsInside( neigh ) )
+ is_seed |= ( labels->GetPixel( neigh ) == 0 );
+
+ } // rof
+
+ } // rof
+
+ // Add pixel as seed or already marked
+ TNode node;
+ node.Vertex = lIt.GetIndex( );
+ node.Parent = lIt.GetIndex( );
+ node.FrontId = lIt.Get( );
+ node.Value = TOutputValue( 0 );
+ if( !is_seed )
+ {
+ this->_Mark( node.Vertex, node.FrontId );
+ this->_UpdateOutputValue( node );
+ }
+ else
+ this->m_UnifiedSeeds.insert( node );
+
+ } // fi
+
+ } // rof
+
+ } // fi
+}
+
+#endif // __fpa__Filters__Image__RandomWalker__hxx__
+// eof - $RCSfile$
--- /dev/null
+// =========================================================================
+// @author Leonardo Florez Valencia
+// @email florez-l@javeriana.edu.co
+// =========================================================================
+#ifndef __fpa__Filters__Image__RegionGrow__h__
+#define __fpa__Filters__Image__RegionGrow__h__
+
+#include <fpa/Filters/RegionGrow.h>
+#include <fpa/Filters/Image/Algorithm.h>
+#include <fpa/Filters/Image/DefaultTraits.h>
+
+namespace fpa
+{
+ namespace Filters
+ {
+ namespace Image
+ {
+ /**
+ */
+ template< class _TInputImage, class _TOutputImage, class _TMark = unsigned char, class _TTraits = fpa::Filters::Image::DefaultTraits< _TInputImage, _TOutputImage, _TMark > >
+ class RegionGrow
+ : public fpa::Filters::Image::Algorithm< fpa::Filters::RegionGrow< _TTraits > >
+ {
+ public:
+ typedef _TInputImage TInputImage;
+ typedef _TOutputImage TOutputImage;
+ typedef _TTraits TTraits;
+ fpaTraitsMacro( typename, TTraits );
+
+ typedef fpa::Filters::RegionGrow< TTraits > TAlgorithm;
+ typedef fpa::Filters::Image::Algorithm< TAlgorithm > Superclass;
+ typedef RegionGrow Self;
+ typedef itk::SmartPointer< Self > Pointer;
+ typedef itk::SmartPointer< const Self > ConstPointer;
+
+ public:
+ itkNewMacro( Self );
+ itkTypeMacro(
+ fpa::Filters::Image::RegionGrow, fpa::Filters::Image::Algorithm
+ );
+
+ protected:
+ RegionGrow( )
+ : Superclass( )
+ {
+ }
+ virtual ~RegionGrow( )
+ {
+ }
+
+ private:
+ // Purposely not implemented.
+ RegionGrow( const Self& other );
+ Self& operator=( const Self& other );
+ };
+
+ } // ecapseman
+
+ } // ecapseman
+
+} // ecapseman
+
+#endif // __fpa__Filters__Image__RegionGrow__h__
+// eof - $RCSfile$
--- /dev/null
+// =========================================================================
+// @author Leonardo Florez Valencia
+// @email florez-l@javeriana.edu.co
+// =========================================================================
+#ifndef __fpa__Filters__Image__Skeleton__h__
+#define __fpa__Filters__Image__Skeleton__h__
+
+#include <map>
+#include <itkProcessObject.h>
+#include <itkSignedMaurerDistanceMapImageFilter.h>
+#include <fpa/Filters/Image/Dijkstra.h>
+#include <fpa/DataStructures/Image/Skeleton.h>
+
+namespace fpa
+{
+ namespace Filters
+ {
+ namespace Image
+ {
+ /**
+ */
+ template< class _TInputImage, class _TDistanceMap = itk::SignedMaurerDistanceMapImageFilter< _TInputImage, itk::Image< double, _TInputImage::ImageDimension > > >
+ class Skeleton
+ : public itk::ProcessObject
+ {
+ public:
+ typedef Skeleton Self;
+ typedef itk::ProcessObject Superclass;
+ typedef itk::SmartPointer< Self > Pointer;
+ typedef itk::SmartPointer< const Self > ConstPointer;
+
+ typedef _TInputImage TInputImage;
+ typedef _TDistanceMap TDistanceMap;
+ itkStaticConstMacro(
+ Dimension,
+ unsigned int,
+ TInputImage::ImageDimension
+ );
+
+ typedef typename TDistanceMap::OutputImageType TOutputImage;
+ typedef typename TInputImage::IndexType TIndex;
+ typedef typename TOutputImage::PixelType TScalar;
+
+ typedef fpa::DataStructures::Image::Skeleton< Self::Dimension > TSkeleton;
+
+ protected:
+ typedef std::multimap< TScalar, TIndex > _TSkeletonQueue;
+
+ /**
+ */
+ class _TDijkstra
+ : public fpa::Filters::Image::Dijkstra< TOutputImage, TOutputImage >
+ {
+ public:
+ typedef fpa::Filters::Image::Dijkstra< TOutputImage, TOutputImage > Superclass;
+ typedef _TDijkstra Self;
+ typedef itk::SmartPointer< Self > Pointer;
+ typedef itk::SmartPointer< const Self > ConstPointer;
+
+ typedef typename Superclass::TNode TNode;
+ typedef typename Superclass::TMST TMST;
+
+ public:
+ itkNewMacro( Self );
+ itkTypeMacro( _TDijkstra, fpa::Image::Dijkstra );
+
+ itkGetConstReferenceMacro( SkeletonQueue, _TSkeletonQueue );
+
+ protected:
+ _TDijkstra( );
+ virtual ~_TDijkstra( );
+
+ virtual void _BeforeGenerateData( ) override;
+ virtual void _UpdateOutputValue( TNode& n ) override;
+
+ private:
+ // Purposely not implemented
+ _TDijkstra( const Self& other );
+ Self& operator=( const Self& other );
+
+ protected:
+ _TSkeletonQueue m_SkeletonQueue;
+ };
+ typedef typename _TDijkstra::TMST _TMST;
+
+ public:
+ itkNewMacro( Self );
+ itkTypeMacro( fpa::Image::Skeleton, fpa::Image::Dijkstra );
+
+ itkBooleanMacro( SeedFromMaximumDistance );
+ itkGetConstMacro( SeedFromMaximumDistance, bool );
+ itkSetMacro( SeedFromMaximumDistance, bool );
+
+ itkGetConstObjectMacro( DistanceMap, TDistanceMap );
+ itkGetObjectMacro( DistanceMap, TDistanceMap );
+
+ itkGetConstMacro( Seed, TIndex );
+ itkSetMacro( Seed, TIndex );
+
+ public:
+ virtual itk::ModifiedTimeType GetMTime( ) const override;
+
+ void SetInput( TInputImage* input );
+ TInputImage* GetInput( );
+ const TInputImage* GetInput( ) const;
+
+ TSkeleton* GetOutput( );
+ const TSkeleton* GetOutput( ) const;
+
+ protected:
+ Skeleton( );
+ virtual ~Skeleton( );
+
+ virtual void GenerateData( ) override;
+
+ template< class _TMarksPointer >
+ void _MarkSphere(
+ _TMarksPointer& marks,
+ const TOutputImage* dmap,
+ const TIndex& center
+ );
+
+ void _EndPoints(
+ std::vector< TIndex >& end_points,
+ const TOutputImage* dmap,
+ const _TMST* mst,
+ const _TSkeletonQueue& queue
+ );
+
+ private:
+ // Purposely not implemented.
+ Skeleton( const Self& other );
+ Self& operator=( const Self& other );
+
+ protected:
+ typename TDistanceMap::Pointer m_DistanceMap;
+ bool m_SeedFromMaximumDistance;
+ TIndex m_Seed;
+ };
+
+ } // ecapseman
+
+ } // ecapseman
+
+} // ecapseman
+
+#ifndef ITK_MANUAL_INSTANTIATION
+# include <fpa/Filters/Image/Skeleton.hxx>
+#endif // ITK_MANUAL_INSTANTIATION
+
+#endif // __fpa__Filters__Image__Skeleton__h__
+
+// eof - $RCSfile$
--- /dev/null
+// =========================================================================
+// @author Leonardo Florez Valencia
+// @email florez-l@javeriana.edu.co
+// =========================================================================
+#ifndef __fpa__Filters__Image__Skeleton__hxx__
+#define __fpa__Filters__Image__Skeleton__hxx__
+
+#include <itkImage.h>
+#include <itkImageRegionIteratorWithIndex.h>
+#include <itkMinimumMaximumImageCalculator.h>
+#include <fpa/Functors/Dijkstra/Invert.h>
+
+// -------------------------------------------------------------------------
+template< class _TInputImage, class _TDistanceMap >
+fpa::Filters::Image::Skeleton< _TInputImage, _TDistanceMap >::_TDijkstra::
+_TDijkstra( )
+ : Superclass( )
+{
+ // Prepare weight function
+ typedef fpa::Functors::Dijkstra::Invert< TScalar > _TWeight;
+ typename _TWeight::Pointer weight = _TWeight::New( );
+ weight->SetAlpha( 1 );
+ weight->SetBeta( 1 );
+ this->SetWeightFunction( weight );
+}
+
+// -------------------------------------------------------------------------
+template< class _TInputImage, class _TDistanceMap >
+fpa::Filters::Image::Skeleton< _TInputImage, _TDistanceMap >::_TDijkstra::
+~_TDijkstra( )
+{
+}
+
+// -------------------------------------------------------------------------
+template< class _TInputImage, class _TDistanceMap >
+void fpa::Filters::Image::Skeleton< _TInputImage, _TDistanceMap >::_TDijkstra::
+_BeforeGenerateData( )
+{
+ this->Superclass::_BeforeGenerateData( );
+ this->m_SkeletonQueue.clear( );
+}
+
+// -------------------------------------------------------------------------
+template< class _TInputImage, class _TDistanceMap >
+void fpa::Filters::Image::Skeleton< _TInputImage, _TDistanceMap >::_TDijkstra::
+_UpdateOutputValue( TNode& n )
+{
+ typedef typename _TSkeletonQueue::value_type _TSkeletonQueueValue;
+
+ this->Superclass::_UpdateOutputValue( n );
+ double d = double( this->GetInput( )->GetPixel( n.Vertex ) );
+ if( d >= double( 0 ) )
+ {
+ // Update skeleton candidates
+ d += double( 1e-5 );
+ double v = double( n.Value ) / ( d * d );
+ this->m_SkeletonQueue.insert( _TSkeletonQueueValue( v, n.Vertex ) );
+
+ } // fi
+}
+
+// -------------------------------------------------------------------------
+template< class _TInputImage, class _TDistanceMap >
+itk::ModifiedTimeType
+fpa::Filters::Image::Skeleton< _TInputImage, _TDistanceMap >::
+GetMTime( ) const
+{
+ itk::ModifiedTimeType t = this->Superclass::GetMTime( );
+ itk::ModifiedTimeType q = this->m_DistanceMap->GetMTime( );
+ return( ( q < t )? q: t );
+}
+
+// -------------------------------------------------------------------------
+template< class _TInputImage, class _TDistanceMap >
+void fpa::Filters::Image::Skeleton< _TInputImage, _TDistanceMap >::
+SetInput( TInputImage* input )
+{
+ this->Superclass::SetNthInput( 0, input );
+}
+
+// -------------------------------------------------------------------------
+template< class _TInputImage, class _TDistanceMap >
+typename fpa::Filters::Image::Skeleton< _TInputImage, _TDistanceMap >::
+TInputImage* fpa::Filters::Image::Skeleton< _TInputImage, _TDistanceMap >::
+GetInput( )
+{
+ return( dynamic_cast< TInputImage* >( this->Superclass::GetInput( 0 ) ) );
+}
+
+// -------------------------------------------------------------------------
+template< class _TInputImage, class _TDistanceMap >
+const typename fpa::Filters::Image::Skeleton< _TInputImage, _TDistanceMap >::
+TInputImage* fpa::Filters::Image::Skeleton< _TInputImage, _TDistanceMap >::
+GetInput( ) const
+{
+ return(
+ dynamic_cast< const TInputImage* >( this->Superclass::GetInput( 0 ) )
+ );
+}
+
+// -------------------------------------------------------------------------
+template< class _TInputImage, class _TDistanceMap >
+typename fpa::Filters::Image::Skeleton< _TInputImage, _TDistanceMap >::
+TSkeleton* fpa::Filters::Image::Skeleton< _TInputImage, _TDistanceMap >::
+GetOutput( )
+{
+ return( dynamic_cast< TSkeleton* >( this->Superclass::GetOutput( 0 ) ) );
+}
+
+// -------------------------------------------------------------------------
+template< class _TInputImage, class _TDistanceMap >
+const typename fpa::Filters::Image::Skeleton< _TInputImage, _TDistanceMap >::
+TSkeleton* fpa::Filters::Image::Skeleton< _TInputImage, _TDistanceMap >::
+GetOutput( ) const
+{
+ return(
+ dynamic_cast< const TSkeleton* >( this->Superclass::GetOutput( 0 ) )
+ );
+}
+
+// -------------------------------------------------------------------------
+template< class _TInputImage, class _TDistanceMap >
+fpa::Filters::Image::Skeleton< _TInputImage, _TDistanceMap >::
+Skeleton( )
+ : Superclass( ),
+ m_SeedFromMaximumDistance( false )
+{
+ this->SetNumberOfRequiredInputs( 1 );
+ this->SetNumberOfRequiredOutputs( 1 );
+ this->SetNthOutput( 0, TSkeleton::New( ) );
+
+ this->m_DistanceMap = TDistanceMap::New( );
+}
+
+// -------------------------------------------------------------------------
+template< class _TInputImage, class _TDistanceMap >
+fpa::Filters::Image::Skeleton< _TInputImage, _TDistanceMap >::
+~Skeleton( )
+{
+}
+
+// -------------------------------------------------------------------------
+template< class _TInputImage, class _TDistanceMap >
+void fpa::Filters::Image::Skeleton< _TInputImage, _TDistanceMap >::
+GenerateData( )
+{
+ // Update distance map
+ this->m_DistanceMap->SetInput( this->GetInput( ) );
+ this->m_DistanceMap->Update( );
+
+ // Correct seed
+ if( this->m_SeedFromMaximumDistance )
+ {
+ typedef itk::MinimumMaximumImageCalculator< TOutputImage > _TMinMax;
+ typename _TMinMax::Pointer minmax = _TMinMax::New( );
+ minmax->SetImage( this->m_DistanceMap->GetOutput( ) );
+ minmax->Compute( );
+ this->m_Seed = minmax->GetIndexOfMaximum( );
+
+ } // fi
+
+ // Compute MST
+ typename _TDijkstra::Pointer dijkstra = _TDijkstra::New( );
+ dijkstra->SetInput( this->m_DistanceMap->GetOutput( ) );
+ dijkstra->AddSeed( this->m_Seed );
+ dijkstra->Update( );
+
+ // Compute end-points
+ const _TMST* mst = dijkstra->GetMinimumSpanningTree( );
+ std::vector< TIndex > end_points;
+ this->_EndPoints(
+ end_points, this->m_DistanceMap->GetOutput( ),
+ mst, dijkstra->GetSkeletonQueue( )
+ );
+
+ // Compute symbolic branches
+ typedef std::map< TIndex, TIndex, typename TIndex::LexicographicCompare > _TTags;
+ _TTags tags, branches;
+ typename std::vector< TIndex >::const_iterator eIt = end_points.begin( );
+ for( ; eIt != end_points.end( ); ++eIt )
+ {
+ // Tag path
+ TIndex it = *eIt;
+ TIndex p = mst->GetParent( it );
+ typename _TTags::iterator bIt = tags.end( );
+ while( it != p && bIt == tags.end( ) )
+ {
+ typename _TTags::iterator tIt = tags.find( it );
+ if( tIt != tags.end( ) )
+ {
+ // Ok, a bifurcation point has been found
+ // branch1: tIt->second <-> it (ok)
+ branches[ tIt->second ] = it;
+
+ // branch2: *eit <-> it (ok)
+ branches[ *eIt ] = it;
+
+ // branch3: it <-> until next bifurcation
+ bIt = tIt;
+ }
+ else
+ tags[ it ] = *eIt;
+ it = p;
+ p = mst->GetParent( it );
+
+ } // elihw
+ if( bIt != tags.end( ) )
+ {
+ TIndex pTag = bIt->second;
+ TIndex nTag = bIt->first;
+ it = bIt->first;
+ p = it;
+ while( tags[ it ] == pTag )
+ {
+ tags[ it ] = nTag;
+ p = it;
+ it = mst->GetParent( it );
+
+ } // elihw
+ tags[ it ] = nTag;
+ branches[ bIt->first ] = p;
+ }
+ else
+ {
+ tags[ it ] = *eIt;
+ branches[ *eIt ] = it;
+
+ } // fi
+
+ } // rof
+
+ // Fill full branches
+ typedef typename _TMST::TVertices _TVertices;
+ typedef typename TSkeleton::TPath _TPath;
+
+ TSkeleton* sk = this->GetOutput( );
+ typename _TTags::const_iterator bIt = branches.begin( );
+ for( ; bIt != branches.end( ); ++bIt )
+ {
+ _TVertices v = mst->GetPath( bIt->first, bIt->second );
+ typename _TPath::Pointer path = _TPath::New( );
+ path->SetReferenceImage( this->GetInput( ) );
+ typename _TVertices::const_reverse_iterator vIt = v.rbegin( );
+ for( ; vIt != v.rend( ); ++vIt )
+ path->AddVertex( *vIt );
+ sk->AddBranch( path );
+
+ } // rof
+}
+
+// -------------------------------------------------------------------------
+template< class _TInputImage, class _TDistanceMap >
+template< class _TMarksPointer >
+void fpa::Filters::Image::Skeleton< _TInputImage, _TDistanceMap >::
+_MarkSphere(
+ _TMarksPointer& marks, const TOutputImage* dmap, const TIndex& center
+ )
+{
+ typedef typename _TMarksPointer::ObjectType _TMarks;
+ typedef itk::ImageRegionIteratorWithIndex< _TMarks > _TMarksIt;
+
+ static const double _eps = std::sqrt( double( Self::Dimension + 1 ) );
+ typename _TMarks::SpacingType spac = dmap->GetSpacing( );
+ typename _TMarks::RegionType region = dmap->GetRequestedRegion( );
+
+ typename _TMarks::PointType cnt;
+ dmap->TransformIndexToPhysicalPoint( center, cnt );
+ double r = double( dmap->GetPixel( center ) ) * _eps;
+
+ TIndex i0, i1;
+ for( unsigned int d = 0; d < Self::Dimension; ++d )
+ {
+ long off = long( std::ceil( r / double( spac[ d ] ) ) );
+ if( off < 3 )
+ off = 3;
+ i0[ d ] = center[ d ] - off;
+ i1[ d ] = center[ d ] + off;
+
+ if( i0[ d ] < region.GetIndex( )[ d ] )
+ i0[ d ] = region.GetIndex( )[ d ];
+
+ if( i1[ d ] >= region.GetIndex( )[ d ] + region.GetSize( )[ d ] )
+ i1[ d ] = region.GetIndex( )[ d ] + region.GetSize( )[ d ] - 1;
+
+ } // rof
+
+ typename _TMarks::SizeType size;
+ for( unsigned int d = 0; d < Self::Dimension; ++d )
+ size[ d ] = i1[ d ] - i0[ d ] + 1;
+
+ typename _TMarks::RegionType neighRegion;
+ neighRegion.SetIndex( i0 );
+ neighRegion.SetSize( size );
+
+ _TMarksIt mIt( marks, neighRegion );
+ for( mIt.GoToBegin( ); !mIt.IsAtEnd( ); ++mIt )
+ mIt.Set( true );
+}
+
+// -------------------------------------------------------------------------
+template< class _TInputImage, class _TDistanceMap >
+void fpa::Filters::Image::Skeleton< _TInputImage, _TDistanceMap >::
+_EndPoints(
+ std::vector< TIndex >& end_points,
+ const TOutputImage* dmap,
+ const _TMST* mst,
+ const _TSkeletonQueue& queue
+ )
+{
+ typedef typename _TSkeletonQueue::value_type _TSkeletonQueueValue;
+
+ // Some values
+ typedef itk::Image< bool, Self::Dimension > _TMarks;
+ typename _TMarks::Pointer marks = _TMarks::New( );
+ marks->SetLargestPossibleRegion( mst->GetLargestPossibleRegion( ) );
+ marks->SetRequestedRegion( mst->GetRequestedRegion( ) );
+ marks->SetBufferedRegion( mst->GetBufferedRegion( ) );
+ marks->SetSpacing( mst->GetSpacing( ) );
+ marks->SetOrigin( mst->GetOrigin( ) );
+ marks->SetDirection( mst->GetDirection( ) );
+ marks->Allocate( );
+ marks->FillBuffer( false );
+
+ // Get candidates in maximum to minimum iteration
+ typename _TSkeletonQueue::const_reverse_iterator nIt = queue.rbegin( );
+ for( ; nIt != queue.rend( ); ++nIt )
+ {
+ // Mark it and update end-points
+ if( !( marks->GetPixel( nIt->second ) ) )
+ {
+ marks->SetPixel( nIt->second, true );
+ end_points.push_back( nIt->second );
+
+ // Mark path
+ TIndex it = nIt->second;
+ TIndex p = mst->GetParent( it );
+ while( it != p )
+ {
+ this->_MarkSphere( marks, dmap, it );
+ it = p;
+ p = mst->GetParent( it );
+
+ } // elihw
+ this->_MarkSphere( marks, dmap, it );
+
+ } // fi
+
+ } // rof
+}
+
+#endif // __fpa__Filters__Image__Skeleton__hxx__
+
+// eof - $RCSfile$
--- /dev/null
+// =========================================================================
+// @author Leonardo Florez Valencia
+// @email florez-l@javeriana.edu.co
+// =========================================================================
+#ifndef __fpa__Filters__MarksInterface__h__
+#define __fpa__Filters__MarksInterface__h__
+
+#include <itkProcessObject.h>
+
+namespace fpa
+{
+ namespace Filters
+ {
+ /**
+ */
+ template< class _TTraits >
+ class MarksInterface
+ {
+ public:
+ typedef MarksInterface Self;
+ typedef _TTraits TTraits;
+ fpaInternalTraitsMacro( typename, TTraits );
+
+ public:
+ MarksInterface( itk::ProcessObject* f );
+ virtual ~MarksInterface( );
+
+ protected:
+ virtual void _InitCollisions( unsigned long nSeeds );
+ virtual bool _Collisions( const TVertex& a, const TVertex& b );
+
+ virtual unsigned long _GetMark( const TNode& n ) const;
+ virtual unsigned long _GetMark( const TVertex& v ) const = 0;
+
+ virtual bool _IsMarked( const TNode& n ) const;
+ virtual bool _IsMarked( const TVertex& v ) const = 0;
+
+ virtual void _Mark( const TNode& n );
+ virtual void _Mark( const TVertex& v, unsigned long m ) = 0;
+
+ protected:
+ itk::ProcessObject::Pointer m_Filter;
+ };
+
+ } // ecapseman
+
+} // ecapseman
+
+#ifndef ITK_MANUAL_INSTANTIATION
+# include <fpa/Filters/MarksInterface.hxx>
+#endif // ITK_MANUAL_INSTANTIATION
+
+#endif // __fpa__Filters__MarksInterface__h__
+// eof - $RCSfile$
--- /dev/null
+// =========================================================================
+// @author Leonardo Florez Valencia
+// @email florez-l@javeriana.edu.co
+// =========================================================================
+#ifndef __fpa__Filters__MarksInterface__hxx__
+#define __fpa__Filters__MarksInterface__hxx__
+
+// -------------------------------------------------------------------------
+template< class _TTraits >
+fpa::Filters::MarksInterface< _TTraits >::
+MarksInterface( itk::ProcessObject* f )
+ : m_Filter( f )
+{
+}
+
+// -------------------------------------------------------------------------
+template< class _TTraits >
+fpa::Filters::MarksInterface< _TTraits >::
+~MarksInterface( )
+{
+}
+
+// -------------------------------------------------------------------------
+template< class _TTraits >
+void fpa::Filters::MarksInterface< _TTraits >::
+_InitCollisions( unsigned long nSeeds )
+{
+ // Do nothing
+}
+
+// -------------------------------------------------------------------------
+template< class _TTraits >
+bool fpa::Filters::MarksInterface< _TTraits >::
+_Collisions( const TVertex& a, const TVertex& b )
+{
+ return( false );
+}
+
+// -------------------------------------------------------------------------
+template< class _TTraits >
+unsigned long fpa::Filters::MarksInterface< _TTraits >::
+_GetMark( const TNode& n ) const
+{
+ return( this->_GetMark( n.Vertex ) );
+}
+
+// -------------------------------------------------------------------------
+template< class _TTraits >
+bool fpa::Filters::MarksInterface< _TTraits >::
+_IsMarked( const TNode& n ) const
+{
+ return( this->_IsMarked( n.Vertex ) );
+}
+
+// -------------------------------------------------------------------------
+template< class _TTraits >
+void fpa::Filters::MarksInterface< _TTraits >::
+_Mark( const TNode& n )
+{
+ this->_Mark( n.Vertex, ( unsigned long )( n.FrontId ) );
+}
+
+#endif // __fpa__Filters__MarksInterface__hxx__
+// eof - $RCSfile$
--- /dev/null
+// =========================================================================
+// @author Leonardo Florez Valencia
+// @email florez-l@javeriana.edu.co
+// =========================================================================
+#ifndef __fpa__Filters__MarksWithCollisionsInterface__h__
+#define __fpa__Filters__MarksWithCollisionsInterface__h__
+
+#include <utility>
+#include <vector>
+#include <fpa/Filters/MarksInterface.h>
+
+namespace fpa
+{
+ namespace Filters
+ {
+ /**
+ */
+ template< class _TTraits >
+ class MarksWithCollisionsInterface
+ : public fpa::Filters::MarksInterface< _TTraits >
+ {
+ public:
+ typedef MarksWithCollisionsInterface Self;
+ typedef fpa::Filters::MarksInterface< _TTraits > Superclass;
+ typedef _TTraits TTraits;
+ fpaInternalTraitsMacro( typename, TTraits );
+
+ // Minigraph to represent collisions
+ typedef std::pair< TVertex, bool > TCollision;
+ typedef std::vector< TCollision > TCollisionsRow;
+ typedef std::vector< TCollisionsRow > TCollisions;
+
+ public:
+ MarksWithCollisionsInterface( itk::ProcessObject* f );
+ virtual ~MarksWithCollisionsInterface( );
+
+ bool StopAtOneFront( ) const;
+ void StopAtOneFrontOn( );
+ void StopAtOneFrontOff( );
+ void SetStopAtOneFront( bool v );
+
+ protected:
+ virtual void _InitCollisions( unsigned long nSeeds ) override;
+ virtual bool _Collisions( const TVertex& a, const TVertex& b ) override;
+
+ protected:
+ bool m_StopAtOneFront;
+ TCollisions m_Collisions;
+ unsigned int m_NumberOfFronts;
+ unsigned int m_NumberOfSeeds;
+ };
+
+ } // ecapseman
+
+} // ecapseman
+
+#ifndef ITK_MANUAL_INSTANTIATION
+# include <fpa/Filters/MarksWithCollisionsInterface.hxx>
+#endif // ITK_MANUAL_INSTANTIATION
+
+#endif // __fpa__Filters__MarksWithCollisionsInterface__h__
+// eof - $RCSfile$
--- /dev/null
+// =========================================================================
+// @author Leonardo Florez Valencia
+// @email florez-l@javeriana.edu.co
+// =========================================================================
+#ifndef __fpa__Filters__MarksWithCollisionsInterface__hxx__
+#define __fpa__Filters__MarksWithCollisionsInterface__hxx__
+
+#include <queue>
+
+// -------------------------------------------------------------------------
+template< class _TTraits >
+fpa::Filters::MarksWithCollisionsInterface< _TTraits >::
+MarksWithCollisionsInterface( itk::ProcessObject* f )
+ : Superclass( f ),
+ m_StopAtOneFront( false ),
+ m_NumberOfFronts( 0 ),
+ m_NumberOfSeeds( 0 )
+{
+}
+
+// -------------------------------------------------------------------------
+template< class _TTraits >
+fpa::Filters::MarksWithCollisionsInterface< _TTraits >::
+~MarksWithCollisionsInterface( )
+{
+}
+
+// -------------------------------------------------------------------------
+template< class _TTraits >
+bool fpa::Filters::MarksWithCollisionsInterface< _TTraits >::
+StopAtOneFront( ) const
+{
+ return( this->m_StopAtOneFront );
+}
+
+// -------------------------------------------------------------------------
+template< class _TTraits >
+void fpa::Filters::MarksWithCollisionsInterface< _TTraits >::
+StopAtOneFrontOn( )
+{
+ this->SetStopAtOneFront( true );
+}
+
+// -------------------------------------------------------------------------
+template< class _TTraits >
+void fpa::Filters::MarksWithCollisionsInterface< _TTraits >::
+StopAtOneFrontOff( )
+{
+ this->SetStopAtOneFront( false );
+}
+
+// -------------------------------------------------------------------------
+template< class _TTraits >
+void fpa::Filters::MarksWithCollisionsInterface< _TTraits >::
+SetStopAtOneFront( bool v )
+{
+ if( this->m_StopAtOneFront != v )
+ {
+ this->m_StopAtOneFront = v;
+ if( this->m_Filter != NULL )
+ this->m_Filter->Modified( );
+
+ } // fi
+}
+
+// -------------------------------------------------------------------------
+template< class _TTraits >
+void fpa::Filters::MarksWithCollisionsInterface< _TTraits >::
+_InitCollisions( unsigned long nSeeds )
+{
+ this->m_NumberOfFronts = this->m_NumberOfSeeds = nSeeds;
+ TCollision coll( TVertex( ), false );
+ TCollisionsRow row( this->m_NumberOfFronts, coll );
+ this->m_Collisions.clear( );
+ this->m_Collisions.resize( this->m_NumberOfFronts, row );
+}
+
+// -------------------------------------------------------------------------
+template< class _TTraits >
+bool fpa::Filters::MarksWithCollisionsInterface< _TTraits >::
+_Collisions( const TVertex& a, const TVertex& b )
+{
+ unsigned long ma = this->_GetMark( a );
+ unsigned long mb = this->_GetMark( b );
+ if( ma == mb || ma == 0 || mb == 0 )
+ return( false );
+
+ // Mark collision, if it is new
+ ma--; mb--;
+ bool ret = false;
+ bool exists = this->m_Collisions[ ma ][ mb ].second;
+ exists &= this->m_Collisions[ mb ][ ma ].second;
+ if( !exists )
+ {
+ this->m_Collisions[ ma ][ mb ].first = a;
+ this->m_Collisions[ ma ][ mb ].second = true;
+ this->m_Collisions[ mb ][ ma ].first = b;
+ this->m_Collisions[ mb ][ ma ].second = true;
+
+ // Update number of fronts
+ unsigned long count = 0;
+ std::vector< bool > m( this->m_NumberOfSeeds, false );
+ std::queue< unsigned long > q;
+ q.push( 0 );
+ while( !q.empty( ) )
+ {
+ unsigned long f = q.front( );
+ q.pop( );
+
+ if( m[ f ] )
+ continue;
+ m[ f ] = true;
+ count++;
+
+ for( unsigned int n = 0; n < this->m_NumberOfSeeds; ++n )
+ if( this->m_Collisions[ f ][ n ].second && !m[ n ] )
+ q.push( n );
+
+ } // elihw
+ this->m_NumberOfFronts = this->m_NumberOfSeeds - count + 1;
+
+ } // fi
+ return(
+ this->m_StopAtOneFront &&
+ this->m_NumberOfSeeds > 1 &&
+ this->m_NumberOfFronts == 1
+ );
+}
+
+#endif // __fpa__Filters__MarksWithCollisionsInterface__hxx__
+// eof - $RCSfile$
--- /dev/null
+// =========================================================================
+// @author Leonardo Florez Valencia
+// @email florez-l@javeriana.edu.co
+// =========================================================================
+#ifndef __fpa__Filters__Mori__h__
+#define __fpa__Filters__Mori__h__
+
+#include <deque>
+#include <set>
+#include <itkConceptChecking.h>
+#include <fpa/Common/PeakDetector.h>
+#include <fpa/Filters/Algorithm.h>
+#include <fpa/Functors/RegionGrow/BinaryThreshold.h>
+
+namespace fpa
+{
+ namespace Filters
+ {
+ /**
+ */
+ template< class _TTraits >
+ class Mori
+ : public fpa::Filters::Algorithm< _TTraits >
+ {
+ public:
+ typedef _TTraits TTraits;
+ fpaTraitsMacro( typename, TTraits );
+
+ typedef fpa::Filters::Algorithm< TTraits > Superclass;
+ typedef Mori Self;
+ typedef itk::SmartPointer< Self > Pointer;
+ typedef itk::SmartPointer< const Self > ConstPointer;
+
+ typedef std::deque< TNode > TQueue;
+ typedef std::set< TInputValue > TThresholds;
+ typedef fpa::Common::PeakDetector TPeakDetector;
+ typedef TPeakDetector::TPeak TPeak;
+ typedef fpa::Functors::RegionGrow::BinaryThreshold< TInputValue > TPredicate;
+
+ protected:
+ itkConceptMacro(
+ Check_TOutputValue,
+ ( itk::Concept::IsUnsignedInteger< TOutputValue > )
+ );
+
+ public:
+ itkTypeMacro( fpa::Filters::Image::Mori, fpa::Filters::Algorithm );
+
+ itkGetConstMacro( InsideValue, TOutputValue );
+ itkSetMacro( InsideValue, TOutputValue );
+
+ itkGetConstMacro( MinimumThreshold, TInputValue );
+ itkSetMacro( MinimumThreshold, TInputValue );
+
+ public:
+ TOutputValue GetOutsideValue( ) const;
+ void SetOutsideValue( const TOutputValue& v );
+
+ unsigned long GetSignalKernelSize( ) const;
+ void SetSignalKernelSize( unsigned long k );
+
+ double GetSignalThreshold( ) const;
+ void SetSignalThreshold( double t );
+
+ double GetSignalInfluence( ) const;
+ void SetSignalInfluence( double i );
+
+ void ClearThresholds( );
+ void AddThreshold( const TInputValue& thr );
+ void SetThresholds(
+ const TInputValue& lower,
+ const TInputValue& upper,
+ const TInputValue& delta
+ );
+ const TThresholds& GetThresholds( ) const;
+ unsigned long GetNumberOfEvaluatedThresholds( ) const;
+ TInputValue GetOptimumThreshold( ) const;
+ void GetSignalValues(
+ unsigned long i, double& x, double& y, TPeak& p
+ ) const;
+
+ protected:
+ Mori( );
+ virtual ~Mori( );
+
+ virtual void _BeforeGenerateData( );
+ virtual void _Reinitialize( );
+ virtual void _UpdateOutputValue( TNode& n ) override;
+ virtual void _QueueClear( ) override;
+ virtual TNode _QueuePop( ) override;
+ virtual void _QueuePush( const TNode& n ) override;
+ virtual unsigned long _QueueSize( ) const override;
+ virtual void _ComputeOutputValue( TNode& n ) override;
+
+ private:
+ // Purposely not implemented.
+ Mori( const Self& other );
+ Self& operator=( const Self& other );
+
+ protected:
+ typename TPredicate::Pointer m_Predicate;
+
+ TOutputValue m_InsideValue;
+ TInputValue m_MinimumThreshold;
+ TThresholds m_Thresholds;
+ typename TThresholds::const_iterator m_CurrThr;
+
+ TQueue m_Queues[ 2 ];
+ unsigned int m_CurrQueue;
+ double m_CurrCount;
+
+ TPeakDetector m_PeakDetector;
+ };
+
+ } // ecapseman
+
+} // ecapseman
+
+#ifndef ITK_MANUAL_INSTANTIATION
+# include <fpa/Filters/Mori.hxx>
+#endif // ITK_MANUAL_INSTANTIATION
+
+#endif // __fpa__Filters__Mori__h__
+// eof - $RCSfile$
--- /dev/null
+// =========================================================================
+// @author Leonardo Florez Valencia
+// @email florez-l@javeriana.edu.co
+// =========================================================================
+#ifndef __fpa__Filters__Mori__hxx__
+#define __fpa__Filters__Mori__hxx__
+
+// -------------------------------------------------------------------------
+template< class _TTraits >
+typename fpa::Filters::Mori< _TTraits >::
+TOutputValue fpa::Filters::Mori< _TTraits >::
+GetOutsideValue( ) const
+{
+ return( this->GetInitValue( ) );
+}
+
+// -------------------------------------------------------------------------
+template< class _TTraits >
+void fpa::Filters::Mori< _TTraits >::
+SetOutsideValue( const TOutputValue& v )
+{
+ this->SetInitValue( v );
+}
+
+// -------------------------------------------------------------------------
+template< class _TTraits >
+unsigned long fpa::Filters::Mori< _TTraits >::
+GetSignalKernelSize( ) const
+{
+ return( this->m_PeakDetector.GetKernelSize( ) );
+}
+
+// -------------------------------------------------------------------------
+template< class _TTraits >
+void fpa::Filters::Mori< _TTraits >::
+SetSignalKernelSize( unsigned long k )
+{
+ this->m_PeakDetector.SetKernelSize( k );
+ this->Modified( );
+}
+
+// -------------------------------------------------------------------------
+template< class _TTraits >
+double fpa::Filters::Mori< _TTraits >::
+GetSignalThreshold( ) const
+{
+ return( this->m_PeakDetector.GetThreshold( ) );
+}
+
+// -------------------------------------------------------------------------
+template< class _TTraits >
+void fpa::Filters::Mori< _TTraits >::
+SetSignalThreshold( double t )
+{
+ this->m_PeakDetector.SetThreshold( t );
+ this->Modified( );
+}
+
+// -------------------------------------------------------------------------
+template< class _TTraits >
+double fpa::Filters::Mori< _TTraits >::
+GetSignalInfluence( ) const
+{
+ return( this->m_PeakDetector.GetInfluence( ) );
+}
+
+// -------------------------------------------------------------------------
+template< class _TTraits >
+void fpa::Filters::Mori< _TTraits >::
+SetSignalInfluence( double i )
+{
+ this->m_PeakDetector.SetInfluence( i );
+ this->Modified( );
+}
+
+// -------------------------------------------------------------------------
+template< class _TTraits >
+void fpa::Filters::Mori< _TTraits >::
+ClearThresholds( )
+{
+ this->m_Thresholds.clear( );
+ this->Modified( );
+}
+
+// -------------------------------------------------------------------------
+template< class _TTraits >
+void fpa::Filters::Mori< _TTraits >::
+AddThreshold( const TInputValue& thr )
+{
+ if( this->m_Thresholds.insert( thr ).second )
+ this->Modified( );
+}
+
+// -------------------------------------------------------------------------
+template< class _TTraits >
+const typename fpa::Filters::Mori< _TTraits >::
+TThresholds& fpa::Filters::Mori< _TTraits >::
+GetThresholds( ) const
+{
+ return( this->m_Thresholds );
+}
+
+// -------------------------------------------------------------------------
+template< class _TTraits >
+unsigned long fpa::Filters::Mori< _TTraits >::
+GetNumberOfEvaluatedThresholds( ) const
+{
+ return( this->m_PeakDetector.GetNumberOfSamples( ) );
+}
+
+// -------------------------------------------------------------------------
+template< class _TTraits >
+typename fpa::Filters::Mori< _TTraits >::
+TInputValue fpa::Filters::Mori< _TTraits >::
+GetOptimumThreshold( ) const
+{
+ TInputValue thr = TInputValue( 0 );
+ unsigned long n = this->m_PeakDetector.GetNumberOfSamples( );
+ if( n > 1 )
+ thr = TInputValue( this->m_PeakDetector.GetXValues( )[ n - 2 ] );
+ return( thr );
+}
+
+// -------------------------------------------------------------------------
+template< class _TTraits >
+void fpa::Filters::Mori< _TTraits >::
+GetSignalValues(
+ unsigned long i, double& x, double& y, TPeak& p
+ ) const
+{
+ if( i < this->m_PeakDetector.GetNumberOfSamples( ) )
+ {
+ x = this->m_PeakDetector.GetXValues( )[ i ];
+ y = this->m_PeakDetector.GetYValues( )[ i ];
+ p = this->m_PeakDetector.GetPeaks( )[ i ];
+
+ } // fi
+}
+
+// -------------------------------------------------------------------------
+template< class _TTraits >
+void fpa::Filters::Mori< _TTraits >::
+SetThresholds(
+ const TInputValue& lower,
+ const TInputValue& upper,
+ const TInputValue& delta
+ )
+{
+ for( TInputValue t = lower; t <= upper; t += delta )
+ this->AddThreshold( t );
+}
+
+// -------------------------------------------------------------------------
+template< class _TTraits >
+fpa::Filters::Mori< _TTraits >::
+Mori( )
+ : Superclass( ),
+ m_InsideValue( TOutputValue( 1 ) )
+{
+ this->SetOutsideValue( 0 );
+ this->m_Predicate = TPredicate::New( );
+ this->m_Predicate->StrictOff( );
+ if( std::numeric_limits< TInputValue >::is_integer )
+ this->m_MinimumThreshold = std::numeric_limits< TInputValue >::min( );
+ else
+ this->m_MinimumThreshold = -std::numeric_limits< TInputValue >::max( );
+ this->m_PeakDetector.SetKernelSize( 20 );
+ this->m_PeakDetector.SetThreshold( 500 );
+ this->m_PeakDetector.SetInfluence( 0.5 );
+}
+
+// -------------------------------------------------------------------------
+template< class _TTraits >
+fpa::Filters::Mori< _TTraits >::
+~Mori( )
+{
+}
+
+// -------------------------------------------------------------------------
+template< class _TTraits >
+void fpa::Filters::Mori< _TTraits >::
+_BeforeGenerateData( )
+{
+ this->Superclass::_BeforeGenerateData( );
+
+ // Prepare queues
+ this->_QueueClear( );
+ this->m_CurrQueue = 0;
+
+ // Prepare iteration over all thresholds
+ this->m_CurrThr = this->m_Thresholds.begin( );
+ this->m_Predicate->SetLowerThreshold( *( this->m_CurrThr ) );
+ this->m_CurrThr++;
+ this->m_Predicate->SetUpperThreshold( *( this->m_CurrThr ) );
+
+ // Prepare counting signal
+ this->m_CurrCount = double( 0 );
+ this->m_PeakDetector.Clear( );
+}
+
+// -------------------------------------------------------------------------
+template< class _TTraits >
+void fpa::Filters::Mori< _TTraits >::
+_Reinitialize( )
+{
+ if( this->m_Queues[ this->m_CurrQueue ].size( ) == 0 )
+ {
+ // Update peak detector
+ TPeak p = this->m_PeakDetector.AddValue(
+ *this->m_CurrThr, this->m_CurrCount
+ );
+ this->m_CurrThr++;
+ this->m_CurrQueue = ( this->m_CurrQueue + 1 ) % 2;
+ if( this->m_CurrThr != this->m_Thresholds.end( ) )
+ {
+ // Update predicate and counting value
+ this->m_Predicate->SetUpperThreshold( *( this->m_CurrThr ) );
+ this->m_CurrCount = double( 0 );
+
+ // Peak detected? -> stop!
+ if(
+ p == TPeakDetector::PosPeak &&
+ this->m_MinimumThreshold < *( this->m_CurrThr )
+ )
+ this->_QueueClear( );
+ }
+ else
+ this->_QueueClear( );
+
+ } // fi
+}
+
+// -------------------------------------------------------------------------
+template< class _TTraits >
+void fpa::Filters::Mori< _TTraits >::
+_UpdateOutputValue( TNode& n )
+{
+ TInputValue value = this->_GetInputValue( n.Vertex );
+ bool inside = this->m_Predicate->Evaluate( value );
+ if( !inside )
+ {
+ n.Value = this->m_InitValue;
+ n.FrontId++;
+ this->m_Queues[ ( this->m_CurrQueue + 1 ) % 2 ].push_back( n );
+ n.FrontId = 0;
+ }
+ else
+ {
+ n.Value = this->m_InsideValue;
+ this->m_CurrCount += double( 1 );
+
+ } // fi
+}
+
+// -------------------------------------------------------------------------
+template< class _TTraits >
+void fpa::Filters::Mori< _TTraits >::
+_QueueClear( )
+{
+ this->m_Queues[ 0 ].clear( );
+ this->m_Queues[ 1 ].clear( );
+}
+
+// -------------------------------------------------------------------------
+template< class _TTraits >
+typename fpa::Filters::Mori< _TTraits >::
+TNode fpa::Filters::Mori< _TTraits >::
+_QueuePop( )
+{
+ TNode n = this->m_Queues[ this->m_CurrQueue ].front( );
+ this->m_Queues[ this->m_CurrQueue ].pop_front( );
+ return( n );
+}
+
+// -------------------------------------------------------------------------
+template< class _TTraits >
+void fpa::Filters::Mori< _TTraits >::
+_QueuePush( const TNode& n )
+{
+ this->m_Queues[ this->m_CurrQueue ].push_back( n );
+}
+
+// -------------------------------------------------------------------------
+template< class _TTraits >
+unsigned long fpa::Filters::Mori< _TTraits >::
+_QueueSize( ) const
+{
+ return( this->m_Queues[ this->m_CurrQueue ].size( ) );
+}
+// -------------------------------------------------------------------------
+template< class _TTraits >
+void fpa::Filters::Mori< _TTraits >::
+_ComputeOutputValue( TNode& n )
+{
+ // Do nothing
+}
+
+#endif // __fpa__Filters__Mori__hxx__
+// eof - $RCSfile$
--- /dev/null
+// =========================================================================
+// @author Leonardo Florez Valencia
+// @email florez-l@javeriana.edu.co
+// =========================================================================
+#ifndef __fpa__Filters__RegionGrow__h__
+#define __fpa__Filters__RegionGrow__h__
+
+#include <deque>
+#include <itkConceptChecking.h>
+#include <itkFunctionBase.h>
+#include <fpa/Filters/Algorithm.h>
+#include <fpa/Functors/BaseVertexFunction.h>
+
+namespace fpa
+{
+ namespace Filters
+ {
+ /**
+ */
+ template< class _TTraits >
+ class RegionGrow
+ : public fpa::Filters::Algorithm< _TTraits >
+ {
+ public:
+ typedef _TTraits TTraits;
+ fpaTraitsMacro( typename, TTraits );
+
+ typedef fpa::Filters::Algorithm< TTraits > Superclass;
+ typedef RegionGrow Self;
+ typedef itk::SmartPointer< Self > Pointer;
+ typedef itk::SmartPointer< const Self > ConstPointer;
+
+ typedef std::deque< TNode > TQueue;
+ typedef itk::FunctionBase< TInputValue, bool > TScalarPredicate;
+ typedef fpa::Functors::BaseVertexFunction< TVertex, bool > TVertexPredicate;
+
+ protected:
+ itkConceptMacro(
+ Check_TOutputValue,
+ ( itk::Concept::IsUnsignedInteger< TOutputValue > )
+ );
+
+ public:
+ itkTypeMacro( fpa::Filters::RegionGrow, fpa::Filters::Algorithm );
+
+ itkGetConstObjectMacro( ScalarPredicate, TScalarPredicate );
+ itkGetObjectMacro( ScalarPredicate, TScalarPredicate );
+
+ itkGetConstObjectMacro( VertexPredicate, TVertexPredicate );
+ itkGetObjectMacro( VertexPredicate, TVertexPredicate );
+
+ itkGetConstMacro( InsideValue, TOutputValue );
+ itkSetMacro( InsideValue, TOutputValue );
+
+ public:
+ void SetPredicate( TScalarPredicate* p );
+ void SetPredicate( TVertexPredicate* p );
+
+ TOutputValue GetOutsideValue( ) const;
+ void SetOutsideValue( const TOutputValue& v );
+
+ protected:
+ RegionGrow( );
+ virtual ~RegionGrow( );
+
+ virtual void _UpdateOutputValue( TNode& n ) override;
+ virtual void _QueueClear( ) override;
+ virtual TNode _QueuePop( ) override;
+ virtual void _QueuePush( const TNode& n ) override;
+ virtual unsigned long _QueueSize( ) const override;
+ virtual void _ComputeOutputValue( TNode& n ) override;
+
+ private:
+ // Purposely not implemented.
+ RegionGrow( const Self& other );
+ Self& operator=( const Self& other );
+
+ protected:
+ typename TScalarPredicate::Pointer m_ScalarPredicate;
+ typename TVertexPredicate::Pointer m_VertexPredicate;
+
+ TOutputValue m_InsideValue;
+ TQueue m_Queue;
+ };
+
+ } // ecapseman
+
+} // ecapseman
+
+#ifndef ITK_MANUAL_INSTANTIATION
+# include <fpa/Filters/RegionGrow.hxx>
+#endif // ITK_MANUAL_INSTANTIATION
+
+#endif // __fpa__Filters__RegionGrow__h__
+// eof - $RCSfile$
--- /dev/null
+// =========================================================================
+// @author Leonardo Florez Valencia
+// @email florez-l@javeriana.edu.co
+// =========================================================================
+#ifndef __fpa__Filters__RegionGrow__hxx__
+#define __fpa__Filters__RegionGrow__hxx__
+
+// -------------------------------------------------------------------------
+template< class _TTraits >
+void fpa::Filters::RegionGrow< _TTraits >::
+SetPredicate( TScalarPredicate* p )
+{
+ if( this->m_ScalarPredicate.GetPointer( ) != p )
+ {
+ this->_Deassociate( this->m_ScalarPredicate );
+ this->m_ScalarPredicate = p;
+ this->_Associate( this->m_ScalarPredicate );
+ this->Modified( );
+
+ } // fi
+}
+
+// -------------------------------------------------------------------------
+template< class _TTraits >
+void fpa::Filters::RegionGrow< _TTraits >::
+SetPredicate( TVertexPredicate* p )
+{
+ if( this->m_VertexPredicate.GetPointer( ) != p )
+ {
+ this->_Deassociate( this->m_VertexPredicate );
+ this->m_VertexPredicate = p;
+ this->_Associate( this->m_VertexPredicate );
+ this->Modified( );
+
+ } // fi
+}
+
+// -------------------------------------------------------------------------
+template< class _TTraits >
+typename fpa::Filters::RegionGrow< _TTraits >::
+TOutputValue fpa::Filters::RegionGrow< _TTraits >::
+GetOutsideValue( ) const
+{
+ return( this->GetInitValue( ) );
+}
+
+// -------------------------------------------------------------------------
+template< class _TTraits >
+void fpa::Filters::RegionGrow< _TTraits >::
+SetOutsideValue( const TOutputValue& v )
+{
+ this->SetInitValue( v );
+}
+
+// -------------------------------------------------------------------------
+template< class _TTraits >
+fpa::Filters::RegionGrow< _TTraits >::
+RegionGrow( )
+ : Superclass( ),
+ m_InsideValue( TOutputValue( 1 ) )
+{
+ this->SetOutsideValue( 0 );
+}
+
+// -------------------------------------------------------------------------
+template< class _TTraits >
+fpa::Filters::RegionGrow< _TTraits >::
+~RegionGrow( )
+{
+}
+
+// -------------------------------------------------------------------------
+template< class _TTraits >
+void fpa::Filters::RegionGrow< _TTraits >::
+_UpdateOutputValue( TNode& n )
+{
+ TInputValue value = this->_GetInputValue( n );
+ bool inside = false;
+ if( this->m_ScalarPredicate.IsNotNull( ) )
+ inside = this->m_ScalarPredicate->Evaluate( value );
+ if( this->m_VertexPredicate.IsNotNull( ) )
+ inside &= this->m_VertexPredicate->Evaluate( n.Vertex, n.Parent );
+ if( !inside )
+ {
+ n.Value = this->GetOutsideValue( );
+ n.FrontId = 0;
+ }
+ else
+ n.Value = this->GetInsideValue( );
+}
+
+// -------------------------------------------------------------------------
+template< class _TTraits >
+void fpa::Filters::RegionGrow< _TTraits >::
+_QueueClear( )
+{
+ this->m_Queue.clear( );
+}
+
+// -------------------------------------------------------------------------
+template< class _TTraits >
+typename fpa::Filters::RegionGrow< _TTraits >::
+TNode fpa::Filters::RegionGrow< _TTraits >::
+_QueuePop( )
+{
+ TNode n = this->m_Queue.front( );
+ this->m_Queue.pop_front( );
+ return( n );
+}
+
+// -------------------------------------------------------------------------
+template< class _TTraits >
+void fpa::Filters::RegionGrow< _TTraits >::
+_QueuePush( const TNode& n )
+{
+ this->m_Queue.push_back( n );
+}
+
+// -------------------------------------------------------------------------
+template< class _TTraits >
+unsigned long fpa::Filters::RegionGrow< _TTraits >::
+_QueueSize( ) const
+{
+ return( this->m_Queue.size( ) );
+}
+
+// -------------------------------------------------------------------------
+template< class _TTraits >
+void fpa::Filters::RegionGrow< _TTraits >::
+_ComputeOutputValue( TNode& n )
+{
+ // Do nothing
+}
+
+#endif // __fpa__Filters__RegionGrow__hxx__
+// eof - $RCSfile$
--- /dev/null
+// =========================================================================
+// @author Leonardo Florez Valencia
+// @email florez-l@javeriana.edu.co
+// =========================================================================
+#ifndef __fpa__Filters__SeedsInterface__h__
+#define __fpa__Filters__SeedsInterface__h__
+
+#include <itkDataObject.h>
+#include <itkProcessObject.h>
+#include <fpa/Config.h>
+
+namespace fpa
+{
+ namespace Filters
+ {
+ /**
+ */
+ template< class _TTraits >
+ class SeedsInterface
+ {
+ public:
+ typedef SeedsInterface Self;
+ typedef _TTraits TTraits;
+ fpaInternalTraitsMacro( typename, TTraits );
+
+ public:
+ SeedsInterface( itk::ProcessObject* f );
+ virtual ~SeedsInterface( );
+
+ void AddSeed( const TPoint& s );
+ void AddSeed( const TVertex& s );
+ void ClearSeeds( );
+ unsigned long GetNumberOfSeeds( ) const;
+
+ const TNodes& GetSeeds( ) const;
+
+ protected:
+ virtual void _PrepareSeeds( const itk::DataObject* input );
+
+ protected:
+ TSeeds m_InputSeeds;
+ TNodes m_UnifiedSeeds;
+ itk::ProcessObject::Pointer m_Filter;
+ };
+
+ } // ecapseman
+
+} // ecapseman
+
+#ifndef ITK_MANUAL_INSTANTIATION
+# include <fpa/Filters/SeedsInterface.hxx>
+#endif // ITK_MANUAL_INSTANTIATION
+
+#endif // __fpa__Filters__SeedsInterface__h__
+// eof - $RCSfile$
--- /dev/null
+// =========================================================================
+// @author Leonardo Florez Valencia
+// @email florez-l@javeriana.edu.co
+// =========================================================================
+#ifndef __fpa__Filters__SeedsInterface__hxx__
+#define __fpa__Filters__SeedsInterface__hxx__
+
+#include <itkImageBase.h>
+
+// -------------------------------------------------------------------------
+template< class _TTraits >
+fpa::Filters::SeedsInterface< _TTraits >::
+SeedsInterface( itk::ProcessObject* f )
+ : m_Filter( f )
+{
+}
+
+// -------------------------------------------------------------------------
+template< class _TTraits >
+fpa::Filters::SeedsInterface< _TTraits >::
+~SeedsInterface( )
+{
+}
+
+// -------------------------------------------------------------------------
+template< class _TTraits >
+void fpa::Filters::SeedsInterface< _TTraits >::
+AddSeed( const TPoint& s )
+{
+ TSeed seed( this->m_InputSeeds.size( ) + 1 );
+ seed.Point = s;
+ seed.IsPoint = true;
+ this->m_InputSeeds.push_back( seed );
+ if( this->m_Filter.IsNotNull( ) )
+ this->m_Filter->Modified( );
+}
+
+// -------------------------------------------------------------------------
+template< class _TTraits >
+void fpa::Filters::SeedsInterface< _TTraits >::
+AddSeed( const TVertex& s )
+{
+ TSeed seed( this->m_InputSeeds.size( ) + 1 );
+ seed.Vertex = s;
+ seed.IsPoint = false;
+ this->m_InputSeeds.push_back( seed );
+ if( this->m_Filter.IsNotNull( ) )
+ this->m_Filter->Modified( );
+}
+
+// -------------------------------------------------------------------------
+template< class _TTraits >
+void fpa::Filters::SeedsInterface< _TTraits >::
+ClearSeeds( )
+{
+ this->m_InputSeeds.clear( );
+ this->m_UnifiedSeeds.clear( );
+ if( this->m_Filter.IsNotNull( ) )
+ this->m_Filter->Modified( );
+}
+
+// -------------------------------------------------------------------------
+template< class _TTraits >
+const typename fpa::Filters::SeedsInterface< _TTraits >::
+TNodes& fpa::Filters::SeedsInterface< _TTraits >::
+GetSeeds( ) const
+{
+ return( this->m_UnifiedSeeds );
+}
+
+// -------------------------------------------------------------------------
+template< class _TTraits >
+void fpa::Filters::SeedsInterface< _TTraits >::
+_PrepareSeeds( const itk::DataObject* input )
+{
+ // Input object is an image?
+ typedef itk::ImageBase< Self::Dimension > _TImageBase;
+ const _TImageBase* image = dynamic_cast< const _TImageBase* >( input );
+ if( image != NULL )
+ {
+ this->m_UnifiedSeeds.clear( );
+ for( TSeed iSeed: this->m_InputSeeds )
+ {
+ if( iSeed.IsPoint )
+ image->TransformPhysicalPointToIndex( iSeed.Point, iSeed.Vertex );
+ TNode node;
+ node.Vertex = iSeed.Vertex;
+ node.Parent = iSeed.Vertex;
+ node.FrontId = iSeed.FrontId;
+ this->m_UnifiedSeeds.insert( node );
+
+ } // rof
+
+ } // fi
+}
+
+#endif // __fpa__Filters__SeedsInterface__hxx__
+// eof - $RCSfile$
--- /dev/null
+// =========================================================================
+// @author Leonardo Florez Valencia
+// @email florez-l@javeriana.edu.co
+// =========================================================================
+#ifndef __fpa__Filters__SingleSeedInterface__h__
+#define __fpa__Filters__SingleSeedInterface__h__
+
+#include <itkDataObject.h>
+#include <itkProcessObject.h>
+#include <fpa/Config.h>
+
+namespace fpa
+{
+ namespace Filters
+ {
+ /**
+ */
+ template< class _TTraits >
+ class SingleSeedInterface
+ {
+ public:
+ typedef SingleSeedInterface Self;
+ typedef _TTraits TTraits;
+ fpaInternalTraitsMacro( typename, TTraits );
+
+ public:
+ SingleSeedInterface( itk::ProcessObject* f );
+ virtual ~SingleSeedInterface( );
+
+ void SetSeed( const TPoint& s );
+ void SetSeed( const TVertex& s );
+
+ const TNodes& GetSeeds( ) const;
+
+ protected:
+ virtual void _PrepareSeeds( const itk::DataObject* input );
+
+ protected:
+ TSeed m_InputSeed;
+ TNodes m_UnifiedSeed;
+ itk::ProcessObject::Pointer m_Filter;
+ };
+
+ } // ecapseman
+
+} // ecapseman
+
+#ifndef ITK_MANUAL_INSTANTIATION
+# include <fpa/Filters/SingleSeedInterface.hxx>
+#endif // ITK_MANUAL_INSTANTIATION
+
+#endif // __fpa__Filters__SingleSeedInterface__h__
+// eof - $RCSfile$
--- /dev/null
+// =========================================================================
+// @author Leonardo Florez Valencia
+// @email florez-l@javeriana.edu.co
+// =========================================================================
+#ifndef __fpa__Filters__SingleSeedInterface__hxx__
+#define __fpa__Filters__SingleSeedInterface__hxx__
+
+// -------------------------------------------------------------------------
+template< class _TTraits >
+fpa::Filters::SingleSeedInterface< _TTraits >::
+SingleSeedInterface( itk::ProcessObject* f )
+ : m_Filter( f )
+{
+}
+
+// -------------------------------------------------------------------------
+template< class _TTraits >
+fpa::Filters::SingleSeedInterface< _TTraits >::
+~SingleSeedInterface( )
+{
+}
+
+// -------------------------------------------------------------------------
+template< class _TTraits >
+void fpa::Filters::SingleSeedInterface< _TTraits >::
+SetSeed( const TPoint& s )
+{
+ this->m_InputSeed.Point = s;
+ this->m_InputSeed.IsPoint = true;
+ if( this->m_Filter.IsNotNull( ) )
+ this->m_Filter->Modified( );
+}
+
+// -------------------------------------------------------------------------
+template< class _TTraits >
+void fpa::Filters::SingleSeedInterface< _TTraits >::
+SetSeed( const TVertex& s )
+{
+ this->m_InputSeed.Vertex = s;
+ this->m_InputSeed.IsPoint = false;
+ if( this->m_Filter.IsNotNull( ) )
+ this->m_Filter->Modified( );
+}
+
+// -------------------------------------------------------------------------
+template< class _TTraits >
+const typename fpa::Filters::SingleSeedInterface< _TTraits >::
+TNodes& fpa::Filters::SingleSeedInterface< _TTraits >::
+GetSeeds( ) const
+{
+ return( this->m_UnifiedSeed );
+}
+
+// -------------------------------------------------------------------------
+template< class _TTraits >
+void fpa::Filters::SingleSeedInterface< _TTraits >::
+_PrepareSeeds( const itk::DataObject* input )
+{
+ // Input object is an image?
+ typedef itk::ImageBase< Self::Dimension > _TImageBase;
+ const _TImageBase* image = dynamic_cast< const _TImageBase* >( input );
+ if( image != NULL )
+ {
+ this->m_UnifiedSeed.clear( );
+ TSeed iSeed = this->m_InputSeed;
+ if( iSeed.IsPoint )
+ image->TransformPhysicalPointToIndex( iSeed.Point, iSeed.Vertex );
+ TNode node;
+ node.Vertex = iSeed.Vertex;
+ node.Parent = iSeed.Vertex;
+ node.FrontId = iSeed.FrontId;
+ this->m_UnifiedSeed.insert( node );
+
+ } // fi
+}
+
+#endif // __fpa__Filters__SingleSeedInterface__hxx__
+// eof - $RCSfile$
--- /dev/null
+// =========================================================================
+// @author Leonardo Florez Valencia
+// @email florez-l@javeriana.edu.co
+// =========================================================================
+#ifndef __fpa__Functors__BaseVertexFunction__h__
+#define __fpa__Functors__BaseVertexFunction__h__
+
+#include <itkDataObject.h>
+#include <itkObject.h>
+
+namespace fpa
+{
+ namespace Functors
+ {
+ /**
+ */
+ template< class _TVertex >
+ class LightBaseVertexFunction
+ : public itk::Object
+ {
+ public:
+ typedef _TVertex TVertex;
+ typedef itk::Object Superclass;
+ typedef LightBaseVertexFunction Self;
+ typedef itk::SmartPointer< Self > Pointer;
+ typedef itk::SmartPointer< const Self > ConstPointer;
+
+ public:
+ itkTypeMacro( fpa::Functors::LightBaseVertexFunction, itk::Object );
+
+ itkSetConstObjectMacro( DataObject, itk::DataObject );
+
+ public:
+ template< class _TDataObject = itk::DataObject >
+ const _TDataObject* GetDataObject( ) const
+ {
+ return(
+ dynamic_cast< const _TDataObject* >(
+ this->m_DataObject.GetPointer( )
+ )
+ );
+ }
+
+ protected:
+ LightBaseVertexFunction( )
+ : Superclass( ),
+ m_DataObject( NULL )
+ {
+ }
+
+ virtual ~LightBaseVertexFunction( )
+ {
+ }
+
+ private:
+ // Purposely not implemented.
+ LightBaseVertexFunction( const Self& other );
+ Self& operator=( const Self& other );
+
+ protected:
+ itk::DataObject::ConstPointer m_DataObject;
+ };
+
+ /**
+ */
+ template< class _TVertex, class _TValue >
+ class BaseVertexFunction
+ : public LightBaseVertexFunction< _TVertex >
+ {
+ public:
+ typedef _TVertex TVertex;
+ typedef _TValue TValue;
+ typedef LightBaseVertexFunction< _TVertex > Superclass;
+ typedef BaseVertexFunction Self;
+ typedef itk::SmartPointer< Self > Pointer;
+ typedef itk::SmartPointer< const Self > ConstPointer;
+
+ public:
+ itkTypeMacro(
+ fpa::Functors::RegionGrow::BaseVertexFunction,
+ fpa::Functors::RegionGrow::LightBaseVertexFunction
+ );
+
+ public:
+ virtual TValue Evaluate(
+ const TVertex& vertex, const TVertex& parent
+ ) const = 0;
+
+ protected:
+ BaseVertexFunction( )
+ : Superclass( )
+ {
+ }
+
+ virtual ~BaseVertexFunction( )
+ {
+ }
+
+ private:
+ // Purposely not implemented.
+ BaseVertexFunction( const Self& other );
+ Self& operator=( const Self& other );
+ };
+
+ } // ecapseman
+
+} // ecapseman
+
+#endif // __fpa__Functors__BaseVertexFunction__h__
+// eof - $RCSfile$
--- /dev/null
+// =========================================================================
+// @author Leonardo Florez Valencia
+// @email florez-l@javeriana.edu.co
+// =========================================================================
+#ifndef __fpa__Functors__Dijkstra__Image__Gaussian__h__
+#define __fpa__Functors__Dijkstra__Image__Gaussian__h__
+
+#include <cmath>
+#include <fpa/Functors/BaseVertexFunction.h>
+
+namespace fpa
+{
+ namespace Functors
+ {
+ namespace Dijkstra
+ {
+ namespace Image
+ {
+ /**
+ */
+ template< class _TImage, class _TValue >
+ class Gaussian
+ : public fpa::Functors::BaseVertexFunction< typename _TImage::IndexType, _TValue >
+ {
+ public:
+ typedef _TImage TImage;
+ typedef _TValue TValue;
+ typedef typename TImage::IndexType TVertex;
+ typedef fpa::Functors::BaseVertexFunction< TVertex, TValue > Superclass;
+ typedef Gaussian Self;
+ typedef itk::SmartPointer< Self > Pointer;
+ typedef itk::SmartPointer< const Self > ConstPointer;
+
+ public:
+ itkNewMacro( Self );
+ itkTypeMacro(
+ fpa::Functors::Dijkstra::Image::Gaussian,
+ fpa::Functors::BaseVertexFunction
+ );
+
+ itkGetConstMacro( Alpha, double );
+ itkSetMacro( Alpha, double );
+
+ itkGetConstMacro( Beta, double );
+ itkSetMacro( Beta, double );
+
+ public:
+ virtual TValue Evaluate( const TVertex& v, const TVertex& p ) const override
+ {
+ const TImage* image =
+ dynamic_cast< const TImage* >(
+ this->m_DataObject.GetPointer( )
+ );
+ if( image != NULL )
+ {
+ double d = double( image->GetPixel( v ) );
+ d -= double( image->GetPixel( p ) );
+ d /= this->m_Beta;
+ d = std::exp( d * d ) - double( 1 );
+ return( TValue( std::pow( d, this->m_Alpha ) ) );
+ }
+ else
+ return( TValue( -1 ) );
+ }
+
+ protected:
+ Gaussian( )
+ : Superclass( ),
+ m_Alpha( double( 1 ) ),
+ m_Beta( double( 1 ) )
+ {
+ }
+ virtual ~Gaussian( )
+ {
+ }
+
+ private:
+ // Purposely not implemented.
+ Gaussian( const Self& other );
+ Self& operator=( const Self& other );
+
+ protected:
+ double m_Alpha;
+ double m_Beta;
+ };
+
+ } // ecapseman
+
+ } // ecapseman
+
+ } // ecapseman
+
+} // ecapseman
+
+#endif // __fpa__Functors__Dijkstra__Gaussian__h__
+// eof - $RCSfile$
--- /dev/null
+// =========================================================================
+// @author Leonardo Florez Valencia
+// @email florez-l@javeriana.edu.co
+// =========================================================================
+#ifndef __fpa__Functors__Dijkstra__Image__Identity__h__
+#define __fpa__Functors__Dijkstra__Image__Identity__h__
+
+#include <fpa/Functors/BaseVertexFunction.h>
+
+namespace fpa
+{
+ namespace Functors
+ {
+ namespace Dijkstra
+ {
+ namespace Image
+ {
+ /**
+ */
+ template< class _TImage, class _TValue >
+ class Identity
+ : public fpa::Functors::BaseVertexFunction< typename _TImage::IndexType, _TValue >
+ {
+ public:
+ typedef _TImage TImage;
+ typedef _TValue TValue;
+ typedef typename TImage::IndexType TVertex;
+ typedef fpa::Functors::BaseVertexFunction< TVertex, TValue > Superclass;
+ typedef Identity Self;
+ typedef itk::SmartPointer< Self > Pointer;
+ typedef itk::SmartPointer< const Self > ConstPointer;
+
+ public:
+ itkNewMacro( Self );
+ itkTypeMacro(
+ fpa::Functors::Dijkstra::Image::Identity,
+ fpa::Functors::BaseVertexFunction
+ );
+
+ public:
+ virtual TValue Evaluate( const TVertex& v, const TVertex& p ) const override
+ {
+ const TImage* image =
+ dynamic_cast< const TImage* >(
+ this->m_DataObject.GetPointer( )
+ );
+ if( image != NULL )
+ return( TValue( image->GetPixel( v ) ) );
+ else
+ return( TValue( -1 ) );
+ }
+
+ protected:
+ Identity( )
+ : Superclass( )
+ {
+ }
+ virtual ~Identity( )
+ {
+ }
+
+ private:
+ // Purposely not implemented.
+ Identity( const Self& other );
+ Self& operator=( const Self& other );
+ };
+
+ } // ecapseman
+
+ } // ecapseman
+
+ } // ecapseman
+
+} // ecapseman
+
+#endif // __fpa__Functors__Dijkstra__Identity__h__
+// eof - $RCSfile$
--- /dev/null
+// =========================================================================
+// @author Leonardo Florez Valencia
+// @email florez-l@javeriana.edu.co
+// =========================================================================
+#ifndef __fpa__Functors__Dijkstra__Invert__h__
+#define __fpa__Functors__Dijkstra__Invert__h__
+
+#include <itkFunctionBase.h>
+
+namespace fpa
+{
+ namespace Functors
+ {
+ namespace Dijkstra
+ {
+ /**
+ */
+ template< class _TValue >
+ class Invert
+ : public itk::FunctionBase< _TValue, _TValue >
+ {
+ public:
+ typedef _TValue TValue;
+ typedef itk::FunctionBase< _TValue, _TValue > Superclass;
+ typedef Invert Self;
+ typedef itk::SmartPointer< Self > Pointer;
+ typedef itk::SmartPointer< const Self > ConstPointer;
+
+ public:
+ itkNewMacro( Self );
+ itkTypeMacro( fpa::Functors::Dijkstra::Invert, itk::FunctionBase );
+
+ itkGetConstMacro( Alpha, double );
+ itkSetMacro( Alpha, double );
+
+ itkGetConstMacro( Beta, double );
+ itkSetMacro( Beta, double );
+
+ public:
+ virtual TValue Evaluate( const TValue& v ) const override
+ {
+ double a = double( v );
+ double d = this->m_Alpha;
+ d += std::pow( double( a ), this->m_Beta );
+ double x = -1;
+ if( std::fabs( d ) > double( 0 ) )
+ x =
+ double( 1 ) /
+ ( this->m_Alpha + std::pow( double( a ), this->m_Beta ) );
+ return( TValue( x ) );
+ }
+
+ protected:
+ Invert( )
+ : Superclass( ),
+ m_Alpha( double( 1 ) ),
+ m_Beta( double( 1 ) )
+ {
+ }
+ virtual ~Invert( )
+ {
+ }
+
+ private:
+ // Purposely not implemented.
+ Invert( const Self& other );
+ Self& operator=( const Self& other );
+
+ protected:
+ double m_Alpha;
+ double m_Beta;
+ };
+
+ } // ecapseman
+
+ } // ecapseman
+
+} // ecapseman
+
+#endif // __fpa__Functors__Dijkstra__Invert__h__
+// eof - $RCSfile$
--- /dev/null
+// =========================================================================
+// @author Leonardo Florez Valencia
+// @email florez-l@javeriana.edu.co
+// =========================================================================
+#ifndef __fpa__Functors__RegionGrow__BinaryThreshold__h__
+#define __fpa__Functors__RegionGrow__BinaryThreshold__h__
+
+#include <itkFunctionBase.h>
+
+namespace fpa
+{
+ namespace Functors
+ {
+ namespace RegionGrow
+ {
+ /**
+ */
+ template< class _TValue >
+ class BinaryThreshold
+ : public itk::FunctionBase< _TValue, bool >
+ {
+ public:
+ typedef _TValue TValue;
+ typedef itk::FunctionBase< TValue, bool > Superclass;
+ typedef BinaryThreshold Self;
+ typedef itk::SmartPointer< Self > Pointer;
+ typedef itk::SmartPointer< const Self > ConstPointer;
+
+ public:
+ itkNewMacro( Self );
+ itkTypeMacro(
+ fpa::Functors::RegionGrow::BinaryThreshold, itk::FunctionBase
+ );
+
+ itkGetConstMacro( LowerThreshold, TValue );
+ itkSetMacro( LowerThreshold, TValue );
+
+ itkGetConstMacro( UpperThreshold, TValue );
+ itkSetMacro( UpperThreshold, TValue );
+
+ itkBooleanMacro( Strict );
+ itkGetConstMacro( Strict, bool );
+ itkSetMacro( Strict, bool );
+
+ public:
+ void ThresholdAbove( const TValue& a );
+ void ThresholdBetween( const TValue& a, const TValue& b );
+ void ThresholdBelow( const TValue& a );
+
+ virtual bool Evaluate( const TValue& v ) const override;
+
+ protected:
+ BinaryThreshold( );
+ virtual ~BinaryThreshold( );
+
+ private:
+ // Purposely not implemented.
+ BinaryThreshold( const Self& other );
+ Self& operator=( const Self& other );
+
+ protected:
+ TValue m_LowerThreshold;
+ TValue m_UpperThreshold;
+ bool m_Strict;
+ };
+
+ } // ecapseman
+
+ } // ecapseman
+
+} // ecapseman
+
+#ifndef ITK_MANUAL_INSTANTIATION
+# include <fpa/Functors/RegionGrow/BinaryThreshold.hxx>
+#endif // ITK_MANUAL_INSTANTIATION
+
+#endif // __fpa__Functors__RegionGrow__BinaryThreshold__h__
+// eof - $RCSfile$
--- /dev/null
+// =========================================================================
+// @author Leonardo Florez Valencia
+// @email florez-l@javeriana.edu.co
+// =========================================================================
+#ifndef __fpa__Functors__RegionGrow__BinaryThreshold__hxx__
+#define __fpa__Functors__RegionGrow__BinaryThreshold__hxx__
+
+#include <limits>
+
+// -------------------------------------------------------------------------
+template< class _TValue >
+void fpa::Functors::RegionGrow::BinaryThreshold< _TValue >::
+ThresholdAbove( const TValue& a )
+{
+ this->SetLowerThreshold( a );
+ this->SetUpperThreshold( std::numeric_limits< _TValue >::max( ) );
+}
+
+// -------------------------------------------------------------------------
+template< class _TValue >
+void fpa::Functors::RegionGrow::BinaryThreshold< _TValue >::
+ThresholdBetween( const TValue& a, const TValue& b )
+{
+ this->SetLowerThreshold( ( a < b )? a: b );
+ this->SetUpperThreshold( ( b < a )? a: b );
+}
+
+// -------------------------------------------------------------------------
+template< class _TValue >
+void fpa::Functors::RegionGrow::BinaryThreshold< _TValue >::
+ThresholdBelow( const TValue& a )
+{
+ if( std::numeric_limits< _TValue >::is_integer )
+ this->SetLowerThreshold( std::numeric_limits< _TValue >::min( ) );
+ else
+ this->SetLowerThreshold( -std::numeric_limits< _TValue >::max( ) );
+ this->SetUpperThreshold( a );
+}
+
+// -------------------------------------------------------------------------
+template< class _TValue >
+bool fpa::Functors::RegionGrow::BinaryThreshold< _TValue >::
+Evaluate( const TValue& v ) const
+{
+ if( this->m_Strict )
+ return( this->m_LowerThreshold < v && v < this->m_UpperThreshold );
+ else
+ return( this->m_LowerThreshold <= v && v <= this->m_UpperThreshold );
+}
+
+// -------------------------------------------------------------------------
+template< class _TValue >
+fpa::Functors::RegionGrow::BinaryThreshold< _TValue >::
+BinaryThreshold( )
+ : Superclass( ),
+ m_Strict( true )
+{
+ this->m_UpperThreshold = std::numeric_limits< _TValue >::max( );
+ if( std::numeric_limits< _TValue >::is_integer )
+ this->m_LowerThreshold = std::numeric_limits< _TValue >::min( );
+ else
+ this->m_LowerThreshold = -this->m_UpperThreshold;
+}
+
+// -------------------------------------------------------------------------
+template< class _TValue >
+fpa::Functors::RegionGrow::BinaryThreshold< _TValue >::
+~BinaryThreshold( )
+{
+}
+
+#endif // __fpa__Functors__RegionGrow__BinaryThreshold__hxx__
+// eof - $RCSfile$
--- /dev/null
+// =========================================================================
+// @author Leonardo Florez Valencia
+// @email florez-l@javeriana.edu.co
+// =========================================================================
+#ifndef __fpa__Functors__RegionGrow__Tautology__h__
+#define __fpa__Functors__RegionGrow__Tautology__h__
+
+#include <itkFunctionBase.h>
+
+namespace fpa
+{
+ namespace Functors
+ {
+ namespace RegionGrow
+ {
+ /**
+ */
+ template< class _TValue >
+ class Tautology
+ : public itk::FunctionBase< _TValue, bool >
+ {
+ public:
+ typedef _TValue TValue;
+ typedef itk::FunctionBase< TValue, bool > Superclass;
+ typedef Tautology Self;
+ typedef itk::SmartPointer< Self > Pointer;
+ typedef itk::SmartPointer< const Self > ConstPointer;
+
+ public:
+ itkNewMacro( Self );
+ itkTypeMacro(
+ fpa::Functors::RegionGrow::Tautology, itk::FunctionBase
+ );
+
+ public:
+ virtual bool Evaluate( const TValue& v ) const override
+ {
+ return( true );
+ }
+
+ protected:
+ Tautology( )
+ : Superclass( )
+ {
+ }
+ virtual ~Tautology( )
+ {
+ }
+
+ private:
+ // Purposely not implemented.
+ Tautology( const Self& other );
+ Self& operator=( const Self& other );
+ };
+
+ } // ecapseman
+
+ } // ecapseman
+
+} // ecapseman
+
+#endif // __fpa__Functors__RegionGrow__Tautology__h__
+// eof - $RCSfile$
--- /dev/null
+// =========================================================================
+// @author Leonardo Florez Valencia
+// @email florez-l@javeriana.edu.co
+// =========================================================================
+#ifndef __fpa__VTK__Image__PolyLineParametricPathToPolyDataFilter__h__
+#define __fpa__VTK__Image__PolyLineParametricPathToPolyDataFilter__h__
+
+#include <vtkPolyDataAlgorithm.h>
+
+namespace fpa
+{
+ namespace VTK
+ {
+ namespace Image
+ {
+ /**
+ */
+ template< class _TPath >
+ class PolyLineParametricPathToPolyDataFilter
+ : public vtkPolyDataAlgorithm
+ {
+ public:
+ typedef PolyLineParametricPathToPolyDataFilter Self;
+ typedef _TPath TPath;
+
+ public:
+ vtkTypeMacro(
+ PolyLineParametricPathToPolyDataFilter,
+ vtkPolyDataAlgorithm
+ );
+
+ public:
+ static Self* New( );
+
+ const TPath* GetInput( ) const;
+ void SetInput( const TPath* path );
+
+ protected:
+ PolyLineParametricPathToPolyDataFilter( );
+ virtual ~PolyLineParametricPathToPolyDataFilter( );
+
+ int RequestData(
+ vtkInformation* information,
+ vtkInformationVector** input,
+ vtkInformationVector* output
+ );
+ int RequestInformation(
+ vtkInformation* information,
+ vtkInformationVector** input,
+ vtkInformationVector* output
+ );
+
+ private:
+ // Purposely not implemented
+ PolyLineParametricPathToPolyDataFilter( const Self& );
+ void operator=( const Self& );
+
+ protected:
+ const TPath* m_PolyLineParametricPath;
+ };
+
+ } // ecapseman
+
+ } // ecapseman
+
+} // ecapseman
+
+#ifndef ITK_MANUAL_INSTANTIATION
+# include <fpa/VTK/Image/PolyLineParametricPathToPolyDataFilter.hxx>
+#endif // ITK_MANUAL_INSTANTIATION
+#endif // __fpa__VTK__Image__PolyLineParametricPathToPolyDataFilter__h__
+
+// eof - $RCSfile$
--- /dev/null
+// =========================================================================
+// @author Leonardo Florez Valencia
+// @email florez-l@javeriana.edu.co
+// =========================================================================
+#ifndef __fpa__VTK__Image__PolyLineParametricPathToPolyDataFilter__hxx__
+#define __fpa__VTK__Image__PolyLineParametricPathToPolyDataFilter__hxx__
+
+#include <vtkCellArray.h>
+#include <vtkInformation.h>
+#include <vtkInformationVector.h>
+#include <vtkPointData.h>
+#include <vtkUnsignedIntArray.h>
+#include <vtkSmartPointer.h>
+
+// -------------------------------------------------------------------------
+template< class _TPath >
+typename fpa::VTK::Image::PolyLineParametricPathToPolyDataFilter< _TPath >::
+Self* fpa::VTK::Image::PolyLineParametricPathToPolyDataFilter< _TPath >::
+New( )
+{
+ return( new Self( ) );
+}
+
+// -------------------------------------------------------------------------
+template< class _TPath >
+const typename
+fpa::VTK::Image::PolyLineParametricPathToPolyDataFilter< _TPath >::
+TPath* fpa::VTK::Image::PolyLineParametricPathToPolyDataFilter< _TPath >::
+GetInput( ) const
+{
+ return( this->m_PolyLineParametricPath );
+}
+
+// -------------------------------------------------------------------------
+template< class _TPath >
+void fpa::VTK::Image::PolyLineParametricPathToPolyDataFilter< _TPath >::
+SetInput( const TPath* path )
+{
+ if( this->m_PolyLineParametricPath != path )
+ {
+ this->m_PolyLineParametricPath = path;
+ this->Modified( );
+
+ } // fi
+}
+
+// -------------------------------------------------------------------------
+template< class _TPath >
+fpa::VTK::Image::PolyLineParametricPathToPolyDataFilter< _TPath >::
+PolyLineParametricPathToPolyDataFilter( )
+ : vtkPolyDataAlgorithm( ),
+ m_PolyLineParametricPath( NULL )
+{
+ this->SetNumberOfInputPorts( 0 );
+}
+
+// -------------------------------------------------------------------------
+template< class _TPath >
+fpa::VTK::Image::PolyLineParametricPathToPolyDataFilter< _TPath >::
+~PolyLineParametricPathToPolyDataFilter( )
+{
+}
+
+// -------------------------------------------------------------------------
+template< class _TPath >
+int fpa::VTK::Image::PolyLineParametricPathToPolyDataFilter< _TPath >::
+RequestData(
+ vtkInformation* information,
+ vtkInformationVector** input,
+ vtkInformationVector* output
+ )
+{
+ static const unsigned int dim = TPath::PathDimension;
+ if( this->m_PolyLineParametricPath == NULL )
+ return( 0 );
+
+ // Get output
+ vtkInformation* info = output->GetInformationObject( 0 );
+ vtkPolyData* out = vtkPolyData::SafeDownCast(
+ info->Get( vtkDataObject::DATA_OBJECT( ) )
+ );
+
+ // Prepare data
+ out->SetPoints( vtkSmartPointer< vtkPoints >::New( ) );
+ out->SetVerts( vtkSmartPointer< vtkCellArray >::New( ) );
+ out->SetLines( vtkSmartPointer< vtkCellArray >::New( ) );
+ out->SetPolys( vtkSmartPointer< vtkCellArray >::New( ) );
+ out->SetStrips( vtkSmartPointer< vtkCellArray >::New( ) );
+ vtkSmartPointer< vtkUnsignedIntArray > darray =
+ vtkSmartPointer< vtkUnsignedIntArray >::New( );
+ darray->SetNumberOfComponents( 1 );
+ out->GetPointData( )->SetScalars( darray );
+ vtkPoints* points = out->GetPoints( );
+ vtkCellArray* lines = out->GetLines( );
+
+ // Assign all data
+ const TPath* path = this->GetInput( );
+ for( unsigned long i = 0; i < path->GetSize( ); ++i )
+ {
+ auto pnt = path->GetPoint( i );
+ if( dim == 1 )
+ points->InsertNextPoint( pnt[ 0 ], 0, 0 );
+ else if( dim == 2 )
+ points->InsertNextPoint( pnt[ 0 ], pnt[ 1 ], 0 );
+ else
+ points->InsertNextPoint( pnt[ 0 ], pnt[ 1 ], pnt[ 2 ] );
+ darray->InsertNextTuple1( double( i ) );
+ if( i > 0 )
+ {
+ lines->InsertNextCell( 2 );
+ lines->InsertCellPoint( points->GetNumberOfPoints( ) - 2 );
+ lines->InsertCellPoint( points->GetNumberOfPoints( ) - 1 );
+
+ } // fi
+
+ } // rof
+ return( 1 );
+}
+
+// -------------------------------------------------------------------------
+template< class _TPath >
+int fpa::VTK::Image::PolyLineParametricPathToPolyDataFilter< _TPath >::
+RequestInformation(
+ vtkInformation* information,
+ vtkInformationVector** input,
+ vtkInformationVector* output
+ )
+{
+ return( 1 );
+}
+
+#endif // __fpa__VTK__Image__PolyLineParametricPathToPolyDataFilterFilter__hxx__
+// eof - $RCSfile$
--- /dev/null
+// =========================================================================
+// @author Leonardo Florez Valencia
+// @email florez-l@javeriana.edu.co
+// =========================================================================
+#ifndef __fpa__VTK__Image__SkeletonToPolyDataFilter__h__
+#define __fpa__VTK__Image__SkeletonToPolyDataFilter__h__
+
+#include <vtkPolyDataAlgorithm.h>
+
+namespace fpa
+{
+ namespace VTK
+ {
+ namespace Image
+ {
+ /**
+ */
+ template< class _TSkeleton >
+ class SkeletonToPolyDataFilter
+ : public vtkPolyDataAlgorithm
+ {
+ public:
+ typedef SkeletonToPolyDataFilter Self;
+ typedef _TSkeleton TSkeleton;
+
+ public:
+ vtkTypeMacro( SkeletonToPolyDataFilter, vtkPolyDataAlgorithm );
+
+ public:
+ static Self* New( );
+
+ const TSkeleton* GetInput( ) const;
+ void SetInput( const TSkeleton* sk );
+
+ protected:
+ SkeletonToPolyDataFilter( );
+ virtual ~SkeletonToPolyDataFilter( );
+
+ int RequestData(
+ vtkInformation* information,
+ vtkInformationVector** input,
+ vtkInformationVector* output
+ );
+ int RequestInformation(
+ vtkInformation* information,
+ vtkInformationVector** input,
+ vtkInformationVector* output
+ );
+
+ private:
+ // Purposely not implemented
+ SkeletonToPolyDataFilter( const Self& );
+ void operator=( const Self& );
+
+ protected:
+ const TSkeleton* m_Skeleton;
+ };
+
+ } // ecapseman
+
+ } // ecapseman
+
+} // ecapseman
+
+#ifndef ITK_MANUAL_INSTANTIATION
+# include <fpa/VTK/Image/SkeletonToPolyDataFilter.hxx>
+#endif // ITK_MANUAL_INSTANTIATION
+
+#endif // __fpa__VTK__Image__SkeletonToPolyDataFilter__h__
+
+// eof - $RCSfile$
--- /dev/null
+// =========================================================================
+// @author Leonardo Florez Valencia
+// @email florez-l@javeriana.edu.co
+// =========================================================================
+#ifndef __fpa__VTK__Image__SkeletonToPolyDataFilter__hxx__
+#define __fpa__VTK__Image__SkeletonToPolyDataFilter__hxx__
+
+#include <vtkCellArray.h>
+#include <vtkInformation.h>
+#include <vtkInformationVector.h>
+#include <vtkPointData.h>
+#include <vtkUnsignedIntArray.h>
+#include <vtkSmartPointer.h>
+
+// -------------------------------------------------------------------------
+template< class _TSkeleton >
+typename fpa::VTK::Image::SkeletonToPolyDataFilter< _TSkeleton >::
+Self* fpa::VTK::Image::SkeletonToPolyDataFilter< _TSkeleton >::
+New( )
+{
+ return( new Self( ) );
+}
+
+// -------------------------------------------------------------------------
+template< class _TSkeleton >
+const typename
+fpa::VTK::Image::SkeletonToPolyDataFilter< _TSkeleton >::
+TSkeleton* fpa::VTK::Image::SkeletonToPolyDataFilter< _TSkeleton >::
+GetInput( ) const
+{
+ return( this->m_Skeleton );
+}
+
+// -------------------------------------------------------------------------
+template< class _TSkeleton >
+void fpa::VTK::Image::SkeletonToPolyDataFilter< _TSkeleton >::
+SetInput( const TSkeleton* sk )
+{
+ if( this->m_Skeleton != sk )
+ {
+ this->m_Skeleton = sk;
+ this->Modified( );
+
+ } // fi
+}
+
+// -------------------------------------------------------------------------
+template< class _TSkeleton >
+fpa::VTK::Image::SkeletonToPolyDataFilter< _TSkeleton >::
+SkeletonToPolyDataFilter( )
+ : vtkPolyDataAlgorithm( ),
+ m_Skeleton( NULL )
+{
+ this->SetNumberOfInputPorts( 0 );
+}
+
+// -------------------------------------------------------------------------
+template< class _TSkeleton >
+fpa::VTK::Image::SkeletonToPolyDataFilter< _TSkeleton >::
+~SkeletonToPolyDataFilter( )
+{
+}
+
+// -------------------------------------------------------------------------
+template< class _TSkeleton >
+int fpa::VTK::Image::SkeletonToPolyDataFilter< _TSkeleton >::
+RequestData(
+ vtkInformation* information,
+ vtkInformationVector** input,
+ vtkInformationVector* output
+ )
+{
+ typedef typename _TSkeleton::TPath _TPath;
+ static const unsigned int dim = _TPath::PathDimension;
+
+ if( this->m_Skeleton == NULL )
+ return( 0 );
+
+ // Get output
+ vtkInformation* info = output->GetInformationObject( 0 );
+ vtkPolyData* out = vtkPolyData::SafeDownCast(
+ info->Get( vtkDataObject::DATA_OBJECT( ) )
+ );
+
+ // Prepare data
+ out->SetPoints( vtkSmartPointer< vtkPoints >::New( ) );
+ out->SetVerts( vtkSmartPointer< vtkCellArray >::New( ) );
+ out->SetLines( vtkSmartPointer< vtkCellArray >::New( ) );
+ out->SetPolys( vtkSmartPointer< vtkCellArray >::New( ) );
+ out->SetStrips( vtkSmartPointer< vtkCellArray >::New( ) );
+ vtkSmartPointer< vtkUnsignedIntArray > darray =
+ vtkSmartPointer< vtkUnsignedIntArray >::New( );
+ darray->SetNumberOfComponents( 1 );
+ out->GetPointData( )->SetScalars( darray );
+ vtkPoints* points = out->GetPoints( );
+ vtkCellArray* lines = out->GetLines( );
+
+ // Assign all data
+ unsigned int dcount = 0;
+ typename TSkeleton::TMatrix::const_iterator mIt = this->m_Skeleton->BeginEdgesRows( );
+ for( ; mIt != this->m_Skeleton->EndEdgesRows( ); ++mIt )
+ {
+ // TODO: mIt->first; --> this is the row index. <--
+ typename TSkeleton::TMatrixRow::const_iterator rIt = mIt->second.begin( );
+ for( ; rIt != mIt->second.end( ); ++rIt )
+ {
+ // TODO: rIt->first; --> this is the column index.
+ typename TSkeleton::TEdges::const_iterator eIt = rIt->second.begin( );
+ for( ; eIt != rIt->second.end( ); ++eIt )
+ {
+ _TPath* path = *eIt;
+ for( unsigned long i = 0; i < path->GetSize( ); ++i )
+ {
+ auto pnt = path->GetPoint( i );
+ if( dim == 1 )
+ points->InsertNextPoint( pnt[ 0 ], 0, 0 );
+ else if( dim == 2 )
+ points->InsertNextPoint( pnt[ 0 ], pnt[ 1 ], 0 );
+ else
+ points->InsertNextPoint( pnt[ 0 ], pnt[ 1 ], pnt[ 2 ] );
+ darray->InsertNextTuple1( double( dcount ) );
+ if( i > 0 )
+ {
+ lines->InsertNextCell( 2 );
+ lines->InsertCellPoint( points->GetNumberOfPoints( ) - 2 );
+ lines->InsertCellPoint( points->GetNumberOfPoints( ) - 1 );
+
+ } // fi
+
+ } // rof
+ dcount++;
+
+ } // rof
+
+ } // rof
+
+ } // rof
+ return( 1 );
+}
+
+// -------------------------------------------------------------------------
+template< class _TSkeleton >
+int fpa::VTK::Image::SkeletonToPolyDataFilter< _TSkeleton >::
+RequestInformation(
+ vtkInformation* information,
+ vtkInformationVector** input,
+ vtkInformationVector* output
+ )
+{
+ return( 1 );
+}
+
+#endif // __fpa__VTK__Image__SkeletonToPolyDataFilterFilter__hxx__
+// eof - $RCSfile$
--- /dev/null
+// =========================================================================
+// @author Leonardo Florez Valencia
+// @email florez-l@javeriana.edu.co
+// =========================================================================
+
+#include <fpa/fpa_export.h>
+#include <string>
+
+std::string FPA_EXPORT version( ) { return( "@prj_VER@" ); }
+
+// eof - $RCSfile$
--- /dev/null
+## =========================================================================
+## @author Leonardo Florez Valencia
+## @email florez-l@javeriana.edu.co
+## =========================================================================
+
+subdirs(image)
+
+## eof - $RCSfile$
--- /dev/null
+## =========================================================================
+## @author Leonardo Florez Valencia
+## @email florez-l@javeriana.edu.co
+## =========================================================================
+
+subdirs(Dijkstra RandomWalker RegionGrow VTK)
+
+## eof - $RCSfile$
--- /dev/null
+## =========================================================================
+## @author Leonardo Florez Valencia
+## @email florez-l@javeriana.edu.co
+## =========================================================================
+
+set(_pfx test_fpa_Image_Dijkstra_)
+set(
+ _tests
+ Identity
+ Invert
+ Gaussian
+ ExtractAxis
+ Skeleton
+ )
+include_directories(${PROJECT_SOURCE_DIR}/lib ${PROJECT_BINARY_DIR}/lib)
+
+foreach(_t ${_tests})
+ add_executable(${_pfx}${_t} ${_t}.cxx)
+ target_link_libraries(${_pfx}${_t} fpa)
+endforeach(_t)
+
+## eof - $RCSfile$
--- /dev/null
+// =========================================================================
+// @author Leonardo Florez Valencia
+// @email florez-l@javeriana.edu.co
+// =========================================================================
+
+#include <itkImage.h>
+#include <itkImageFileReader.h>
+#include <fpa/Common/Image/PolyLineParametricPathWriter.h>
+#include <fpa/Filters/Image/ExtractAxis.h>
+
+// -------------------------------------------------------------------------
+const unsigned int Dim = 2;
+typedef unsigned char TPixel;
+typedef float TScalar;
+typedef itk::Image< TPixel, Dim > TImage;
+
+// -------------------------------------------------------------------------
+int main( int argc, char* argv[] )
+{
+ // Get arguments
+ if( argc < 3 )
+ {
+ std::cerr
+ << "Usage: " << argv[ 0 ]
+ << " input_image output_axis [seeds]"
+ << std::endl;
+ return( 1 );
+
+ } // fi
+ std::string input_image_filename = argv[ 1 ];
+ std::string output_path_filename = argv[ 2 ];
+
+ // Read image
+ typedef itk::ImageFileReader< TImage > TImageReader;
+ TImageReader::Pointer input_image_reader = TImageReader::New( );
+ input_image_reader->SetFileName( input_image_filename );
+
+ // Prepare filter
+ typedef fpa::Filters::Image::ExtractAxis< TImage, TScalar > TFilter;
+ TFilter::Pointer filter = TFilter::New( );
+ filter->SetInput( input_image_reader->GetOutput( ) );
+
+ // Get all seeds
+ for( int i = 3; i < argc; i += Dim )
+ {
+ TImage::IndexType seed;
+ for( int j = 0; j < Dim; ++j )
+ if( i + j < argc )
+ seed[ j ] = std::atoi( argv[ i + j ] );
+ filter->AddSeed( seed );
+ if( i == 3 )
+ filter->SetStartIndex( seed );
+ else if( i == 4 )
+ filter->SetEndIndex( seed );
+
+ } // rof
+
+ // Execute filter
+ filter->Update( );
+
+ // Save results
+ typedef fpa::Common::Image::PolyLineParametricPathWriter< TFilter::TPath > TPathWriter;
+ TPathWriter::Pointer path_writer = TPathWriter::New( );
+ path_writer->SetInput( filter->GetOutput( ) );
+ path_writer->SetFileName( output_path_filename );
+
+ try
+ {
+ path_writer->Update( );
+ }
+ catch( std::exception& err )
+ {
+ std::cerr << "Error caught: " << err.what( ) << std::endl;
+ return( 1 );
+
+ } // yrt
+ return( 0 );
+}
+
+// eof - $RCSfile$
--- /dev/null
+// =========================================================================
+// @author Leonardo Florez Valencia
+// @email florez-l@javeriana.edu.co
+// =========================================================================
+
+#include <itkImage.h>
+#include <itkImageFileReader.h>
+#include <itkImageFileWriter.h>
+#include <fpa/Filters/Image/Dijkstra.h>
+#include <fpa/Functors/Dijkstra/Image/Gaussian.h>
+
+// -------------------------------------------------------------------------
+const unsigned int Dim = 2;
+typedef unsigned char TInputPixel;
+typedef float TOutputPixel;
+typedef itk::Image< TInputPixel, Dim > TInputImage;
+typedef itk::Image< TOutputPixel, Dim > TOutputImage;
+
+// -------------------------------------------------------------------------
+int main( int argc, char* argv[] )
+{
+ // Get arguments
+ if( argc < 7 )
+ {
+ std::cerr
+ << "Usage: " << argv[ 0 ]
+ << " input_image output_image output_marks output_mst alpha beta [seeds]"
+ << std::endl;
+ return( 1 );
+
+ } // fi
+ std::string input_image_filename = argv[ 1 ];
+ std::string output_image_filename = argv[ 2 ];
+ std::string output_marks_filename = argv[ 3 ];
+ std::string output_mst_filename = argv[ 4 ];
+ double alpha = std::atof( argv[ 5 ] );
+ double beta = std::atof( argv[ 6 ] );
+
+ // Read image
+ typedef itk::ImageFileReader< TInputImage > TInputImageReader;
+ TInputImageReader::Pointer input_image_reader = TInputImageReader::New( );
+ input_image_reader->SetFileName( input_image_filename );
+
+ // Prepare weight functor
+ typedef fpa::Functors::Dijkstra::Image::Gaussian< TInputImage, TOutputPixel > TWeight;
+ TWeight::Pointer weight = TWeight::New( );
+ weight->SetAlpha( alpha );
+ weight->SetBeta( beta );
+
+ // Prepare filter
+ typedef fpa::Filters::Image::Dijkstra< TInputImage, TOutputImage > TFilter;
+ TFilter::Pointer filter = TFilter::New( );
+ filter->SetInput( input_image_reader->GetOutput( ) );
+ filter->SetWeightFunction( weight );
+
+ // Get all seeds
+ for( int i = 7; i < argc; i += Dim )
+ {
+ TInputImage::IndexType seed;
+ for( int j = 0; j < Dim; ++j )
+ if( i + j < argc )
+ seed[ j ] = std::atoi( argv[ i + j ] );
+ filter->AddSeed( seed );
+
+ } // rof
+
+ // Execute filter
+ filter->Update( );
+
+ // Save results
+ typedef itk::ImageFileWriter< TFilter::TOutputImage > TOutputWriter;
+ TOutputWriter::Pointer output_writer = TOutputWriter::New( );
+ output_writer->SetInput( filter->GetOutput( ) );
+ output_writer->SetFileName( output_image_filename );
+
+ typedef itk::ImageFileWriter< TFilter::TMarksImage > TMarksWriter;
+ TMarksWriter::Pointer marks_writer = TMarksWriter::New( );
+ marks_writer->SetInput( filter->GetMarks( ) );
+ marks_writer->SetFileName( output_marks_filename );
+
+ typedef itk::ImageFileWriter< TFilter::TMST > TMSTWriter;
+ TMSTWriter::Pointer mst_writer = TMSTWriter::New( );
+ mst_writer->SetInput( filter->GetMinimumSpanningTree( ) );
+ mst_writer->SetFileName( output_mst_filename );
+
+ try
+ {
+ output_writer->Update( );
+ marks_writer->Update( );
+ mst_writer->Update( );
+ }
+ catch( std::exception& err )
+ {
+ std::cerr << "Error caught: " << err.what( ) << std::endl;
+ return( 1 );
+
+ } // yrt
+
+ return( 0 );
+}
+
+// eof - $RCSfile$
--- /dev/null
+// =========================================================================
+// @author Leonardo Florez Valencia
+// @email florez-l@javeriana.edu.co
+// =========================================================================
+
+#include <itkImage.h>
+#include <itkImageFileWriter.h>
+#include <fpa/Filters/Image/Dijkstra.h>
+
+// -------------------------------------------------------------------------
+const unsigned int Dim = 2;
+typedef unsigned char TInputPixel;
+typedef float TOutputPixel;
+typedef itk::Image< TInputPixel, Dim > TInputImage;
+typedef itk::Image< TOutputPixel, Dim > TOutputImage;
+
+// -------------------------------------------------------------------------
+int main( int argc, char* argv[] )
+{
+ // Get arguments
+ if( argc < 5 )
+ {
+ std::cerr
+ << "Usage: " << argv[ 0 ]
+ << " output_image output_marks output_mst size [seeds]"
+ << std::endl;
+ return( 1 );
+
+ } // fi
+ std::string output_image_filename = argv[ 1 ];
+ std::string output_marks_filename = argv[ 2 ];
+ std::string output_mst_filename = argv[ 3 ];
+ TInputImage::SizeType size;
+ size.Fill( std::atoi( argv[ 4 ] ) );
+
+ // Create image
+ TInputImage::Pointer image = TInputImage::New( );
+ image->SetRegions( size );
+ image->Allocate( );
+ image->FillBuffer( TInputPixel( 1 ) );
+
+ // Prepare filter
+ typedef fpa::Filters::Image::Dijkstra< TInputImage, TOutputImage > TFilter;
+ TFilter::Pointer filter = TFilter::New( );
+ filter->SetInput( image );
+
+ // Get all seeds
+ for( int i = 5; i < argc; i += Dim )
+ {
+ TInputImage::IndexType seed;
+ for( int j = 0; j < Dim; ++j )
+ if( i + j < argc )
+ seed[ j ] = std::atoi( argv[ i + j ] );
+ filter->AddSeed( seed );
+
+ } // rof
+
+ // Execute filter
+ filter->Update( );
+
+ // Save results
+ typedef itk::ImageFileWriter< TFilter::TOutputImage > TOutputWriter;
+ TOutputWriter::Pointer output_writer = TOutputWriter::New( );
+ output_writer->SetInput( filter->GetOutput( ) );
+ output_writer->SetFileName( output_image_filename );
+
+ typedef itk::ImageFileWriter< TFilter::TMarksImage > TMarksWriter;
+ TMarksWriter::Pointer marks_writer = TMarksWriter::New( );
+ marks_writer->SetInput( filter->GetMarks( ) );
+ marks_writer->SetFileName( output_marks_filename );
+
+ typedef itk::ImageFileWriter< TFilter::TMST > TMSTWriter;
+ TMSTWriter::Pointer mst_writer = TMSTWriter::New( );
+ mst_writer->SetInput( filter->GetMinimumSpanningTree( ) );
+ mst_writer->SetFileName( output_mst_filename );
+
+ try
+ {
+ output_writer->Update( );
+ marks_writer->Update( );
+ mst_writer->Update( );
+ }
+ catch( std::exception& err )
+ {
+ std::cerr << "Error caught: " << err.what( ) << std::endl;
+ return( 1 );
+
+ } // yrt
+
+ return( 0 );
+}
+
+// eof - $RCSfile$
--- /dev/null
+// =========================================================================
+// @author Leonardo Florez Valencia
+// @email florez-l@javeriana.edu.co
+// =========================================================================
+
+#include <itkImage.h>
+#include <itkImageFileReader.h>
+#include <itkImageFileWriter.h>
+#include <fpa/Filters/Image/Dijkstra.h>
+#include <fpa/Functors/Dijkstra/Invert.h>
+
+// -------------------------------------------------------------------------
+const unsigned int Dim = 2;
+typedef unsigned char TInputPixel;
+typedef float TOutputPixel;
+typedef itk::Image< TInputPixel, Dim > TInputImage;
+typedef itk::Image< TOutputPixel, Dim > TOutputImage;
+
+// -------------------------------------------------------------------------
+int main( int argc, char* argv[] )
+{
+ // Get arguments
+ if( argc < 7 )
+ {
+ std::cerr
+ << "Usage: " << argv[ 0 ]
+ << " input_image output_image output_marks output_mst alpha beta [seeds]"
+ << std::endl;
+ return( 1 );
+
+ } // fi
+ std::string input_image_filename = argv[ 1 ];
+ std::string output_image_filename = argv[ 2 ];
+ std::string output_marks_filename = argv[ 3 ];
+ std::string output_mst_filename = argv[ 4 ];
+ double alpha = std::atof( argv[ 5 ] );
+ double beta = std::atof( argv[ 6 ] );
+
+ // Read image
+ typedef itk::ImageFileReader< TInputImage > TInputImageReader;
+ TInputImageReader::Pointer input_image_reader = TInputImageReader::New( );
+ input_image_reader->SetFileName( input_image_filename );
+
+ // Prepare weight functor
+ typedef fpa::Functors::Dijkstra::Invert< TOutputPixel > TWeight;
+ TWeight::Pointer weight = TWeight::New( );
+ weight->SetAlpha( alpha );
+ weight->SetBeta( beta );
+
+ // Prepare filter
+ typedef fpa::Filters::Image::Dijkstra< TInputImage, TOutputImage > TFilter;
+ TFilter::Pointer filter = TFilter::New( );
+ filter->SetInput( input_image_reader->GetOutput( ) );
+ filter->SetWeightFunction( weight );
+
+ // Get all seeds
+ for( int i = 7; i < argc; i += Dim )
+ {
+ TInputImage::IndexType seed;
+ for( int j = 0; j < Dim; ++j )
+ if( i + j < argc )
+ seed[ j ] = std::atoi( argv[ i + j ] );
+ filter->AddSeed( seed );
+
+ } // rof
+
+ // Execute filter
+ filter->Update( );
+
+ // Save results
+ typedef itk::ImageFileWriter< TFilter::TOutputImage > TOutputWriter;
+ TOutputWriter::Pointer output_writer = TOutputWriter::New( );
+ output_writer->SetInput( filter->GetOutput( ) );
+ output_writer->SetFileName( output_image_filename );
+
+ typedef itk::ImageFileWriter< TFilter::TMarksImage > TMarksWriter;
+ TMarksWriter::Pointer marks_writer = TMarksWriter::New( );
+ marks_writer->SetInput( filter->GetMarks( ) );
+ marks_writer->SetFileName( output_marks_filename );
+
+ typedef itk::ImageFileWriter< TFilter::TMST > TMSTWriter;
+ TMSTWriter::Pointer mst_writer = TMSTWriter::New( );
+ mst_writer->SetInput( filter->GetMinimumSpanningTree( ) );
+ mst_writer->SetFileName( output_mst_filename );
+
+ try
+ {
+ output_writer->Update( );
+ marks_writer->Update( );
+ mst_writer->Update( );
+ }
+ catch( std::exception& err )
+ {
+ std::cerr << "Error caught: " << err.what( ) << std::endl;
+ return( 1 );
+
+ } // yrt
+
+ return( 0 );
+}
+
+// eof - $RCSfile$
--- /dev/null
+// =========================================================================
+// @author Leonardo Florez Valencia
+// @email florez-l@javeriana.edu.co
+// =========================================================================
+
+#include <itkImage.h>
+#include <itkImageFileReader.h>
+#include <fpa/Common/Image/SkeletonWriter.h>
+#include <fpa/Filters/Image/Skeleton.h>
+
+// -------------------------------------------------------------------------
+const unsigned int Dim = 2;
+typedef unsigned char TPixel;
+typedef itk::Image< TPixel, Dim > TImage;
+
+// -------------------------------------------------------------------------
+int main( int argc, char* argv[] )
+{
+ // Get arguments
+ if( argc < 3 )
+ {
+ std::cerr
+ << "Usage: " << argv[ 0 ]
+ << " input_image output_skeleton [seed]"
+ << std::endl;
+ return( 1 );
+
+ } // fi
+ std::string input_image_filename = argv[ 1 ];
+ std::string output_skeleton_filename = argv[ 2 ];
+
+ // Read image
+ typedef itk::ImageFileReader< TImage > TImageReader;
+ TImageReader::Pointer input_image_reader = TImageReader::New( );
+ input_image_reader->SetFileName( input_image_filename );
+
+ // Prepare filter
+ typedef fpa::Filters::Image::Skeleton< TImage > TFilter;
+ TFilter::Pointer filter = TFilter::New( );
+ filter->SetInput( input_image_reader->GetOutput( ) );
+
+ // Get seed
+ if( argc >= Dim + 3 )
+ {
+ TImage::IndexType seed;
+ for( int j = 0; j < Dim; ++j )
+ if( 3 + j < argc )
+ seed[ j ] = std::atoi( argv[ 3 + j ] );
+ filter->SeedFromMaximumDistanceOff( );
+ filter->SetSeed( seed );
+ }
+ else
+ filter->SeedFromMaximumDistanceOn( );
+
+ // Configure distance map
+ filter->GetDistanceMap( )->InsideIsPositiveOn( );
+ filter->GetDistanceMap( )->SquaredDistanceOff( );
+ filter->GetDistanceMap( )->UseImageSpacingOn( );
+
+ // Execute filter
+ filter->Update( );
+
+ // Save results
+ typedef fpa::Common::Image::SkeletonWriter< TFilter::TSkeleton > TSkeletonWriter;
+ TSkeletonWriter::Pointer skeleton_writer = TSkeletonWriter::New( );
+ skeleton_writer->SetInput( filter->GetOutput( ) );
+ skeleton_writer->SetFileName( output_skeleton_filename );
+
+ try
+ {
+ skeleton_writer->Update( );
+ }
+ catch( std::exception& err )
+ {
+ std::cerr << "Error caught: " << err.what( ) << std::endl;
+ return( 1 );
+
+ } // yrt
+ return( 0 );
+}
+
+// eof - $RCSfile$
--- /dev/null
+## =========================================================================
+## @author Leonardo Florez Valencia
+## @email florez-l@javeriana.edu.co
+## =========================================================================
+
+set(_pfx test_fpa_Image_RandomWalker_)
+set(
+ _tests
+ Gaussian
+ )
+include_directories(${PROJECT_SOURCE_DIR}/lib ${PROJECT_BINARY_DIR}/lib)
+
+foreach(_t ${_tests})
+ add_executable(${_pfx}${_t} ${_t}.cxx)
+ target_link_libraries(${_pfx}${_t} fpa)
+endforeach(_t)
+
+## eof - $RCSfile$
--- /dev/null
+// =========================================================================
+// @author Leonardo Florez Valencia
+// @email florez-l@javeriana.edu.co
+// =========================================================================
+
+#include <itkImage.h>
+#include <itkImageFileReader.h>
+#include <itkImageFileWriter.h>
+#include <fpa/Filters/Image/RandomWalker.h>
+#include <fpa/Functors/Dijkstra/Image/Gaussian.h>
+
+// -------------------------------------------------------------------------
+const unsigned int Dim = 2;
+typedef unsigned char TInputPixel;
+typedef unsigned char TInputLabel;
+typedef float TOutputPixel;
+typedef itk::Image< TInputPixel, Dim > TInputImage;
+typedef itk::Image< TInputLabel, Dim > TInputLabelImage;
+typedef itk::Image< TOutputPixel, Dim > TOutputImage;
+
+// -------------------------------------------------------------------------
+int main( int argc, char* argv[] )
+{
+ // Get arguments
+ if( argc < 7 )
+ {
+ std::cerr
+ << "Usage: " << argv[ 0 ]
+ << " input_image input_labels output_image output_costs alpha beta"
+ << std::endl;
+ return( 1 );
+
+ } // fi
+ std::string input_image_filename = argv[ 1 ];
+ std::string input_labels_filename = argv[ 2 ];
+ std::string output_image_filename = argv[ 3 ];
+ std::string output_costs_filename = argv[ 4 ];
+ double alpha = std::atof( argv[ 5 ] );
+ double beta = std::atof( argv[ 6 ] );
+
+ // Read image
+ typedef itk::ImageFileReader< TInputImage > TInputImageReader;
+ TInputImageReader::Pointer input_image_reader = TInputImageReader::New( );
+ input_image_reader->SetFileName( input_image_filename );
+
+ // Read labels
+ typedef itk::ImageFileReader< TInputLabelImage > TInputLabelImageReader;
+ TInputLabelImageReader::Pointer input_labels_reader =
+ TInputLabelImageReader::New( );
+ input_labels_reader->SetFileName( input_labels_filename );
+
+ // Prepare weight functor
+ typedef fpa::Functors::Dijkstra::Image::Gaussian< TInputImage, TOutputPixel > TWeight;
+ TWeight::Pointer weight = TWeight::New( );
+ weight->SetAlpha( alpha );
+ weight->SetBeta( beta );
+
+ // Prepare filter
+ typedef fpa::Filters::Image::RandomWalker< TInputImage, TInputLabelImage, TOutputImage > TFilter;
+ TFilter::Pointer filter = TFilter::New( );
+ filter->SetInputImage( input_image_reader->GetOutput( ) );
+ filter->SetInputLabels( input_labels_reader->GetOutput( ) );
+ filter->SetWeightFunction( weight );
+
+ // Execute filter
+ filter->Update( );
+
+ // Save results
+ typedef itk::ImageFileWriter< TFilter::TOutputLabels > TOutputWriter;
+ TOutputWriter::Pointer output_writer = TOutputWriter::New( );
+ output_writer->SetInput( filter->GetOutputLabels( ) );
+ output_writer->SetFileName( output_image_filename );
+
+ typedef itk::ImageFileWriter< TFilter::TCostsImage > TCostsWriter;
+ TCostsWriter::Pointer costs_writer = TCostsWriter::New( );
+ costs_writer->SetInput( filter->GetOutputCosts( ) );
+ costs_writer->SetFileName( output_costs_filename );
+
+ try
+ {
+ output_writer->Update( );
+ costs_writer->Update( );
+ }
+ catch( std::exception& err )
+ {
+ std::cerr << "Error caught: " << err.what( ) << std::endl;
+ return( 1 );
+
+ } // yrt
+
+ return( 0 );
+}
+
+// eof - $RCSfile$
--- /dev/null
+// =========================================================================
+// @author Leonardo Florez Valencia
+// @email florez-l@javeriana.edu.co
+// =========================================================================
+
+#include <itkImage.h>
+#include <itkImageFileReader.h>
+#include <itkImageFileWriter.h>
+#include <fpa/Filters/Image/RegionGrow.h>
+#include <fpa/Functors/RegionGrow/BinaryThreshold.h>
+
+// -------------------------------------------------------------------------
+const unsigned int Dim = 2;
+typedef unsigned char TPixel;
+typedef itk::Image< TPixel, Dim > TImage;
+
+// -------------------------------------------------------------------------
+int main( int argc, char* argv[] )
+{
+ // Get arguments
+ if( argc < 6 )
+ {
+ std::cerr
+ << "Usage: " << argv[ 0 ]
+ << " input_image output_image output_marks lower upper [seeds]"
+ << std::endl;
+ return( 1 );
+
+ } // fi
+ std::string input_image_filename = argv[ 1 ];
+ std::string output_image_filename = argv[ 2 ];
+ std::string output_marks_filename = argv[ 3 ];
+ TPixel lower = TPixel( std::atof( argv[ 4 ] ) );
+ TPixel upper = TPixel( std::atof( argv[ 5 ] ) );
+
+ // Read image
+ typedef itk::ImageFileReader< TImage > TImageReader;
+ TImageReader::Pointer input_image_reader = TImageReader::New( );
+ input_image_reader->SetFileName( input_image_filename );
+
+ // Prepare predicate
+ typedef fpa::Functors::RegionGrow::BinaryThreshold< TPixel > TPredicate;
+ TPredicate::Pointer predicate = TPredicate::New( );
+ predicate->SetLowerThreshold( lower );
+ predicate->SetUpperThreshold( upper );
+
+ // Prepare filter
+ typedef fpa::Filters::Image::RegionGrow< TImage, TImage > TFilter;
+ TFilter::Pointer filter = TFilter::New( );
+ filter->SetInput( input_image_reader->GetOutput( ) );
+ filter->SetPredicate( predicate );
+ filter->SetInsideValue( std::numeric_limits< TPixel >::max( ) );
+ filter->SetOutsideValue( TPixel( 0 ) );
+
+ // Get all seeds
+ for( int i = 6; i < argc; i += Dim )
+ {
+ TImage::IndexType seed;
+ for( int j = 0; j < Dim; ++j )
+ if( i + j < argc )
+ seed[ j ] = std::atoi( argv[ i + j ] );
+ filter->AddSeed( seed );
+
+ } // rof
+
+ // Execute filter
+ filter->Update( );
+
+ // Save results
+ typedef itk::ImageFileWriter< TFilter::TOutputImage > TOutputWriter;
+ TOutputWriter::Pointer output_writer = TOutputWriter::New( );
+ output_writer->SetInput( filter->GetOutput( ) );
+ output_writer->SetFileName( output_image_filename );
+
+ typedef itk::ImageFileWriter< TFilter::TMarksImage > TMarksWriter;
+ TMarksWriter::Pointer marks_writer = TMarksWriter::New( );
+ marks_writer->SetInput( filter->GetMarks( ) );
+ marks_writer->SetFileName( output_marks_filename );
+
+ try
+ {
+ output_writer->Update( );
+ marks_writer->Update( );
+ }
+ catch( std::exception& err )
+ {
+ std::cerr << "Error caught: " << err.what( ) << std::endl;
+ return( 1 );
+
+ } // yrt
+
+ return( 0 );
+}
+
+// eof - $RCSfile$
--- /dev/null
+## =========================================================================
+## @author Leonardo Florez Valencia
+## @email florez-l@javeriana.edu.co
+## =========================================================================
+
+set(_pfx test_fpa_Image_RegionGrow_)
+set(
+ _tests
+ Tautology
+ BinaryThreshold
+ Mori
+ )
+include_directories(${PROJECT_SOURCE_DIR}/lib ${PROJECT_BINARY_DIR}/lib)
+
+foreach(_t ${_tests})
+ add_executable(${_pfx}${_t} ${_t}.cxx)
+ target_link_libraries(${_pfx}${_t} fpa)
+endforeach(_t)
+
+## eof - $RCSfile$
--- /dev/null
+// =========================================================================
+// @author Leonardo Florez Valencia
+// @email florez-l@javeriana.edu.co
+// =========================================================================
+
+#include <itkImage.h>
+#include <itkImageFileReader.h>
+#include <itkImageFileWriter.h>
+#include <fpa/Filters/Image/Mori.h>
+
+// -------------------------------------------------------------------------
+const unsigned int Dim = 2;
+typedef unsigned char TPixel;
+typedef itk::Image< TPixel, Dim > TImage;
+
+// -------------------------------------------------------------------------
+int main( int argc, char* argv[] )
+{
+ // Get arguments
+ if( argc < 9 + Dim )
+ {
+ std::cerr
+ << "Usage: " << argv[ 0 ]
+ << " input_image output_image lower upper delta seed"
+ << std::endl;
+ return( 1 );
+
+ } // fi
+ std::string input_image_filename = argv[ 1 ];
+ std::string output_image_filename = argv[ 2 ];
+ TPixel lower = TPixel( std::atof( argv[ 3 ] ) );
+ TPixel upper = TPixel( std::atof( argv[ 4 ] ) );
+ TPixel delta = TPixel( std::atof( argv[ 5 ] ) );
+ unsigned long signal_kernel_size = std::atoi( argv[ 6 ] );
+ double signal_threshold = std::atof( argv[ 7 ] );
+ double signal_influence = std::atof( argv[ 8 ] );
+
+ // Read image
+ typedef itk::ImageFileReader< TImage > TImageReader;
+ TImageReader::Pointer input_image_reader = TImageReader::New( );
+ input_image_reader->SetFileName( input_image_filename );
+
+ // Prepare filter
+ typedef fpa::Filters::Image::Mori< TImage, TImage > TFilter;
+ TFilter::Pointer filter = TFilter::New( );
+ filter->SetInput( input_image_reader->GetOutput( ) );
+ filter->SetInsideValue( std::numeric_limits< TPixel >::max( ) );
+ filter->SetOutsideValue( TPixel( 0 ) );
+ filter->SetThresholds( lower, upper, delta );
+ filter->SetSignalKernelSize( signal_kernel_size );
+ filter->SetSignalThreshold( signal_threshold );
+ filter->SetSignalInfluence( signal_influence );
+
+ // Configure seed
+ TImage::IndexType seed;
+ for( int j = 0; j < Dim; ++j )
+ seed[ j ] = std::atoi( argv[ 9 + j ] );
+ filter->SetSeed( seed );
+
+ // Execute filter
+ filter->Update( );
+
+ // Save results
+ typedef itk::ImageFileWriter< TFilter::TOutputImage > TOutputWriter;
+ TOutputWriter::Pointer output_writer = TOutputWriter::New( );
+ output_writer->SetInput( filter->GetOutput( ) );
+ output_writer->SetFileName( output_image_filename );
+ try
+ {
+ output_writer->Update( );
+ }
+ catch( std::exception& err )
+ {
+ std::cerr << "Error caught: " << err.what( ) << std::endl;
+ return( 1 );
+
+ } // yrt
+
+ return( 0 );
+}
+
+// eof - $RCSfile$
--- /dev/null
+// =========================================================================
+// @author Leonardo Florez Valencia
+// @email florez-l@javeriana.edu.co
+// =========================================================================
+
+#include <itkImage.h>
+#include <itkImageFileWriter.h>
+#include <fpa/Filters/Image/RegionGrow.h>
+#include <fpa/Functors/RegionGrow/Tautology.h>
+
+// -------------------------------------------------------------------------
+const unsigned int Dim = 2;
+typedef unsigned char TPixel;
+typedef itk::Image< TPixel, Dim > TImage;
+
+// -------------------------------------------------------------------------
+int main( int argc, char* argv[] )
+{
+ // Get arguments
+ if( argc < 4 )
+ {
+ std::cerr
+ << "Usage: " << argv[ 0 ]
+ << " output_image output_marks size [seeds]"
+ << std::endl;
+ return( 1 );
+
+ } // fi
+ std::string output_image_filename = argv[ 1 ];
+ std::string output_marks_filename = argv[ 2 ];
+ TImage::SizeType size;
+ size.Fill( std::atoi( argv[ 3 ] ) );
+
+ // Create image
+ TImage::Pointer image = TImage::New( );
+ image->SetRegions( size );
+ image->Allocate( );
+ image->FillBuffer( TPixel( 0 ) );
+
+ // Prepare predicate
+ typedef fpa::Functors::RegionGrow::Tautology< TPixel > TPredicate;
+ TPredicate::Pointer predicate = TPredicate::New( );
+
+ // Prepare filter
+ typedef fpa::Filters::Image::RegionGrow< TImage, TImage > TFilter;
+ TFilter::Pointer filter = TFilter::New( );
+ filter->SetInput( image );
+ filter->SetPredicate( predicate );
+ filter->SetInsideValue( std::numeric_limits< TPixel >::max( ) );
+ filter->SetOutsideValue( TPixel( 0 ) );
+
+ // Get all seeds
+ for( int i = 4; i < argc; i += Dim )
+ {
+ TImage::IndexType seed;
+ for( int j = 0; j < Dim; ++j )
+ if( i + j < argc )
+ seed[ j ] = std::atoi( argv[ i + j ] );
+ filter->AddSeed( seed );
+
+ } // rof
+
+ // Execute filter
+ filter->Update( );
+
+ // Save results
+ typedef itk::ImageFileWriter< TFilter::TOutputImage > TOutputWriter;
+ TOutputWriter::Pointer output_writer = TOutputWriter::New( );
+ output_writer->SetInput( filter->GetOutput( ) );
+ output_writer->SetFileName( output_image_filename );
+
+ typedef itk::ImageFileWriter< TFilter::TMarksImage > TMarksWriter;
+ TMarksWriter::Pointer marks_writer = TMarksWriter::New( );
+ marks_writer->SetInput( filter->GetMarks( ) );
+ marks_writer->SetFileName( output_marks_filename );
+
+ try
+ {
+ output_writer->Update( );
+ marks_writer->Update( );
+ }
+ catch( std::exception& err )
+ {
+ std::cerr << "Error caught: " << err.what( ) << std::endl;
+ return( 1 );
+
+ } // yrt
+
+ return( 0 );
+}
+
+// eof - $RCSfile$
--- /dev/null
+## =========================================================================
+## @author Leonardo Florez Valencia
+## @email florez-l@javeriana.edu.co
+## =========================================================================
+
+if(VTK_FOUND)
+ set(_pfx test_fpa_Image_VTK_)
+ set(
+ _tests
+ PolyLineParametricPathToPolyData
+ SkeletonToPolyData
+ )
+ include_directories(${PROJECT_SOURCE_DIR}/lib ${PROJECT_BINARY_DIR}/lib)
+
+ foreach(_t ${_tests})
+ add_executable(${_pfx}${_t} ${_t}.cxx)
+ target_link_libraries(${_pfx}${_t} fpa ${VTK_LIBRARIES})
+ endforeach(_t)
+endif(VTK_FOUND)
+
+## eof - $RCSfile$
--- /dev/null
+// =========================================================================
+// @author Leonardo Florez Valencia
+// @email florez-l@javeriana.edu.co
+// =========================================================================
+
+#include <vtkPolyDataWriter.h>
+#include <vtkSmartPointer.h>
+#include <fpa/DataStructures/Image/PolyLineParametricPath.h>
+#include <fpa/Common/Image/PolyLineParametricPathReader.h>
+#include <fpa/VTK/Image/PolyLineParametricPathToPolyDataFilter.h>
+
+// -------------------------------------------------------------------------
+const unsigned int Dim = 2;
+typedef fpa::DataStructures::Image::PolyLineParametricPath< Dim > TPath;
+
+// -------------------------------------------------------------------------
+int main( int argc, char* argv[] )
+{
+ // Get arguments
+ if( argc < 3 )
+ {
+ std::cerr
+ << "Usage: " << argv[ 0 ]
+ << " input_path output_vtk"
+ << std::endl;
+ return( 1 );
+
+ } // fi
+ std::string input_path_filename = argv[ 1 ];
+ std::string output_vtk_filename = argv[ 2 ];
+
+ // Read image
+ typedef fpa::Common::Image::PolyLineParametricPathReader< TPath > TReader;
+ TReader::Pointer input_path_reader = TReader::New( );
+ input_path_reader->SetFileName( input_path_filename );
+ input_path_reader->Update( );
+
+ // Execute filter
+ typedef fpa::VTK::Image::PolyLineParametricPathToPolyDataFilter< TPath > TFilter;
+ vtkSmartPointer< TFilter > filter = vtkSmartPointer< TFilter >::New( );
+ filter->SetInput( input_path_reader->GetOutput( ) );
+ filter->Update( );
+
+ // Save results
+ vtkSmartPointer< vtkPolyDataWriter > output_vtk_writer =
+ vtkSmartPointer< vtkPolyDataWriter >::New( );
+ output_vtk_writer->SetFileName( output_vtk_filename.c_str( ) );
+ output_vtk_writer->SetInputConnection( filter->GetOutputPort( ) );
+ output_vtk_writer->Update( );
+
+ return( 0 );
+}
+
+// eof - $RCSfile$
--- /dev/null
+// =========================================================================
+// @author Leonardo Florez Valencia
+// @email florez-l@javeriana.edu.co
+// =========================================================================
+
+#include <vtkPolyDataWriter.h>
+#include <vtkSmartPointer.h>
+#include <fpa/DataStructures/Image/Skeleton.h>
+#include <fpa/Common/Image/SkeletonReader.h>
+#include <fpa/VTK/Image/SkeletonToPolyDataFilter.h>
+
+// -------------------------------------------------------------------------
+const unsigned int Dim = 2;
+typedef fpa::DataStructures::Image::Skeleton< Dim > TSkeleton;
+
+// -------------------------------------------------------------------------
+int main( int argc, char* argv[] )
+{
+ // Get arguments
+ if( argc < 3 )
+ {
+ std::cerr
+ << "Usage: " << argv[ 0 ]
+ << " input_skeleton output_vtk"
+ << std::endl;
+ return( 1 );
+
+ } // fi
+ std::string input_skeleton_filename = argv[ 1 ];
+ std::string output_vtk_filename = argv[ 2 ];
+
+ // Read image
+ typedef fpa::Common::Image::SkeletonReader< TSkeleton > TReader;
+ TReader::Pointer input_skeleton_reader = TReader::New( );
+ input_skeleton_reader->SetFileName( input_skeleton_filename );
+ input_skeleton_reader->Update( );
+
+ // Execute filter
+ typedef fpa::VTK::Image::SkeletonToPolyDataFilter< TSkeleton > TFilter;
+ vtkSmartPointer< TFilter > filter = vtkSmartPointer< TFilter >::New( );
+ filter->SetInput( input_skeleton_reader->GetOutput( ) );
+ filter->Update( );
+
+ // Save results
+ vtkSmartPointer< vtkPolyDataWriter > output_vtk_writer =
+ vtkSmartPointer< vtkPolyDataWriter >::New( );
+ output_vtk_writer->SetFileName( output_vtk_filename.c_str( ) );
+ output_vtk_writer->SetInputConnection( filter->GetOutputPort( ) );
+ output_vtk_writer->Update( );
+
+ return( 0 );
+}
+
+// eof - $RCSfile$