--- /dev/null
+cmake_minimum_required(VERSION 3.0)
+
+## ========================
+## == Project definition ==
+## ========================
+
+set(prj_MAJ_VERSION 0)
+set(prj_MIN_VERSION 1)
+set(prj_REL_VERSION 0)
+set(prj_VERSION "${prj_MAJ_VERSION}.${prj_MIN_VERSION}.${prj_REL_VERSION}")
+set(prj_SHORT_VERSION "${prj_MAJ_VERSION}")
+project(fpa VERSION ${prj_VERSION})
+
+## ==========================
+## == Some useful policies ==
+## ==========================
+
+set(_policies CMP0015 CMP0020 CMP0042 CMP0053)
+foreach(_p ${_policies})
+ if(POLICY ${_p})
+ cmake_policy(SET ${_p} NEW)
+ endif(POLICY ${_p})
+endforeach(_p)
+
+## ===============================
+## == Some basic configurations ==
+## ===============================
+
+include(cmake/fpaBaseConfig.cmake)
+
+## ==========================
+## == Find needed packages ==
+## ==========================
+
+find_package(ivq CONFIG QUIET)
+if(NOT ivq_FOUND)
+ find_package(ITK CONFIG REQUIRED)
+ include(${ITK_USE_FILE})
+endif(NOT ivq_FOUND)
+
+## =========================
+## == Installation values ==
+## =========================
+
+set(config_install_dir "lib/cmake/${PROJECT_NAME}")
+set(include_install_dir "include")
+set(generated_dir "${CMAKE_CURRENT_BINARY_DIR}/generated")
+set(version_config "${generated_dir}/${PROJECT_NAME}ConfigVersion.cmake")
+set(project_config "${generated_dir}/${PROJECT_NAME}Config.cmake")
+set(targets_export_name "${PROJECT_NAME}Targets")
+set(namespace "${PROJECT_NAME}::")
+
+## ===========================
+## == Build different parts ==
+## ===========================
+
+subdirs(lib tests)
+
+## ===============================
+## == Global installation rules ==
+## ===============================
+
+include(CMakePackageConfigHelpers)
+write_basic_package_version_file(
+ "${version_config}" COMPATIBILITY SameMajorVersion
+ )
+configure_package_config_file(
+ "cmake/${PROJECT_NAME}Config.cmake.in"
+ "${project_config}"
+ INSTALL_DESTINATION "${config_install_dir}"
+ )
+install(
+ FILES
+ "${project_config}"
+ "${version_config}"
+ "${CMAKE_CURRENT_SOURCE_DIR}/cmake/${PROJECT_NAME}BaseConfig.cmake"
+ DESTINATION "${config_install_dir}"
+ )
+install(
+ EXPORT "${targets_export_name}"
+ NAMESPACE "${namespace}"
+ DESTINATION "${config_install_dir}"
+ )
+
+## eof - $RCSfile$
--- /dev/null
+## =========================================================
+## == If working on a MacOSX, activate the use of RPATH's ==
+## =========================================================
+
+set(EXECUTABLE_TYPE "" CACHE STRING "Executable linking." FORCE)
+if(APPLE)
+ set(EXECUTABLE_TYPE "MACOSX_BUNDLE" CACHE STRING "Executable linking." FORCE)
+ set(CMAKE_MACOSX_RPATH true CACHE BOOL "Use RPATH's on MacOSX systems." FORCE)
+ mark_as_advanced(CMAKE_MACOSX_RPATH)
+elseif(WIN32)
+ set(EXECUTABLE_TYPE "WIN32" CACHE STRING "Executable linking." FORCE)
+endif(APPLE)
+mark_as_advanced(EXECUTABLE_TYPE)
+
+## =======================================================================
+## == Force c++11 language version ==
+## == NOTE: It seems that by default on Visual Studio Compiler supports ==
+## == c++11, so it only need to be tested on other OS. ==
+## =======================================================================
+
+if(NOT MSVC)
+ include(CheckCXXCompilerFlag)
+ check_cxx_compiler_flag("-std=c++11" COMPILER_SUPPORTS_CXX11)
+ if(COMPILER_SUPPORTS_CXX11)
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
+ else(COMPILER_SUPPORTS_CXX11)
+ check_cxx_compiler_flag("-std=c++0x" COMPILER_SUPPORTS_CXX0X)
+ if(COMPILER_SUPPORTS_CXX0X)
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x")
+ else(COMPILER_SUPPORTS_CXX0X)
+ message(
+ FATAL_ERROR
+ "The compiler ${CMAKE_CXX_COMPILER} has no C++11 support."
+ )
+ endif(COMPILER_SUPPORTS_CXX0X)
+ endif(COMPILER_SUPPORTS_CXX11)
+endif(NOT MSVC)
+
+## ===================================================
+## == Prepare header generator to build shared libs ==
+## ===================================================
+
+include(GenerateExportHeader)
+
+## ==================================================
+## == Do not allow to build inside the source tree ==
+## ==================================================
+
+if(PROJECT_BINARY_DIR STREQUAL ${PROJECT_SOURCE_DIR})
+ message(FATAL_ERROR "Building in the source tree is not allowed.")
+endif(PROJECT_BINARY_DIR STREQUAL ${PROJECT_SOURCE_DIR})
+
+## =================================================
+## == Where to put targets (executables and libs) ==
+## =================================================
+
+set(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR})
+set(LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR})
+mark_as_advanced(
+ CMAKE_BACKWARDS_COMPATIBILITY
+ EXECUTABLE_OUTPUT_PATH
+ LIBRARY_OUTPUT_PATH
+ )
+
+## eof - $RCSfile$
--- /dev/null
+@PACKAGE_INIT@
+
+include("${CMAKE_CURRENT_LIST_DIR}/fpaBaseConfig.cmake")
+include("${CMAKE_CURRENT_LIST_DIR}/@targets_export_name@.cmake")
+check_required_components("@PROJECT_NAME@")
+
+## ==============
+## == Find ITK ==
+## ==============
+
+set(ITK_DIR @ITK_DIR@)
+
+find_package(ITK CONFIG REQUIRED)
+include(${ITK_USE_FILE})
+
+## eof - $RCSfile$
--- /dev/null
+
+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
+// =========================================================================
+
+#ifndef __fpa__Base__Algorithm__h__
+#define __fpa__Base__Algorithm__h__
+
+#include <fpa/Config.h>
+
+#include <vector>
+#include <itkObject.h>
+#include <itkEventObject.h>
+
+namespace fpa
+{
+ namespace Base
+ {
+ /**
+ */
+ template< class _TFilter, class _TMarksInterface, class _TSeedsInterface >
+ class Algorithm
+ : public _TFilter,
+ public _TMarksInterface,
+ public _TSeedsInterface
+ {
+ public:
+ typedef Algorithm Self;
+ typedef _TFilter Superclass;
+ typedef _TMarksInterface TMarksInterface;
+ typedef _TSeedsInterface TSeedsInterface;
+ typedef itk::SmartPointer< Self > Pointer;
+ typedef itk::SmartPointer< const Self > ConstPointer;
+
+ typedef typename _TSeedsInterface::TInputValue TInputValue;
+ typedef typename _TSeedsInterface::TOutputValue TOutputValue;
+ typedef typename _TSeedsInterface::TNode TNode;
+ typedef typename _TSeedsInterface::TSeeds TSeeds;
+ typedef typename _TSeedsInterface::TVertex TVertex;
+
+ typedef std::vector< TVertex > TNeighborhood;
+
+ /**
+ */
+ class TEvent
+ : public itk::EventObject
+ {
+ public:
+ typedef TEvent Self;
+ typedef itk::EventObject Superclass;
+
+ public:
+ TEvent( );
+ TEvent( const TVertex& v, unsigned long fid, bool intoq );
+ virtual ~TEvent( );
+ 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;
+ };
+
+ public:
+ itkTypeMacro( fpa::Base::Algorithm, _TFilter );
+
+ itkBooleanMacro( VisualDebug );
+
+ itkGetConstMacro( InitValue, TOutputValue );
+ itkGetConstMacro( VisualDebug, bool );
+
+ itkSetMacro( InitValue, TOutputValue );
+ itkSetMacro( VisualDebug, bool );
+
+ public:
+ virtual void InvokeEvent( const itk::EventObject& e );
+ virtual void InvokeEvent( const itk::EventObject& e ) const;
+
+ protected:
+ Algorithm( );
+ virtual ~Algorithm( );
+
+ virtual void GenerateData( ) override;
+ virtual void _BeforeGenerateData( );
+ virtual void _AfterGenerateData( );
+
+ virtual void _QueueInit( );
+
+ virtual void _ConfigureOutput( const TOutputValue& v ) = 0;
+ virtual TNeighborhood _GetNeighbors( const TVertex& v ) const = 0;
+ virtual TInputValue _GetInputValue( const TVertex& v ) const = 0;
+ virtual TOutputValue _GetOutputValue( const TVertex& v ) const = 0;
+
+ virtual TOutputValue _ComputeOutputValue( const TNode& n ) = 0;
+ virtual void _UpdateOutputValue( const TNode& n ) = 0;
+ virtual void _QueueClear( ) = 0;
+ virtual void _QueuePush( const TNode& node ) = 0;
+ virtual unsigned long _QueueSize( ) const = 0;
+ virtual TNode _QueuePop( ) = 0;
+
+ private:
+ // Purposely not implemented
+ Algorithm( const Self& other );
+ Self& operator=( const Self& other );
+
+ protected:
+ bool m_VisualDebug;
+ TOutputValue m_InitValue;
+ };
+
+ } // ecapseman
+
+} // ecapseman
+
+#ifndef ITK_MANUAL_INSTANTIATION
+# include <fpa/Base/Algorithm.hxx>
+#endif // ITK_MANUAL_INSTANTIATION
+
+#endif // __fpa__Base__Algorithm__h__
+
+// eof - $RCSfile$
--- /dev/null
+// =========================================================================
+// @author Leonardo Florez Valencia
+// @email florez-l@javeriana.edu.co
+// =========================================================================
+
+#ifndef __fpa__Base__Algorithm__hxx__
+#define __fpa__Base__Algorithm__hxx__
+
+// -------------------------------------------------------------------------
+template< class _TFilter, class _TMarksInterface, class _TSeedsInterface >
+fpa::Base::Algorithm< _TFilter, _TMarksInterface, _TSeedsInterface >::TEvent::
+TEvent( )
+ : Superclass( )
+{
+}
+
+// -------------------------------------------------------------------------
+template< class _TFilter, class _TMarksInterface, class _TSeedsInterface >
+fpa::Base::Algorithm< _TFilter, _TMarksInterface, _TSeedsInterface >::TEvent::
+TEvent( const TVertex& v, unsigned long fid, bool intoq )
+ : Superclass( ),
+ Vertex( v ),
+ FrontId( fid ),
+ IntoQueue( intoq )
+{
+}
+
+// -------------------------------------------------------------------------
+template< class _TFilter, class _TMarksInterface, class _TSeedsInterface >
+fpa::Base::Algorithm< _TFilter, _TMarksInterface, _TSeedsInterface >::TEvent::
+~TEvent( )
+{
+}
+
+// -------------------------------------------------------------------------
+template< class _TFilter, class _TMarksInterface, class _TSeedsInterface >
+const char*
+fpa::Base::Algorithm< _TFilter, _TMarksInterface, _TSeedsInterface >::TEvent::
+GetEventName( ) const
+{
+ return( "fpa::Base::Algorithm< _TFilter, _TMarksInterface, _TSeedsInterface >::TEvent" );
+}
+
+// -------------------------------------------------------------------------
+template< class _TFilter, class _TMarksInterface, class _TSeedsInterface >
+bool
+fpa::Base::Algorithm< _TFilter, _TMarksInterface, _TSeedsInterface >::TEvent::
+CheckEvent( const itk::EventObject* e ) const
+{
+ return( dynamic_cast< const Self* >( e ) != NULL );
+}
+
+// -------------------------------------------------------------------------
+template< class _TFilter, class _TMarksInterface, class _TSeedsInterface >
+itk::EventObject*
+fpa::Base::Algorithm< _TFilter, _TMarksInterface, _TSeedsInterface >::TEvent::
+MakeObject( ) const
+{
+ return( new Self );
+}
+
+// -------------------------------------------------------------------------
+template< class _TFilter, class _TMarksInterface, class _TSeedsInterface >
+void fpa::Base::Algorithm< _TFilter, _TMarksInterface, _TSeedsInterface >::
+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 _TFilter, class _TMarksInterface, class _TSeedsInterface >
+void fpa::Base::Algorithm< _TFilter, _TMarksInterface, _TSeedsInterface >::
+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 _TFilter, class _TMarksInterface, class _TSeedsInterface >
+fpa::Base::Algorithm< _TFilter, _TMarksInterface, _TSeedsInterface >::
+Algorithm( )
+ : Superclass( ),
+ _TMarksInterface( this ),
+ _TSeedsInterface( this ),
+ m_VisualDebug( false )
+{
+}
+
+// -------------------------------------------------------------------------
+template< class _TFilter, class _TMarksInterface, class _TSeedsInterface >
+fpa::Base::Algorithm< _TFilter, _TMarksInterface, _TSeedsInterface >::
+~Algorithm( )
+{
+}
+
+// -------------------------------------------------------------------------
+template< class _TFilter, class _TMarksInterface, class _TSeedsInterface >
+void fpa::Base::Algorithm< _TFilter, _TMarksInterface, _TSeedsInterface >::
+GenerateData( )
+{
+ this->InvokeEvent( itk::StartEvent( ) );
+
+ // Init objects
+ this->_BeforeGenerateData( );
+ this->_ConfigureOutput( this->m_InitValue );
+ this->_InitMarks( this->GetNumberOfSeeds( ) );
+
+ // Init queue
+ this->_QueueInit( );
+ typename TSeeds::const_iterator sIt = this->BeginSeeds( );
+ for( ; sIt != this->EndSeeds( ); ++sIt )
+ {
+ this->_QueuePush( *sIt );
+ this->InvokeEvent( TEvent( sIt->Vertex, sIt->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.Vertex ) ) )
+ {
+ // Mark it
+ if( this->_Mark( node.Vertex, node.FrontId ) )
+ {
+ // Update output value
+ this->_UpdateOutputValue( node );
+
+ // 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;
+ nnode.Value = this->_ComputeOutputValue( nnode );
+ this->_QueuePush( nnode );
+ this->InvokeEvent( TEvent( nnode.Vertex, nnode.FrontId, true ) );
+
+ } // fi
+ ++nIt;
+
+ } // elihw
+
+ } // fi
+
+ } // fi
+
+ } // elihw
+
+ // Finish
+ this->_AfterGenerateData( );
+ this->InvokeEvent( itk::EndEvent( ) );
+}
+
+// -------------------------------------------------------------------------
+template< class _TFilter, class _TMarksInterface, class _TSeedsInterface >
+void fpa::Base::Algorithm< _TFilter, _TMarksInterface, _TSeedsInterface >::
+_BeforeGenerateData( )
+{
+}
+
+// -------------------------------------------------------------------------
+template< class _TFilter, class _TMarksInterface, class _TSeedsInterface >
+void fpa::Base::Algorithm< _TFilter, _TMarksInterface, _TSeedsInterface >::
+_AfterGenerateData( )
+{
+}
+
+// -------------------------------------------------------------------------
+template< class _TFilter, class _TMarksInterface, class _TSeedsInterface >
+void fpa::Base::Algorithm< _TFilter, _TMarksInterface, _TSeedsInterface >::
+_QueueInit( )
+{
+ this->_QueueClear( );
+}
+
+#endif // __fpa__Base__Algorithm__hxx__
+
+// eof - $RCSfile$
--- /dev/null
+// =========================================================================
+// @author Leonardo Florez Valencia
+// @email florez-l@javeriana.edu.co
+// =========================================================================
+
+#ifndef __fpa__Base__Dijkstra__h__
+#define __fpa__Base__Dijkstra__h__
+
+#include <fpa/Base/DijkstraBase.h>
+
+namespace fpa
+{
+ namespace Base
+ {
+ /**
+ */
+ template< class _TAlgorithm, class _TMST >
+ class Dijkstra
+ : public fpa::Base::DijkstraBase< _TAlgorithm >
+ {
+ public:
+ typedef Dijkstra Self;
+ typedef fpa::Base::DijkstraBase< _TAlgorithm > Superclass;
+ typedef itk::SmartPointer< Self > Pointer;
+ typedef itk::SmartPointer< const Self > ConstPointer;
+
+ typedef _TMST TMST;
+
+ typedef typename Superclass::TNode TNode;
+ typedef typename Superclass::TInputValue TInputValue;
+ typedef typename Superclass::TOutputValue TOutputValue;
+ typedef typename Superclass::TFrontId TFrontId;
+ typedef typename Superclass::TVertex TVertex;
+
+ typedef typename Superclass::TQueue TQueue;
+ typedef typename Superclass::TQueueOrder TQueueOrder;
+ typedef typename Superclass::TWeightFunction TWeightFunction;
+
+ public:
+ TMST* GetMinimumSpanningTree( );
+ const TMST* GetMinimumSpanningTree( ) const;
+
+ protected:
+ Dijkstra( );
+ virtual ~Dijkstra( );
+
+ virtual void _AfterGenerateData( ) override;
+ virtual void _UpdateOutputValue( const TNode& n ) override;
+
+ private:
+ // Purposely not implemented.
+ Dijkstra( const Self& other );
+ Self& operator=( const Self& other );
+
+ protected:
+ unsigned int m_MSTIdx;
+ };
+
+ } // ecapseman
+
+} // ecapseman
+
+#ifndef ITK_MANUAL_INSTANTIATION
+# include <fpa/Base/Dijkstra.hxx>
+#endif // ITK_MANUAL_INSTANTIATION
+
+#endif // __fpa__Base__Dijkstra__h__
+
+// eof - $RCSfile$
--- /dev/null
+// =========================================================================
+// @author Leonardo Florez Valencia
+// @email florez-l@javeriana.edu.co
+// =========================================================================
+
+#ifndef __fpa__Base__Dijkstra__hxx__
+#define __fpa__Base__Dijkstra__hxx__
+
+// -------------------------------------------------------------------------
+template< class _TAlgorithm, class _TMST >
+typename fpa::Base::Dijkstra< _TAlgorithm, _TMST >::
+TMST* fpa::Base::Dijkstra< _TAlgorithm, _TMST >::
+GetMinimumSpanningTree( )
+{
+ dynamic_cast< TMST* >(
+ this->itk::ProcessObject::GetOutput( this->m_MSTIdx )
+ );
+}
+
+// -------------------------------------------------------------------------
+template< class _TAlgorithm, class _TMST >
+const typename fpa::Base::Dijkstra< _TAlgorithm, _TMST >::
+TMST* fpa::Base::Dijkstra< _TAlgorithm, _TMST >::
+GetMinimumSpanningTree( ) const
+{
+ dynamic_cast< const TMST* >(
+ this->itk::ProcessObject::GetOutput( this->m_MSTIdx )
+ );
+}
+
+// -------------------------------------------------------------------------
+template< class _TAlgorithm, class _TMST >
+fpa::Base::Dijkstra< _TAlgorithm, _TMST >::
+Dijkstra( )
+ : Superclass( )
+{
+ this->m_MSTIdx = this->GetNumberOfRequiredOutputs( );
+ this->itk::ProcessObject::SetNumberOfRequiredOutputs( this->m_MSTIdx + 1 );
+ this->SetNthOutput( this->m_MSTIdx, TMST::New( ) );
+}
+
+// -------------------------------------------------------------------------
+template< class _TAlgorithm, class _TMST >
+fpa::Base::Dijkstra< _TAlgorithm, _TMST >::
+~Dijkstra( )
+{
+}
+
+// -------------------------------------------------------------------------
+template< class _TAlgorithm, class _TMST >
+void fpa::Base::Dijkstra< _TAlgorithm, _TMST >::
+_AfterGenerateData( )
+{
+ typedef typename Superclass::TSeedsInterface::TSeeds::iterator _TIt;
+
+ TMST* mst = this->GetMinimumSpanningTree( );
+ mst->ClearSeeds( );
+ mst->SetCollisions( this->m_Collisions );
+ for( _TIt sIt = this->BeginSeeds( ); sIt != this->EndSeeds( ); ++sIt )
+ mst->AddSeed( sIt->Vertex );
+}
+
+// -------------------------------------------------------------------------
+template< class _TAlgorithm, class _TMST >
+void fpa::Base::Dijkstra< _TAlgorithm, _TMST >::
+_UpdateOutputValue( const TNode& n )
+{
+ this->Superclass::_UpdateOutputValue( n );
+ this->GetMinimumSpanningTree( )->SetParent( n.Vertex, n.Parent );
+}
+
+#endif // __fpa__Base__Dijkstra__hxx__
+
+// eof - $RCSfile$
--- /dev/null
+// =========================================================================
+// @author Leonardo Florez Valencia
+// @email florez-l@javeriana.edu.co
+// =========================================================================
+
+#ifndef __fpa__Base__DijkstraBase__h__
+#define __fpa__Base__DijkstraBase__h__
+
+#include <vector>
+
+#include <itkConceptChecking.h>
+#include <fpa/Base/Functors/Dijkstra/Function.h>
+
+namespace fpa
+{
+ namespace Base
+ {
+ /**
+ */
+ template< class _TAlgorithm >
+ class DijkstraBase
+ : public _TAlgorithm
+ {
+ public:
+ typedef DijkstraBase Self;
+ typedef _TAlgorithm Superclass;
+ typedef itk::SmartPointer< Self > Pointer;
+ typedef itk::SmartPointer< const Self > ConstPointer;
+
+ typedef typename _TAlgorithm::TNode TNode;
+ typedef typename _TAlgorithm::TInputValue TInputValue;
+ typedef typename _TAlgorithm::TOutputValue TOutputValue;
+ typedef typename _TAlgorithm::TVertex TVertex;
+
+ typedef std::vector< TNode > TQueue;
+ struct TQueueOrder
+ {
+ bool operator()( const TNode& a, const TNode& b ) const
+ {
+ return( b.Value < a.Value );
+ }
+ };
+ typedef fpa::Base::Functors::Dijkstra::Function< TVertex, TOutputValue > TWeightFunction;
+
+ public:
+ itkConceptMacro(
+ Check_TOutputValue,
+ ( itk::Concept::IsFloatingPoint< TOutputValue > )
+ );
+
+ public:
+ itkGetObjectMacro( WeightFunction, TWeightFunction );
+ itkSetObjectMacro( WeightFunction, TWeightFunction );
+
+ public:
+ virtual itk::ModifiedTimeType GetMTime( ) const override;
+
+ protected:
+ DijkstraBase( );
+ virtual ~DijkstraBase( );
+
+ virtual TOutputValue _ComputeOutputValue( const TNode& n ) override;
+ virtual void _QueueInit( ) override;
+ virtual void _QueueClear( ) override;
+ virtual TNode _QueuePop( ) override;
+ virtual void _QueuePush( const TNode& node ) override;
+ virtual unsigned long _QueueSize( ) const override;
+
+ private:
+ // Purposely not implemented.
+ DijkstraBase( const Self& other );
+ Self& operator=( const Self& other );
+
+ protected:
+ typename TWeightFunction::Pointer m_WeightFunction;
+
+ TQueue m_Queue;
+ TQueueOrder m_QueueOrder;
+ };
+
+ } // ecapseman
+
+} // ecapseman
+
+#ifndef ITK_MANUAL_INSTANTIATION
+# include <fpa/Base/DijkstraBase.hxx>
+#endif // ITK_MANUAL_INSTANTIATION
+
+#endif // __fpa__Base__DijkstraBase__h__
+
+// eof - $RCSfile$
--- /dev/null
+// =========================================================================
+// @author Leonardo Florez Valencia
+// @email florez-l@javeriana.edu.co
+// =========================================================================
+
+#ifndef __fpa__Base__DijkstraBase__hxx__
+#define __fpa__Base__DijkstraBase__hxx__
+
+#include <algorithm>
+#include <limits>
+
+// -------------------------------------------------------------------------
+template< class _TAlgorithm >
+itk::ModifiedTimeType fpa::Base::DijkstraBase< _TAlgorithm >::
+GetMTime( ) const
+{
+ itk::ModifiedTimeType t = this->Superclass::GetMTime( );
+ if( this->m_WeightFunction.IsNotNull( ) )
+ {
+ itk::ModifiedTimeType q = this->m_WeightFunction->GetMTime( );
+ t = ( q < t )? q: t;
+
+ } // fi
+ return( t );
+}
+
+// -------------------------------------------------------------------------
+template< class _TAlgorithm >
+fpa::Base::DijkstraBase< _TAlgorithm >::
+DijkstraBase( )
+ : Superclass( )
+{
+ this->SetInitValue( std::numeric_limits< TOutputValue >::max( ) );
+}
+
+// -------------------------------------------------------------------------
+template< class _TAlgorithm >
+fpa::Base::DijkstraBase< _TAlgorithm >::
+~DijkstraBase( )
+{
+}
+
+// -------------------------------------------------------------------------
+template< class _TAlgorithm >
+typename fpa::Base::DijkstraBase< _TAlgorithm >::
+TOutputValue fpa::Base::DijkstraBase< _TAlgorithm >::
+_ComputeOutputValue( const TNode& n )
+{
+ TOutputValue c = this->m_WeightFunction->Evaluate( n.Vertex, n.Parent );
+ return( c + this->_GetOutputValue( n.Parent ) );
+}
+
+// -------------------------------------------------------------------------
+template< class _TAlgorithm >
+void fpa::Base::DijkstraBase< _TAlgorithm >::
+_QueueInit( )
+{
+ typedef typename Superclass::TSeedsInterface::TSeeds::iterator _TIt;
+
+ this->Superclass::_QueueInit( );
+ for( _TIt sIt = this->BeginSeeds( ); sIt != this->EndSeeds( ); ++sIt )
+ sIt->Value = TOutputValue( 0 );
+}
+
+// -------------------------------------------------------------------------
+template< class _TAlgorithm >
+void fpa::Base::DijkstraBase< _TAlgorithm >::
+_QueueClear( )
+{
+ this->m_Queue.clear( );
+}
+
+// -------------------------------------------------------------------------
+template< class _TAlgorithm >
+typename fpa::Base::DijkstraBase< _TAlgorithm >::
+TNode fpa::Base::DijkstraBase< _TAlgorithm >::
+_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 _TAlgorithm >
+void fpa::Base::DijkstraBase< _TAlgorithm >::
+_QueuePush( const TNode& node )
+{
+ bool push_needed = ( node.Parent == node.Vertex );
+ push_needed |= !( node.Value < this->_GetOutputValue( node.Parent ) );
+ if( push_needed )
+ {
+ this->m_Queue.push_back( node );
+ std::push_heap(
+ this->m_Queue.begin( ), this->m_Queue.end( ), this->m_QueueOrder
+ );
+
+ } // fi
+}
+
+// -------------------------------------------------------------------------
+template< class _TAlgorithm >
+unsigned long fpa::Base::DijkstraBase< _TAlgorithm >::
+_QueueSize( ) const
+{
+ return( this->m_Queue.size( ) );
+}
+
+#endif // __fpa__Base__DijkstraBase__hxx__
+
+// eof - $RCSfile$
--- /dev/null
+// =========================================================================
+// @author Leonardo Florez Valencia
+// @email florez-l@javeriana.edu.co
+// =========================================================================
+
+#ifndef __fpa__Base__Functors__Dijkstra__Function__h__
+#define __fpa__Base__Functors__Dijkstra__Function__h__
+
+#include <itkObject.h>
+
+namespace fpa
+{
+ namespace Base
+ {
+ namespace Functors
+ {
+ namespace Dijkstra
+ {
+ /**
+ */
+ template< class _TVertex, class _TOutputValue >
+ class Function
+ : public itk::Object
+ {
+ public:
+ typedef Function Self;
+ typedef itk::Object Superclass;
+ typedef itk::SmartPointer< Self > Pointer;
+ typedef itk::SmartPointer< const Self > ConstPointer;
+
+ public:
+ itkTypeMacro( fpa::Base::Functors::Dijkstra::Function, itk::Object );
+
+ public:
+ virtual _TOutputValue Evaluate(
+ const _TVertex& v, const _TVertex& p
+ ) const = 0;
+
+ protected:
+ Function( )
+ : Superclass( )
+ {
+ }
+ virtual ~Function( )
+ {
+ }
+
+ private:
+ // Purposely not implemented
+ Function( const Self& other );
+ Self& operator=( const Self& other );
+ };
+
+ } // ecapseman
+
+ } // ecapseman
+
+ } // ecapseman
+
+} // ecapseman
+
+#endif // __fpa__Base__Functors__Dijkstra__Function__h__
+
+// eof - $RCSfile$
--- /dev/null
+// =========================================================================
+// @author Leonardo Florez Valencia
+// @email florez-l@javeriana.edu.co
+// =========================================================================
+
+#ifndef __fpa__Base__Functors__RegionGrow__BinaryThreshold__h__
+#define __fpa__Base__Functors__RegionGrow__BinaryThreshold__h__
+
+#include <limits>
+#include <itkFunctionBase.h>
+
+namespace fpa
+{
+ namespace Base
+ {
+ namespace Functors
+ {
+ namespace RegionGrow
+ {
+ /**
+ */
+ template< class _TValue >
+ class BinaryThreshold
+ : public itk::FunctionBase< _TValue, bool >
+ {
+ public:
+ typedef BinaryThreshold Self;
+ typedef itk::FunctionBase< _TValue, bool > Superclass;
+ typedef itk::SmartPointer< Self > Pointer;
+ typedef itk::SmartPointer< const Self > ConstPointer;
+
+ public:
+ itkNewMacro( Self );
+ itkTypeMacro(
+ fpa::Base::Functors::RegionGrow::BinaryThreshold,
+ itk::FunctionBase
+ );
+
+ itkGetConstMacro( Lower, _TValue );
+ itkGetConstMacro( Upper, _TValue );
+
+ itkSetMacro( Lower, _TValue );
+ itkSetMacro( Upper, _TValue );
+
+ public:
+ virtual bool Evaluate( const _TValue& input ) const override
+ {
+ return( this->m_Lower < input && input < this->m_Upper );
+ }
+
+ protected:
+ BinaryThreshold( )
+ : Superclass( )
+ {
+ this->m_Upper = std::numeric_limits< _TValue >::max( );
+ if( std::numeric_limits< _TValue >::is_integer )
+ this->m_Lower = std::numeric_limits< _TValue >::min( );
+ else
+ this->m_Lower = -this->m_Upper;
+ }
+
+ virtual ~BinaryThreshold( )
+ {
+ }
+
+ private:
+ // Purposely not implemented
+ BinaryThreshold( const Self& other );
+ Self& operator=( const Self& other );
+
+ protected:
+ _TValue m_Lower;
+ _TValue m_Upper;
+ };
+
+ } // ecapseman
+
+ } // ecapseman
+
+ } // ecapseman
+
+} // ecapseman
+
+#endif // __fpa__Base__Functors__RegionGrow__BinaryThreshold__h__
+
+// eof - $RCSfile$
--- /dev/null
+// =========================================================================
+// @author Leonardo Florez Valencia
+// @email florez-l@javeriana.edu.co
+// =========================================================================
+
+#ifndef __fpa__Base__Functors__RegionGrow__Tautology__h__
+#define __fpa__Base__Functors__RegionGrow__Tautology__h__
+
+#include <itkFunctionBase.h>
+
+namespace fpa
+{
+ namespace Base
+ {
+ namespace Functors
+ {
+ namespace RegionGrow
+ {
+ /**
+ */
+ template< class _TValue >
+ class Tautology
+ : public itk::FunctionBase< _TValue, bool >
+ {
+ public:
+ typedef Tautology Self;
+ typedef itk::FunctionBase< _TValue, bool > Superclass;
+ typedef itk::SmartPointer< Self > Pointer;
+ typedef itk::SmartPointer< const Self > ConstPointer;
+
+ public:
+ itkNewMacro( Self );
+ itkTypeMacro(
+ fpa::Base::Functors::RegionGrow::Tautology,
+ itk::FunctionBase
+ );
+
+ public:
+ virtual bool Evaluate( const _TValue& input ) 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
+
+} // ecapseman
+
+#endif // __fpa__Base__Functors__RegionGrow__Tautology__h__
+
+// eof - $RCSfile$
--- /dev/null
+// =========================================================================
+// @author Leonardo Florez Valencia
+// @email florez-l@javeriana.edu.co
+// =========================================================================
+
+#ifndef __fpa__Base__Graph__h__
+#define __fpa__Base__Graph__h__
+
+#include <map>
+#include <set>
+#include <vector>
+#include <itkDataObject.h>
+#include <itkObjectFactory.h>
+
+namespace fpa
+{
+ namespace Base
+ {
+ /** \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/Base/Graph.hxx>
+#endif // ITK_MANUAL_INSTANTIATION
+
+#endif // __fpa__Base__Graph__h__
+
+// eof - $RCSfile$
--- /dev/null
+// =========================================================================
+// @author Leonardo Florez Valencia
+// @email florez-l@javeriana.edu.co
+// =========================================================================
+
+#ifndef __fpa__Base__Graph__hxx__
+#define __fpa__Base__Graph__hxx__
+
+// -------------------------------------------------------------------------
+template< class _TVertex, class _TCost, class _TIndex, class _TIndexCompare >
+void fpa::Base::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::Base::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::Base::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::Base::Graph< _TVertex, _TCost, _TIndex, _TIndexCompare >::
+TEdges&
+fpa::Base::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::Base::Graph< _TVertex, _TCost, _TIndex, _TIndexCompare >::
+TEdges&
+fpa::Base::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::Base::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::Base::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::Base::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::Base::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::Base::Graph< _TVertex, _TCost, _TIndex, _TIndexCompare >::
+Graph( )
+ : Superclass( )
+{
+}
+
+// -------------------------------------------------------------------------
+template< class _TVertex, class _TCost, class _TIndex, class _TIndexCompare >
+fpa::Base::Graph< _TVertex, _TCost, _TIndex, _TIndexCompare >::
+~Graph( )
+{
+}
+
+#endif // __fpa__Base__Graph__hxx__
+
+// eof - $RCSfile$
--- /dev/null
+// =========================================================================
+// @author Leonardo Florez Valencia
+// @email florez-l@javeriana.edu.co
+// =========================================================================
+
+#ifndef __fpa__Base__MarksInterface__h__
+#define __fpa__Base__MarksInterface__h__
+
+#include <itkProcessObject.h>
+
+namespace fpa
+{
+ namespace Base
+ {
+ /**
+ */
+ template< class _TVertex >
+ class MarksInterface
+ {
+ public:
+ typedef _TVertex TVertex;
+ typedef MarksInterface Self;
+
+ protected:
+ MarksInterface( itk::ProcessObject* filter );
+ virtual ~MarksInterface( );
+
+ virtual bool _IsMarked( const TVertex& v ) const = 0;
+ virtual unsigned long _GetMark( const TVertex& v ) const = 0;
+ virtual bool _Mark( const TVertex& v, unsigned long frontId ) = 0;
+
+ virtual void _InitMarks( unsigned long nSeeds );
+ virtual bool _Collisions( const TVertex& a, const TVertex& b );
+
+ protected:
+ unsigned int m_NumberOfSeeds;
+ itk::ProcessObject* m_Filter;
+ };
+
+ } // ecapseman
+
+} // ecapseman
+
+#ifndef ITK_MANUAL_INSTANTIATION
+# include <fpa/Base/MarksInterface.hxx>
+#endif // ITK_MANUAL_INSTANTIATION
+
+#endif // __fpa__Base__MarksInterface__h__
+
+// eof - $RCSfile$
--- /dev/null
+// =========================================================================
+// @author Leonardo Florez Valencia
+// @email florez-l@javeriana.edu.co
+// =========================================================================
+
+#ifndef __fpa__Base__MarksInterface__hxx__
+#define __fpa__Base__MarksInterface__hxx__
+
+// -------------------------------------------------------------------------
+template< class _TVertex >
+fpa::Base::MarksInterface< _TVertex >::
+MarksInterface( itk::ProcessObject* filter )
+ : m_NumberOfSeeds( 0 ),
+ m_Filter( filter )
+{
+}
+
+// -------------------------------------------------------------------------
+template< class _TVertex >
+fpa::Base::MarksInterface< _TVertex >::
+~MarksInterface( )
+{
+}
+
+// -------------------------------------------------------------------------
+template< class _TVertex >
+void fpa::Base::MarksInterface< _TVertex >::
+_InitMarks( unsigned long nSeeds )
+{
+ this->m_NumberOfSeeds = nSeeds;
+}
+
+// -------------------------------------------------------------------------
+template< class _TVertex >
+bool fpa::Base::MarksInterface< _TVertex >::
+_Collisions( const TVertex& a, const TVertex& b )
+{
+ return( false );
+}
+
+#endif // __fpa__Base__MarksInterface__hxx__
+
+// eof - $RCSfile$
--- /dev/null
+// =========================================================================
+// @author Leonardo Florez Valencia
+// @email florez-l@javeriana.edu.co
+// =========================================================================
+
+#ifndef __fpa__Base__MarksInterfaceWithCollisions__h__
+#define __fpa__Base__MarksInterfaceWithCollisions__h__
+
+#include <fpa/Base/MarksInterface.h>
+#include <utility>
+#include <vector>
+
+namespace fpa
+{
+ namespace Base
+ {
+ /**
+ */
+ template< class _TVertex >
+ class MarksInterfaceWithCollisions
+ : public fpa::Base::MarksInterface< _TVertex >
+ {
+ public:
+ typedef _TVertex TVertex;
+ typedef MarksInterfaceWithCollisions Self;
+ typedef fpa::Base::MarksInterface< TVertex > Superclass;
+
+ // Minigraph to represent collisions
+ typedef std::pair< TVertex, bool > TCollision;
+ typedef std::vector< TCollision > TCollisionsRow;
+ typedef std::vector< TCollisionsRow > TCollisions;
+
+ public:
+ bool StopAtOneFront( ) const;
+ void StopAtOneFrontOn( );
+ void StopAtOneFrontOff( );
+ void SetStopAtOneFront( bool v );
+
+ protected:
+ MarksInterfaceWithCollisions( itk::ProcessObject* filter );
+ virtual ~MarksInterfaceWithCollisions( );
+
+ virtual void _InitMarks( 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;
+ };
+
+ } // ecapseman
+
+} // ecapseman
+
+#ifndef ITK_MANUAL_INSTANTIATION
+# include <fpa/Base/MarksInterfaceWithCollisions.hxx>
+#endif // ITK_MANUAL_INSTANTIATION
+
+#endif // __fpa__Base__MarksInterfaceWithCollisions__h__
+
+// eof - $RCSfile$
--- /dev/null
+// =========================================================================
+// @author Leonardo Florez Valencia
+// @email florez-l@javeriana.edu.co
+// =========================================================================
+
+#ifndef __fpa__Base__MarksInterfaceWithCollisions__hxx__
+#define __fpa__Base__MarksInterfaceWithCollisions__hxx__
+
+#include <queue>
+
+// -------------------------------------------------------------------------
+template< class _TVertex >
+bool fpa::Base::MarksInterfaceWithCollisions< _TVertex >::
+StopAtOneFront( ) const
+{
+ return( this->m_StopAtOneFront );
+}
+
+// -------------------------------------------------------------------------
+template< class _TVertex >
+void fpa::Base::MarksInterfaceWithCollisions< _TVertex >::
+StopAtOneFrontOn( )
+{
+ this->SetStopAtOneFront( true );
+}
+
+// -------------------------------------------------------------------------
+template< class _TVertex >
+void fpa::Base::MarksInterfaceWithCollisions< _TVertex >::
+StopAtOneFrontOff( )
+{
+ this->SetStopAtOneFront( false );
+}
+
+// -------------------------------------------------------------------------
+template< class _TVertex >
+void fpa::Base::MarksInterfaceWithCollisions< _TVertex >::
+SetStopAtOneFront( bool v )
+{
+ if( this->m_StopAtOneFront != v )
+ {
+ this->m_StopAtOneFront = v;
+ if( this->m_Filter != NULL )
+ this->m_Filter->Modified( );
+
+ } // fi
+}
+
+// -------------------------------------------------------------------------
+template< class _TVertex >
+fpa::Base::MarksInterfaceWithCollisions< _TVertex >::
+MarksInterfaceWithCollisions( itk::ProcessObject* filter )
+ : Superclass( filter ),
+ m_StopAtOneFront( false ),
+ m_NumberOfFronts( 0 )
+{
+}
+
+// -------------------------------------------------------------------------
+template< class _TVertex >
+fpa::Base::MarksInterfaceWithCollisions< _TVertex >::
+~MarksInterfaceWithCollisions( )
+{
+}
+
+// -------------------------------------------------------------------------
+template< class _TVertex >
+void fpa::Base::MarksInterfaceWithCollisions< _TVertex >::
+_InitMarks( unsigned long nSeeds )
+{
+ this->Superclass::_InitMarks( nSeeds );
+ this->m_NumberOfFronts = 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 _TVertex >
+bool fpa::Base::MarksInterfaceWithCollisions< _TVertex >::
+_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__Base__MarksInterfaceWithCollisions__hxx__
+
+// eof - $RCSfile$
--- /dev/null
+// =========================================================================
+// @author Leonardo Florez Valencia
+// @email florez-l@javeriana.edu.co
+// =========================================================================
+
+#ifndef __fpa__Base__MinimumSpanningTree__h__
+#define __fpa__Base__MinimumSpanningTree__h__
+
+#include <vector>
+
+namespace fpa
+{
+ namespace Base
+ {
+ /**
+ */
+ 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/Base/MinimumSpanningTree.hxx>
+#endif // ITK_MANUAL_INSTANTIATION
+
+#endif // __fpa__Base__MinimumSpanningTree__h__
+
+// eof - $RCSfile$
--- /dev/null
+// =========================================================================
+// @author Leonardo Florez Valencia
+// @email florez-l@javeriana.edu.co
+// =========================================================================
+
+#ifndef __fpa__Base__MinimumSpanningTree__hxx__
+#define __fpa__Base__MinimumSpanningTree__hxx__
+
+// -------------------------------------------------------------------------
+template< class _TVertex, class _Superclass >
+const typename fpa::Base::MinimumSpanningTree< _TVertex, _Superclass >::
+TCollisions& fpa::Base::MinimumSpanningTree< _TVertex, _Superclass >::
+GetCollisions( ) const
+{
+ return( this->m_Collisions );
+}
+
+// -------------------------------------------------------------------------
+template< class _TVertex, class _Superclass >
+void fpa::Base::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::Base::MinimumSpanningTree< _TVertex, _Superclass >::
+ClearSeeds( )
+{
+ this->m_Seeds.clear( );
+ this->Modified( );
+}
+
+// -------------------------------------------------------------------------
+template< class _TVertex, class _Superclass >
+void fpa::Base::MinimumSpanningTree< _TVertex, _Superclass >::
+AddSeed( const _TVertex& seed )
+{
+ this->m_Seeds.push_back( seed );
+ this->Modified( );
+}
+
+// -------------------------------------------------------------------------
+template< class _TVertex, class _Superclass >
+typename fpa::Base::MinimumSpanningTree< _TVertex, _Superclass >::
+TVertices fpa::Base::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::Base::MinimumSpanningTree< _TVertex, _Superclass >::
+TVertices fpa::Base::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 ] ][ fpath[ i - 1 ] ].first,
+ this->m_Collisions[ fpath[ i ] ][ fpath[ i + 1 ] ].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::Base::MinimumSpanningTree< _TVertex, _Superclass >::
+MinimumSpanningTree( )
+ : Superclass( )
+{
+}
+
+// -------------------------------------------------------------------------
+template< class _TVertex, class _Superclass >
+fpa::Base::MinimumSpanningTree< _TVertex, _Superclass >::
+~MinimumSpanningTree( )
+{
+}
+
+#endif // __fpa__Base__MinimumSpanningTree__hxx__
+
+// eof - $RCSfile$
--- /dev/null
+// =========================================================================
+// @author Leonardo Florez Valencia
+// @email florez-l@javeriana.edu.co
+// =========================================================================
+
+#ifndef __fpa__Base__RegionGrow__h__
+#define __fpa__Base__RegionGrow__h__
+
+#include <deque>
+
+#include <itkConceptChecking.h>
+#include <itkFunctionBase.h>
+
+namespace fpa
+{
+ namespace Base
+ {
+ /**
+ */
+ template< class _TAlgorithm >
+ class RegionGrow
+ : public _TAlgorithm
+ {
+ public:
+ typedef RegionGrow Self;
+ typedef _TAlgorithm Superclass;
+ typedef itk::SmartPointer< Self > Pointer;
+ typedef itk::SmartPointer< const Self > ConstPointer;
+
+ typedef typename _TAlgorithm::TNode TNode;
+ typedef typename _TAlgorithm::TInputValue TInputValue;
+ typedef typename _TAlgorithm::TOutputValue TOutputValue;
+ typedef typename _TAlgorithm::TFrontId TFrontId;
+ typedef typename _TAlgorithm::TVertex TVertex;
+
+ typedef std::deque< TNode > TQueue;
+ typedef itk::FunctionBase< TInputValue, bool > TValuePredicate;
+ typedef itk::FunctionBase< TVertex, bool > TVertexPredicate;
+
+ public:
+ itkConceptMacro(
+ Check_TOutputValue,
+ ( itk::Concept::IsUnsignedInteger< TOutputValue > )
+ );
+
+ public:
+ itkGetObjectMacro( ValuePredicate, TValuePredicate );
+ itkGetObjectMacro( VertexPredicate, TVertexPredicate );
+ itkGetConstMacro( InsideValue, TOutputValue );
+
+ itkSetMacro( InsideValue, TOutputValue );
+
+ public:
+ virtual itk::ModifiedTimeType GetMTime( ) const override;
+ virtual TOutputValue GetOutsideValue( ) const;
+ virtual void SetOutsideValue( const TOutputValue& v );
+
+ void SetPredicate( TValuePredicate* p );
+ void SetPredicate( TVertexPredicate* p );
+
+ protected:
+ RegionGrow( );
+ virtual ~RegionGrow( );
+
+ virtual TOutputValue _ComputeOutputValue( const TNode& n ) override;
+ virtual void _QueueInit( ) override;
+ virtual void _QueueClear( ) override;
+ virtual TNode _QueuePop( ) override;
+ virtual void _QueuePush( const TNode& node ) override;
+ virtual unsigned long _QueueSize( ) const override;
+
+ private:
+ // Purposely not implemented.
+ RegionGrow( const Self& other );
+ Self& operator=( const Self& other );
+
+ protected:
+ typename TValuePredicate::Pointer m_ValuePredicate;
+ typename TVertexPredicate::Pointer m_VertexPredicate;
+
+ TOutputValue m_InsideValue;
+
+ TQueue m_Queue;
+ };
+
+ } // ecapseman
+
+} // ecapseman
+
+#ifndef ITK_MANUAL_INSTANTIATION
+# include <fpa/Base/RegionGrow.hxx>
+#endif // ITK_MANUAL_INSTANTIATION
+
+#endif // __fpa__Base__RegionGrow__h__
+
+// eof - $RCSfile$
--- /dev/null
+// =========================================================================
+// @author Leonardo Florez Valencia
+// @email florez-l@javeriana.edu.co
+// =========================================================================
+
+#ifndef __fpa__Base__RegionGrow__hxx__
+#define __fpa__Base__RegionGrow__hxx__
+
+// -------------------------------------------------------------------------
+template< class _TAlgorithm >
+itk::ModifiedTimeType fpa::Base::RegionGrow< _TAlgorithm >::
+GetMTime( ) const
+{
+ itk::ModifiedTimeType t = this->Superclass::GetMTime( );
+ if( this->m_ValuePredicate.IsNotNull( ) )
+ {
+ itk::ModifiedTimeType q = this->m_ValuePredicate->GetMTime( );
+ t = ( q < t )? q: t;
+
+ } // fi
+ if( this->m_VertexPredicate.IsNotNull( ) )
+ {
+ itk::ModifiedTimeType q = this->m_VertexPredicate->GetMTime( );
+ t = ( q < t )? q: t;
+
+ } // fi
+
+ return( t );
+}
+
+// -------------------------------------------------------------------------
+template< class _TAlgorithm >
+typename fpa::Base::RegionGrow< _TAlgorithm >::
+TOutputValue fpa::Base::RegionGrow< _TAlgorithm >::
+GetOutsideValue( ) const
+{
+ return( this->GetInitValue( ) );
+}
+
+// -------------------------------------------------------------------------
+template< class _TAlgorithm >
+void fpa::Base::RegionGrow< _TAlgorithm >::
+SetOutsideValue( const TOutputValue& v )
+{
+ this->SetInitValue( v );
+}
+
+// -------------------------------------------------------------------------
+template< class _TAlgorithm >
+void fpa::Base::RegionGrow< _TAlgorithm >::
+SetPredicate( TValuePredicate* p )
+{
+ if( this->m_ValuePredicate.GetPointer( ) != p )
+ {
+ this->m_ValuePredicate = p;
+ this->Modified( );
+
+ } // fi
+}
+
+// -------------------------------------------------------------------------
+template< class _TAlgorithm >
+void fpa::Base::RegionGrow< _TAlgorithm >::
+SetPredicate( TVertexPredicate* p )
+{
+ if( this->m_VertexPredicate.GetPointer( ) != p )
+ {
+ this->m_VertexPredicate = p;
+ this->Modified( );
+
+ } // fi
+}
+
+// -------------------------------------------------------------------------
+template< class _TAlgorithm >
+fpa::Base::RegionGrow< _TAlgorithm >::
+RegionGrow( )
+ : Superclass( ),
+ m_InsideValue( TOutputValue( 1 ) )
+{
+ this->SetInitValue( TOutputValue( 0 ) );
+}
+
+// -------------------------------------------------------------------------
+template< class _TAlgorithm >
+fpa::Base::RegionGrow< _TAlgorithm >::
+~RegionGrow( )
+{
+}
+
+// -------------------------------------------------------------------------
+template< class _TAlgorithm >
+typename fpa::Base::RegionGrow< _TAlgorithm >::
+TOutputValue fpa::Base::RegionGrow< _TAlgorithm >::
+_ComputeOutputValue( const TNode& n )
+{
+ TInputValue value = this->_GetInputValue( n.Vertex );
+ bool inside = false;
+ if( this->m_ValuePredicate.IsNotNull( ) )
+ inside = this->m_ValuePredicate->Evaluate( value );
+ if( this->m_VertexPredicate.IsNotNull( ) )
+ inside &= this->m_VertexPredicate->Evaluate( n.Vertex );
+ return( ( inside )? this->m_InsideValue: this->m_InitValue );
+}
+
+// -------------------------------------------------------------------------
+template< class _TAlgorithm >
+void fpa::Base::RegionGrow< _TAlgorithm >::
+_QueueInit( )
+{
+ typedef typename Superclass::TSeedsInterface::TSeeds::iterator _TIt;
+
+ this->Superclass::_QueueInit( );
+ for( _TIt sIt = this->BeginSeeds( ); sIt != this->EndSeeds( ); ++sIt )
+ sIt->Value = this->m_InsideValue;
+}
+
+// -------------------------------------------------------------------------
+template< class _TAlgorithm >
+void fpa::Base::RegionGrow< _TAlgorithm >::
+_QueueClear( )
+{
+ this->m_Queue.clear( );
+}
+
+// -------------------------------------------------------------------------
+template< class _TAlgorithm >
+typename fpa::Base::RegionGrow< _TAlgorithm >::
+TNode fpa::Base::RegionGrow< _TAlgorithm >::
+_QueuePop( )
+{
+ TNode n = this->m_Queue.front( );
+ this->m_Queue.pop_front( );
+ return( n );
+}
+
+// -------------------------------------------------------------------------
+template< class _TAlgorithm >
+void fpa::Base::RegionGrow< _TAlgorithm >::
+_QueuePush( const TNode& node )
+{
+ this->m_Queue.push_back( node );
+}
+
+// -------------------------------------------------------------------------
+template< class _TAlgorithm >
+unsigned long fpa::Base::RegionGrow< _TAlgorithm >::
+_QueueSize( ) const
+{
+ return( this->m_Queue.size( ) );
+}
+
+#endif // __fpa__Base__RegionGrow__hxx__
+
+// eof - $RCSfile$
--- /dev/null
+// =========================================================================
+// @author Leonardo Florez Valencia
+// @email florez-l@javeriana.edu.co
+// =========================================================================
+
+#ifndef __fpa__Base__SeedsInterface__h__
+#define __fpa__Base__SeedsInterface__h__
+
+#include <functional>
+#include <set>
+
+#include <itkConceptChecking.h>
+#include <itkProcessObject.h>
+
+namespace fpa
+{
+ namespace Base
+ {
+ /**
+ */
+ template< class _TVertex, class _TInputValue, class _TOutputValue, class _TFrontId, class _TCompare = std::greater< _TVertex > >
+ class SeedsInterface
+ {
+ public:
+ itkConceptMacro(
+ Check_TFrontId,
+ ( itk::Concept::IsUnsignedInteger< _TFrontId > )
+ );
+
+ public:
+ typedef _TVertex TVertex;
+ typedef _TInputValue TInputValue;
+ typedef _TOutputValue TOutputValue;
+ typedef _TFrontId TFrontId;
+ typedef _TCompare TCompare;
+ typedef SeedsInterface Self;
+
+ struct TNode
+ {
+ TVertex Vertex;
+ TVertex Parent;
+ TFrontId FrontId;
+
+ // Hack to hide the fact that seed values need to be initialized
+ mutable TOutputValue Value;
+ };
+ struct TNodeCompare
+ {
+ bool operator()( const TNode& a, const TNode& b ) const
+ {
+ TCompare cmp;
+ return( cmp( a.Vertex, b.Vertex ) );
+ }
+ };
+ typedef std::set< TNode, TNodeCompare > TSeeds;
+
+ public:
+ unsigned int GetNumberOfSeeds( ) const;
+ const TSeeds& GetSeeds( ) const;
+ typename TSeeds::const_iterator BeginSeeds( ) const;
+ typename TSeeds::const_iterator EndSeeds( ) const;
+
+ virtual void AddSeed( const TVertex& seed );
+ virtual void RemoveSeed( const TVertex& seed );
+ virtual void ClearSeeds( );
+
+ protected:
+ SeedsInterface( itk::ProcessObject* filter );
+ virtual ~SeedsInterface( );
+
+ protected:
+ TSeeds m_Seeds;
+ itk::ProcessObject* m_Filter;
+ };
+
+ } // ecapseman
+
+} // ecapseman
+
+#ifndef ITK_MANUAL_INSTANTIATION
+# include <fpa/Base/SeedsInterface.hxx>
+#endif // ITK_MANUAL_INSTANTIATION
+
+#endif // __fpa__Base__SeedsInterface__h__
+
+// eof - $RCSfile$
--- /dev/null
+// =========================================================================
+// @author Leonardo Florez Valencia
+// @email florez-l@javeriana.edu.co
+// =========================================================================
+
+#ifndef __fpa__Base__SeedsInterface__hxx__
+#define __fpa__Base__SeedsInterface__hxx__
+
+// -------------------------------------------------------------------------
+template< class _TVertex, class _TInputValue, class _TOutputValue, class _TFrontId, class _TCompare >
+unsigned int
+fpa::Base::SeedsInterface< _TVertex, _TInputValue, _TOutputValue, _TFrontId, _TCompare >::
+GetNumberOfSeeds( ) const
+{
+ return( this->m_Seeds.size( ) );
+}
+
+// -------------------------------------------------------------------------
+template< class _TVertex, class _TInputValue, class _TOutputValue, class _TFrontId, class _TCompare >
+const typename
+fpa::Base::SeedsInterface< _TVertex, _TInputValue, _TOutputValue, _TFrontId, _TCompare >::
+TSeeds&
+fpa::Base::SeedsInterface< _TVertex, _TInputValue, _TOutputValue, _TFrontId, _TCompare >::
+GetSeeds( ) const
+{
+ return( this->m_Seeds );
+}
+
+// -------------------------------------------------------------------------
+template< class _TVertex, class _TInputValue, class _TOutputValue, class _TFrontId, class _TCompare >
+typename
+fpa::Base::SeedsInterface< _TVertex, _TInputValue, _TOutputValue, _TFrontId, _TCompare >::
+TSeeds::const_iterator
+fpa::Base::SeedsInterface< _TVertex, _TInputValue, _TOutputValue, _TFrontId, _TCompare >::
+BeginSeeds( ) const
+{
+ return( this->m_Seeds.begin( ) );
+}
+
+// -------------------------------------------------------------------------
+template< class _TVertex, class _TInputValue, class _TOutputValue, class _TFrontId, class _TCompare >
+typename
+fpa::Base::SeedsInterface< _TVertex, _TInputValue, _TOutputValue, _TFrontId, _TCompare >::
+TSeeds::const_iterator
+fpa::Base::SeedsInterface< _TVertex, _TInputValue, _TOutputValue, _TFrontId, _TCompare >::
+EndSeeds( ) const
+{
+ return( this->m_Seeds.end( ) );
+}
+
+// -------------------------------------------------------------------------
+template< class _TVertex, class _TInputValue, class _TOutputValue, class _TFrontId, class _TCompare >
+void
+fpa::Base::SeedsInterface< _TVertex, _TInputValue, _TOutputValue, _TFrontId, _TCompare >::
+AddSeed( const TVertex& seed )
+{
+ TNode node;
+ node.Vertex = seed;
+ node.Parent = seed;
+ node.FrontId = TFrontId( this->m_Seeds.size( ) + 1 );
+ if( this->m_Seeds.insert( node ).second && this->m_Filter != NULL )
+ this->m_Filter->Modified( );
+}
+
+// -------------------------------------------------------------------------
+template< class _TVertex, class _TInputValue, class _TOutputValue, class _TFrontId, class _TCompare >
+void
+fpa::Base::SeedsInterface< _TVertex, _TInputValue, _TOutputValue, _TFrontId, _TCompare >::
+RemoveSeed( const TVertex& seed )
+{
+ TNode node;
+ node.Vertex = seed;
+ node.Parent = seed;
+ typename TSeeds::const_iterator i = this->m_Seeds.find( node );
+ if( i != this->m_Seeds.end( ) )
+ {
+ this->m_Seeds.erase( i );
+ if( this->m_Filter != NULL )
+ this->m_Filter->Modified( );
+
+ } // fi
+}
+
+// -------------------------------------------------------------------------
+template< class _TVertex, class _TInputValue, class _TOutputValue, class _TFrontId, class _TCompare >
+void
+fpa::Base::SeedsInterface< _TVertex, _TInputValue, _TOutputValue, _TFrontId, _TCompare >::
+ClearSeeds( )
+{
+ if( this->m_Seeds.size( ) > 0 )
+ {
+ this->m_Seeds.clear( );
+ if( this->m_Filter != NULL )
+ this->m_Filter->Modified( );
+
+ } // fi
+}
+
+// -------------------------------------------------------------------------
+template< class _TVertex, class _TInputValue, class _TOutputValue, class _TFrontId, class _TCompare >
+fpa::Base::SeedsInterface< _TVertex, _TInputValue, _TOutputValue, _TFrontId, _TCompare >::
+SeedsInterface( itk::ProcessObject* filter )
+ : m_Filter( filter )
+{
+}
+
+// -------------------------------------------------------------------------
+template< class _TVertex, class _TInputValue, class _TOutputValue, class _TFrontId, class _TCompare >
+fpa::Base::SeedsInterface< _TVertex, _TInputValue, _TOutputValue, _TFrontId, _TCompare >::
+~SeedsInterface( )
+{
+ this->m_Seeds.clear( );
+}
+
+#endif // __fpa__Base__SeedsInterface__hxx__
+
+// eof - $RCSfile$
--- /dev/null
+
+## =====================
+## == Get source code ==
+## =====================
+
+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 _base_src "${CMAKE_CURRENT_SOURCE_DIR}/Base/*.cxx")
+file(GLOB_RECURSE _base_hdr "${CMAKE_CURRENT_SOURCE_DIR}/Base/*.h")
+file(GLOB_RECURSE _base_hrc "${CMAKE_CURRENT_SOURCE_DIR}/Base/*.hxx")
+file(GLOB_RECURSE _image_src "${CMAKE_CURRENT_SOURCE_DIR}/Image/*.cxx")
+file(GLOB_RECURSE _image_hdr "${CMAKE_CURRENT_SOURCE_DIR}/Image/*.h")
+file(GLOB_RECURSE _image_hrc "${CMAKE_CURRENT_SOURCE_DIR}/Image/*.hxx")
+
+set(_src
+ ${_base_src} ${_image_src}
+ "${CMAKE_CURRENT_BINARY_DIR}/Version.cxx"
+ )
+set(
+ _hdr
+ ${_base_hdr} ${_image_hdr}
+ "${CMAKE_CURRENT_BINARY_DIR}/Config.h"
+ )
+set(_hrc ${_base_hrc} ${_image_hrc})
+
+## =====================
+## == Compile library ==
+## =====================
+
+add_library(fpa SHARED ${_src} ${_hdr} ${_hrc})
+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 ${VTK_LIBRARIES} ${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"
+ )
+
+## eof - $RCSfile$
--- /dev/null
+// =========================================================================
+// @author Leonardo Florez Valencia
+// @email florez-l@javeriana.edu.co
+// =========================================================================
+
+#ifndef __fpa__Config__h__
+#define __fpa__Config__h__
+
+#define ivq_FOUND @ivq_FOUND@
+#if ivq_FOUND == 1
+# define USE_ivq
+#else
+# undef USE_ivq
+#endif
+
+#endif // __fpa__Config__h__
+
+// eof - $RCSfile$
--- /dev/null
+// =========================================================================
+// @author Leonardo Florez Valencia
+// @email florez-l@javeriana.edu.co
+// =========================================================================
+
+#ifndef __fpa__Image__Algorithm__h__
+#define __fpa__Image__Algorithm__h__
+
+#include <itkImage.h>
+#include <itkImageToImageFilter.h>
+
+#include <fpa/Base/Algorithm.h>
+
+namespace fpa
+{
+ namespace Image
+ {
+ /**
+ */
+ template< class _TInputImage, class _TOutputImage, class _TMarksInterface, class _TSeedsInterface >
+ class Algorithm
+ : public fpa::Base::Algorithm< itk::ImageToImageFilter< _TInputImage, _TOutputImage >, _TMarksInterface, _TSeedsInterface >
+ {
+ public:
+ typedef _TInputImage TInputImage;
+ typedef _TOutputImage TOutputImage;
+ typedef _TMarksInterface TMarksInterface;
+ typedef _TSeedsInterface TSeedsInterface;
+ typedef itk::ImageToImageFilter< TInputImage, TOutputImage > TFilter;
+
+ typedef Algorithm Self;
+ typedef fpa::Base::Algorithm< TFilter, TMarksInterface, TSeedsInterface > Superclass;
+ typedef itk::SmartPointer< Self > Pointer;
+ typedef itk::SmartPointer< const Self > ConstPointer;
+
+ typedef typename TInputImage::PixelType TInputValue;
+ typedef typename TOutputImage::PixelType TOutputValue;
+ typedef typename Superclass::TFrontId TFrontId;
+ typedef typename Superclass::TNeighborhood TNeighborhood;
+ typedef typename Superclass::TNode TNode;
+ typedef typename Superclass::TVertex TVertex;
+
+ typedef itk::Image< TFrontId, TInputImage::ImageDimension > TMarks;
+
+ public:
+ itkTypeMacro( fpa::Image::Algorithm, fpa::Base::Algorithm );
+
+ itkGetConstMacro( NeigborhoodOrder, unsigned int );
+ itkSetMacro( NeigborhoodOrder, unsigned int );
+
+ public:
+ TMarks* GetMarks( );
+ const TMarks* GetMarks( ) const;
+
+ protected:
+ Algorithm( );
+ virtual ~Algorithm( );
+
+ virtual void _ConfigureOutput( const TOutputValue& v ) override;
+ virtual TNeighborhood _GetNeighbors( const TVertex& v ) const override;
+ virtual TInputValue _GetInputValue( const TVertex& v ) const override;
+ virtual TOutputValue _GetOutputValue( const TVertex& v ) const override;
+ virtual void _UpdateOutputValue( const TNode& n ) override;
+ virtual bool _IsMarked( const TVertex& v ) const override;
+ virtual unsigned long _GetMark( const TVertex& v ) const override;
+ virtual bool _Mark( const TVertex& v, unsigned long frontId ) override;
+
+ private:
+ // Purposely not implemented.
+ Algorithm( const Self& other );
+ Self& operator=( const Self& other );
+
+ protected:
+ unsigned long m_MarksIdx;
+ unsigned int m_NeigborhoodOrder;
+ };
+
+ } // ecapseman
+
+} // ecapseman
+
+#ifndef ITK_MANUAL_INSTANTIATION
+# include <fpa/Image/Algorithm.hxx>
+#endif // ITK_MANUAL_INSTANTIATION
+
+#endif // __fpa__Image__Algorithm__h__
+
+// eof - $RCSfile$
--- /dev/null
+// =========================================================================
+// @author Leonardo Florez Valencia
+// @email florez-l@javeriana.edu.co
+// =========================================================================
+
+#ifndef __fpa__Image__Algorithm__hxx__
+#define __fpa__Image__Algorithm__hxx__
+
+// -------------------------------------------------------------------------
+template< class _TInputImage, class _TOutputImage, class _TMarksInterface, class _TSeedsInterface >
+typename
+fpa::Image::Algorithm< _TInputImage, _TOutputImage, _TMarksInterface, _TSeedsInterface >::
+TMarks*
+fpa::Image::Algorithm< _TInputImage, _TOutputImage, _TMarksInterface, _TSeedsInterface >::
+GetMarks( )
+{
+ dynamic_cast< TMarks* >(
+ this->itk::ProcessObject::GetOutput( this->m_MarksIdx )
+ );
+}
+
+// -------------------------------------------------------------------------
+template< class _TInputImage, class _TOutputImage, class _TMarksInterface, class _TSeedsInterface >
+const typename
+fpa::Image::Algorithm< _TInputImage, _TOutputImage, _TMarksInterface, _TSeedsInterface >::
+TMarks*
+fpa::Image::Algorithm< _TInputImage, _TOutputImage, _TMarksInterface, _TSeedsInterface >::
+GetMarks( ) const
+{
+ dynamic_cast< const TMarks* >(
+ this->itk::ProcessObject::GetOutput( this->m_MarksIdx )
+ );
+}
+
+// -------------------------------------------------------------------------
+template< class _TInputImage, class _TOutputImage, class _TMarksInterface, class _TSeedsInterface >
+fpa::Image::Algorithm< _TInputImage, _TOutputImage, _TMarksInterface, _TSeedsInterface >::
+Algorithm( )
+ : Superclass( ),
+ m_NeigborhoodOrder( 1 )
+{
+ this->m_MarksIdx = this->GetNumberOfRequiredOutputs( );
+ this->itk::ProcessObject::SetNumberOfRequiredOutputs( this->m_MarksIdx + 1 );
+ this->SetNthOutput( this->m_MarksIdx, TMarks::New( ) );
+}
+
+// -------------------------------------------------------------------------
+template< class _TInputImage, class _TOutputImage, class _TMarksInterface, class _TSeedsInterface >
+fpa::Image::Algorithm< _TInputImage, _TOutputImage, _TMarksInterface, _TSeedsInterface >::
+~Algorithm( )
+{
+}
+
+// -------------------------------------------------------------------------
+template< class _TInputImage, class _TOutputImage, class _TMarksInterface, class _TSeedsInterface >
+void
+fpa::Image::Algorithm< _TInputImage, _TOutputImage, _TMarksInterface, _TSeedsInterface >::
+_ConfigureOutput( const TOutputValue& v )
+{
+ 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( v );
+
+ TMarks* 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( TFrontId( 0 ) );
+}
+
+// -------------------------------------------------------------------------
+template< class _TInputImage, class _TOutputImage, class _TMarksInterface, class _TSeedsInterface >
+typename
+fpa::Image::Algorithm< _TInputImage, _TOutputImage, _TMarksInterface, _TSeedsInterface >::
+TNeighborhood fpa::Image::Algorithm< _TInputImage, _TOutputImage, _TMarksInterface, _TSeedsInterface >::
+_GetNeighbors( const TVertex& v ) const
+{
+ typename TInputImage::RegionType region =
+ this->GetInput( )->GetRequestedRegion( );
+ TNeighborhood neighborhood;
+ if( this->m_NeigborhoodOrder != 1 )
+ {
+ // TODO
+ }
+ else
+ {
+ for( unsigned int d = 0; d < TInputImage::ImageDimension; ++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
+
+ } // fi
+ return( neighborhood );
+}
+
+// -------------------------------------------------------------------------
+template< class _TInputImage, class _TOutputImage, class _TMarksInterface, class _TSeedsInterface >
+typename
+fpa::Image::Algorithm< _TInputImage, _TOutputImage, _TMarksInterface, _TSeedsInterface >::
+TInputValue
+fpa::Image::Algorithm< _TInputImage, _TOutputImage, _TMarksInterface, _TSeedsInterface >::
+_GetInputValue( const TVertex& v ) const
+{
+ return( this->GetInput( )->GetPixel( v ) );
+}
+
+// -------------------------------------------------------------------------
+template< class _TInputImage, class _TOutputImage, class _TMarksInterface, class _TSeedsInterface >
+typename
+fpa::Image::Algorithm< _TInputImage, _TOutputImage, _TMarksInterface, _TSeedsInterface >::
+TOutputValue fpa::Image::Algorithm< _TInputImage, _TOutputImage, _TMarksInterface, _TSeedsInterface >::
+_GetOutputValue( const TVertex& v ) const
+{
+ return( this->GetOutput( )->GetPixel( v ) );
+}
+
+// -------------------------------------------------------------------------
+template< class _TInputImage, class _TOutputImage, class _TMarksInterface, class _TSeedsInterface >
+void
+fpa::Image::Algorithm< _TInputImage, _TOutputImage, _TMarksInterface, _TSeedsInterface >::
+_UpdateOutputValue( const TNode& n )
+{
+ this->GetOutput( )->SetPixel( n.Vertex, n.Value );
+}
+
+// -------------------------------------------------------------------------
+template< class _TInputImage, class _TOutputImage, class _TMarksInterface, class _TSeedsInterface >
+bool
+fpa::Image::Algorithm< _TInputImage, _TOutputImage, _TMarksInterface, _TSeedsInterface >::
+_IsMarked( const TVertex& v ) const
+{
+ return( this->GetMarks( )->GetPixel( v ) > 0 );
+}
+
+// -------------------------------------------------------------------------
+template< class _TInputImage, class _TOutputImage, class _TMarksInterface, class _TSeedsInterface >
+unsigned long
+fpa::Image::Algorithm< _TInputImage, _TOutputImage, _TMarksInterface, _TSeedsInterface >::
+_GetMark( const TVertex& v ) const
+{
+ return( ( unsigned long )( this->GetMarks( )->GetPixel( v ) ) );
+}
+
+// -------------------------------------------------------------------------
+template< class _TInputImage, class _TOutputImage, class _TMarksInterface, class _TSeedsInterface >
+bool
+fpa::Image::Algorithm< _TInputImage, _TOutputImage, _TMarksInterface, _TSeedsInterface >::
+_Mark( const TVertex& v, unsigned long frontId )
+{
+ this->GetMarks( )->SetPixel( v, TFrontId( frontId ) );
+ return( true );
+}
+
+#endif // __fpa__Image__Algorithm__hxx__
+
+// eof - $RCSfile$
--- /dev/null
+// =========================================================================
+// @author Leonardo Florez Valencia
+// @email florez-l@javeriana.edu.co
+// =========================================================================
+
+#ifndef __fpa__Image__Dijkstra__h__
+#define __fpa__Image__Dijkstra__h__
+
+#include <fpa/Base/Dijkstra.h>
+#include <fpa/Base/MarksInterfaceWithCollisions.h>
+#include <fpa/Base/SeedsInterface.h>
+#include <fpa/Image/Algorithm.h>
+#include <fpa/Image/MinimumSpanningTree.h>
+#include <fpa/Image/Functors/Dijkstra/Identity.h>
+
+namespace fpa
+{
+ namespace Image
+ {
+ /**
+ */
+ template< class _TInputImage, class _TOutputImage, class _TFrontId = unsigned char >
+ class Dijkstra
+ : public fpa::Base::Dijkstra< fpa::Image::Algorithm< _TInputImage, _TOutputImage, fpa::Base::MarksInterfaceWithCollisions< typename _TInputImage::IndexType >, fpa::Base::SeedsInterface< typename _TInputImage::IndexType, typename _TInputImage::PixelType, typename _TOutputImage::PixelType, _TFrontId, typename _TInputImage::IndexType::LexicographicCompare > >, fpa::Image::MinimumSpanningTree< _TInputImage::ImageDimension > >
+ {
+ public:
+ typedef _TInputImage TInputImage;
+ typedef _TOutputImage TOutputImage;
+ typedef _TFrontId TFrontId;
+
+ typedef typename TInputImage::IndexType TVertex;
+ typedef typename TVertex::LexicographicCompare TVertexCompare;
+ typedef typename TInputImage::PixelType TInputValue;
+ typedef typename TOutputImage::PixelType TOutputValue;
+
+ typedef fpa::Base::MarksInterfaceWithCollisions< TVertex > TMarksInterface;
+ typedef fpa::Base::SeedsInterface< TVertex, TInputValue, TOutputValue, TFrontId, TVertexCompare > TSeedsInterface;
+ typedef fpa::Image::Algorithm< TInputImage, TOutputImage, TMarksInterface, TSeedsInterface > TAlgorithm;
+ typedef fpa::Image::MinimumSpanningTree< TInputImage::ImageDimension > TMST;
+
+ typedef Dijkstra Self;
+ typedef fpa::Base::Dijkstra< TAlgorithm, TMST > Superclass;
+ typedef itk::SmartPointer< Self > Pointer;
+ typedef itk::SmartPointer< const Self > ConstPointer;
+
+ typedef fpa::Image::Functors::Dijkstra::Function< TInputImage, TOutputValue > TWeightFunction;
+
+ public:
+ itkNewMacro( Self );
+ itkTypeMacro( fpa::Image::Dijkstra, fpa::Base::Dijkstra );
+
+ protected:
+ Dijkstra( )
+ : Superclass( )
+ {
+ typedef fpa::Image::Functors::Dijkstra::Identity< TInputImage, TOutputValue > _TDefaultFunction;
+ this->SetWeightFunction( _TDefaultFunction::New( ) );
+ }
+ virtual ~Dijkstra( )
+ {
+ }
+
+ virtual void _ConfigureOutput( const TOutputValue& v ) override
+ {
+ this->Superclass::_ConfigureOutput( v );
+ 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 TMST::PixelType zero;
+ zero.Fill( 0 );
+ mst->FillBuffer( zero );
+ }
+
+ virtual void _BeforeGenerateData( ) override
+ {
+ this->Superclass::_BeforeGenerateData( );
+ TWeightFunction* wf =
+ dynamic_cast< TWeightFunction* >( this->GetWeightFunction( ) );
+ if( wf != NULL )
+ wf->SetImage( this->GetInput( ) );
+ }
+
+ private:
+ // Purposely not implemented.
+ Dijkstra( const Self& other );
+ Self& operator=( const Self& other );
+ };
+
+ } // ecapseman
+
+} // ecapseman
+
+#endif // __fpa__Image__Dijkstra__h__
+
+// eof - $RCSfile$
--- /dev/null
+// =========================================================================
+// @author Leonardo Florez Valencia
+// @email florez-l@javeriana.edu.co
+// =========================================================================
+
+#ifndef __fpa__Image__Functors__Dijkstra__Function__h__
+#define __fpa__Image__Functors__Dijkstra__Function__h__
+
+#include <fpa/Base/Functors/Dijkstra/Function.h>
+
+namespace fpa
+{
+ namespace Image
+ {
+ namespace Functors
+ {
+ namespace Dijkstra
+ {
+ /**
+ */
+ template< class _TInputImage, class _TOutputValue >
+ class Function
+ : public fpa::Base::Functors::Dijkstra::Function< typename _TInputImage::IndexType, _TOutputValue >
+ {
+ public:
+ typedef typename _TInputImage::IndexType TVertex;
+ typedef Function Self;
+ typedef fpa::Base::Functors::Dijkstra::Function< TVertex, _TOutputValue > Superclass;
+ typedef itk::SmartPointer< Self > Pointer;
+ typedef itk::SmartPointer< const Self > ConstPointer;
+
+ public:
+ itkTypeMacro(
+ fpa::Image::Functors::Dijkstra::Function,
+ fpa::Base::Functors::Dijkstra::Function
+ );
+
+ itkGetConstObjectMacro( Image, _TInputImage );
+ itkSetConstObjectMacro( Image, _TInputImage );
+
+ protected:
+ Function( )
+ : Superclass( )
+ {
+ }
+ virtual ~Function( )
+ {
+ }
+
+ private:
+ // Purposely not implemented
+ Function( const Self& other );
+ Self& operator=( const Self& other );
+
+ protected:
+ typename _TInputImage::ConstPointer m_Image;
+ };
+
+ } // ecapseman
+
+ } // ecapseman
+
+ } // ecapseman
+
+} // ecapseman
+
+#endif // __fpa__Image__Functors__Dijkstra__Function__h__
+
+// eof - $RCSfile$
--- /dev/null
+// =========================================================================
+// @author Leonardo Florez Valencia
+// @email florez-l@javeriana.edu.co
+// =========================================================================
+
+#ifndef __fpa__Image__Functors__Dijkstra__Gaussian__h__
+#define __fpa__Image__Functors__Dijkstra__Gaussian__h__
+
+#include <cmath>
+#include <fpa/Image/Functors/Dijkstra/Function.h>
+
+namespace fpa
+{
+ namespace Image
+ {
+ namespace Functors
+ {
+ namespace Dijkstra
+ {
+ /**
+ */
+ template< class _TInputImage, class _TOutputValue >
+ class Gaussian
+ : public fpa::Image::Functors::Dijkstra::Function< _TInputImage, _TOutputValue >
+ {
+ public:
+ typedef Gaussian Self;
+ typedef fpa::Image::Functors::Dijkstra::Function< _TInputImage, _TOutputValue > Superclass;
+ typedef itk::SmartPointer< Self > Pointer;
+ typedef itk::SmartPointer< const Self > ConstPointer;
+
+ typedef typename Superclass::TVertex TVertex;
+
+ public:
+ itkNewMacro( Self );
+ itkTypeMacro(
+ fpa::Image::Functors::Dijkstra::Gaussian,
+ fpa::Image::Functors::Dijkstra::Function
+ );
+
+ public:
+ double GetAlpha( ) const
+ {
+ return( double( 1 ) - this->m_Alpha );
+ }
+ double GetBeta( ) const
+ {
+ return( std::sqrt( this->m_Beta ) );
+ }
+ void SetAlpha( const double& v )
+ {
+ this->m_Alpha = double( 1 ) - v;
+ this->Modified( );
+ }
+ void SetBeta( const double& v )
+ {
+ this->m_Beta = v * v;
+ this->Modified( );
+ }
+
+ virtual _TOutputValue Evaluate(
+ const TVertex& v, const TVertex& p
+ ) const override
+ {
+ double d = double( this->m_Image->GetPixel( v ) );
+ d -= double( this->m_Image->GetPixel( p ) );
+ d = ( d * d ) / this->m_Beta;
+ return(
+ _TOutputValue( double( 1 ) - ( this->m_Alpha * std::exp( -d ) ) )
+ );
+ }
+
+ 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__Image__Functors__Dijkstra__Gaussian__h__
+
+// eof - $RCSfile$
--- /dev/null
+// =========================================================================
+// @author Leonardo Florez Valencia
+// @email florez-l@javeriana.edu.co
+// =========================================================================
+
+#ifndef __fpa__Image__Functors__Dijkstra__Identity__h__
+#define __fpa__Image__Functors__Dijkstra__Identity__h__
+
+#include <fpa/Image/Functors/Dijkstra/Function.h>
+
+namespace fpa
+{
+ namespace Image
+ {
+ namespace Functors
+ {
+ namespace Dijkstra
+ {
+ /**
+ */
+ template< class _TInputImage, class _TOutputValue >
+ class Identity
+ : public fpa::Image::Functors::Dijkstra::Function< _TInputImage, _TOutputValue >
+ {
+ public:
+ typedef Identity Self;
+ typedef fpa::Image::Functors::Dijkstra::Function< _TInputImage, _TOutputValue > Superclass;
+ typedef itk::SmartPointer< Self > Pointer;
+ typedef itk::SmartPointer< const Self > ConstPointer;
+
+ typedef typename Superclass::TVertex TVertex;
+
+ public:
+ itkNewMacro( Self );
+ itkTypeMacro(
+ fpa::Image::Functors::Dijkstra::Identity,
+ fpa::Image::Functors::Dijkstra::Function
+ );
+
+ public:
+ virtual _TOutputValue Evaluate(
+ const TVertex& v, const TVertex& p
+ ) const override
+ {
+ return( _TOutputValue( this->m_Image->GetPixel( v ) ) );
+ }
+
+ protected:
+ Identity( )
+ : Superclass( )
+ {
+ }
+ virtual ~Identity( )
+ {
+ }
+
+ private:
+ // Purposely not implemented
+ Identity( const Self& other );
+ Self& operator=( const Self& other );
+ };
+
+ } // ecapseman
+
+ } // ecapseman
+
+ } // ecapseman
+
+} // ecapseman
+
+#endif // __fpa__Image__Functors__Dijkstra__Identity__h__
+
+// eof - $RCSfile$
--- /dev/null
+// =========================================================================
+// @author Leonardo Florez Valencia
+// @email florez-l@javeriana.edu.co
+// =========================================================================
+
+#ifndef __fpa__Image__Functors__Dijkstra__Invert__h__
+#define __fpa__Image__Functors__Dijkstra__Invert__h__
+
+#include <cmath>
+#include <fpa/Image/Functors/Dijkstra/Function.h>
+
+namespace fpa
+{
+ namespace Image
+ {
+ namespace Functors
+ {
+ namespace Dijkstra
+ {
+ /**
+ */
+ template< class _TInputImage, class _TOutputValue >
+ class Invert
+ : public fpa::Image::Functors::Dijkstra::Function< _TInputImage, _TOutputValue >
+ {
+ public:
+ typedef Invert Self;
+ typedef fpa::Image::Functors::Dijkstra::Function< _TInputImage, _TOutputValue > Superclass;
+ typedef itk::SmartPointer< Self > Pointer;
+ typedef itk::SmartPointer< const Self > ConstPointer;
+
+ typedef typename Superclass::TVertex TVertex;
+
+ public:
+ itkNewMacro( Self );
+ itkTypeMacro(
+ fpa::Image::Functors::Dijkstra::Invert,
+ fpa::Image::Functors::Dijkstra::Function
+ );
+
+ itkGetConstMacro( Alpha, double );
+ itkGetConstMacro( Beta, double );
+
+ itkSetMacro( Alpha, double );
+ itkSetMacro( Beta, double );
+
+ public:
+ virtual _TOutputValue Evaluate(
+ const TVertex& v, const TVertex& p
+ ) const override
+ {
+ double a = double( this->m_Image->GetPixel( 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( _TOutputValue( 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
+
+} // ecapseman
+
+#endif // __fpa__Image__Functors__Dijkstra__Invert__h__
+
+// eof - $RCSfile$
--- /dev/null
+// =========================================================================
+// @author Leonardo Florez Valencia
+// @email florez-l@javeriana.edu.co
+// =========================================================================
+
+#ifndef __fpa__Image__LabelledSeedsInterface__h__
+#define __fpa__Image__LabelledSeedsInterface__h__
+
+#include <fpa/Base/SeedsInterface.h>
+
+#include <itkImage.h>
+
+namespace fpa
+{
+ namespace Image
+ {
+ /**
+ */
+ template< class _TVertex, class _TInputValue, class _TOutputValue, class _TFrontId, class _TCompare = std::greater< _TVertex > >
+ class LabelledSeedsInterface
+ : public fpa::Base::SeedsInterface< _TVertex, _TInputValue, _TOutputValue, _TFrontId, _TCompare >
+ {
+ public:
+ typedef _TVertex TVertex;
+ typedef _TInputValue TInputValue;
+ typedef _TOutputValue TOutputValue;
+ typedef _TFrontId TFrontId;
+ typedef _TCompare TCompare;
+ typedef LabelledSeedsInterface Self;
+ typedef fpa::Base::SeedsInterface< TVertex, TInputValue, TOutputValue, TFrontId, TCompare > Superclass;
+
+ typedef typename Superclass::TNode TNode;
+ typedef typename Superclass::TNodeCompare TNodeCompare;
+ typedef typename Superclass::TSeeds TSeeds;
+
+ typedef itk::Image< TFrontId, TVertex::Dimension > TLabelImage;
+
+ public:
+ virtual void AddSeed( const TVertex& seed ) override;
+
+ const TLabelImage* GetLabels( ) const;
+ void SetLabels( const TLabelImage* image );
+
+ protected:
+ LabelledSeedsInterface( itk::ProcessObject* filter );
+ virtual ~LabelledSeedsInterface( );
+
+ protected:
+ typename TLabelImage::ConstPointer m_LabelImage;
+ };
+
+ } // ecapseman
+
+} // ecapseman
+
+#ifndef ITK_MANUAL_INSTANTIATION
+# include <fpa/Image/LabelledSeedsInterface.hxx>
+#endif // ITK_MANUAL_INSTANTIATION
+
+#endif // __fpa__Image__LabelledSeedsInterface__h__
+
+// eof - $RCSfile$
--- /dev/null
+// =========================================================================
+// @author Leonardo Florez Valencia
+// @email florez-l@javeriana.edu.co
+// =========================================================================
+
+#ifndef __fpa__Image__LabelledSeedsInterface__hxx__
+#define __fpa__Image__LabelledSeedsInterface__hxx__
+
+#include <sstream>
+#include <itkExceptionObject.h>
+
+// -------------------------------------------------------------------------
+template< class _TVertex, class _TInputValue, class _TOutputValue, class _TFrontId, class _TCompare >
+void
+fpa::Image::LabelledSeedsInterface< _TVertex, _TInputValue, _TOutputValue, _TFrontId, _TCompare >::
+AddSeed( const TVertex& seed )
+{
+ std::ostringstream msg;
+ msg << "itk::ERROR: fpa::Image::LabelledSeedsInterface (" << this
+ << "): \"AddSeed( const TVertex& seed )\" is not valid for this class. "
+ << "Use \"SetLabels( TLabelImage* labels )\" instead.";
+ ::itk::ExceptionObject e(
+ __FILE__, __LINE__, msg.str( ).c_str( ), ITK_LOCATION
+ );
+ throw e;
+}
+
+// -------------------------------------------------------------------------
+template< class _TVertex, class _TInputValue, class _TOutputValue, class _TFrontId, class _TCompare >
+const typename
+fpa::Image::LabelledSeedsInterface< _TVertex, _TInputValue, _TOutputValue, _TFrontId, _TCompare >::
+TLabelImage*
+fpa::Image::LabelledSeedsInterface< _TVertex, _TInputValue, _TOutputValue, _TFrontId, _TCompare >::
+GetLabels( ) const
+{
+ return( this->m_LabelImage );
+}
+
+// -------------------------------------------------------------------------
+template< class _TVertex, class _TInputValue, class _TOutputValue, class _TFrontId, class _TCompare >
+void fpa::Image::LabelledSeedsInterface< _TVertex, _TInputValue, _TOutputValue, _TFrontId, _TCompare >::
+SetLabels( const TLabelImage* image )
+{
+ this->m_LabelImage = image;
+}
+
+// -------------------------------------------------------------------------
+template< class _TVertex, class _TInputValue, class _TOutputValue, class _TFrontId, class _TCompare >
+fpa::Image::LabelledSeedsInterface< _TVertex, _TInputValue, _TOutputValue, _TFrontId, _TCompare >::
+LabelledSeedsInterface( itk::ProcessObject* filter )
+ : Superclass( filter )
+{
+}
+
+// -------------------------------------------------------------------------
+template< class _TVertex, class _TInputValue, class _TOutputValue, class _TFrontId, class _TCompare >
+fpa::Image::LabelledSeedsInterface< _TVertex, _TInputValue, _TOutputValue, _TFrontId, _TCompare >::
+~LabelledSeedsInterface( )
+{
+}
+
+#endif // __fpa__Image__LabelledSeedsInterface__hxx__
+
+// eof - $RCSfile$
--- /dev/null
+// =========================================================================
+// @author Leonardo Florez Valencia
+// @email florez-l@javeriana.edu.co
+// =========================================================================
+
+#ifndef __fpa__Image__MinimumSpanningTree__h__
+#define __fpa__Image__MinimumSpanningTree__h__
+
+#include <fpa/Base/MinimumSpanningTree.h>
+#include <itkImage.h>
+
+namespace fpa
+{
+ namespace Image
+ {
+ /**
+ */
+ template< unsigned int _VDim >
+ class MinimumSpanningTree
+ : public fpa::Base::MinimumSpanningTree< itk::Index< _VDim >, itk::Image< itk::Offset< _VDim >, _VDim > >
+ {
+ public:
+ typedef itk::Index< _VDim > TVertex;
+ typedef itk::Image< itk::Offset< _VDim >, _VDim > TBaseImage;
+
+ typedef MinimumSpanningTree Self;
+ typedef itk::SmartPointer< Self > Pointer;
+ typedef itk::SmartPointer< const Self > ConstPointer;
+ typedef fpa::Base::MinimumSpanningTree< TVertex, TBaseImage > Superclass;
+
+ typedef typename Superclass::TCollision TCollision;
+ typedef typename Superclass::TCollisionsRow TCollisionsRow;
+ typedef typename Superclass::TCollisions TCollisions;
+ typedef typename Superclass::TVertices TVertices;
+
+ public:
+ itkNewMacro( Self );
+ itkTypeMacro(
+ fpa::Image::MinimumSpanningTree,
+ fpa::Base::MinimumSpanningTree
+ );
+
+ public:
+ virtual TVertex GetParent( const TVertex& v ) const override
+ {
+ return( v + this->GetPixel( v ) );
+ }
+ virtual void SetParent( const TVertex& v, const TVertex& p ) override
+ {
+ this->SetPixel( v, p - v );
+ }
+
+ protected:
+ MinimumSpanningTree( )
+ : Superclass( )
+ { }
+ virtual ~MinimumSpanningTree( )
+ { }
+
+ private:
+ MinimumSpanningTree( const Self& other );
+ Self& operator=( const Self& other );
+ };
+
+ } // ecapseman
+
+} // ecapseman
+
+#endif // __fpa__Image__MinimumSpanningTree__h__
+
+// eof - $RCSfile$
--- /dev/null
+// =========================================================================
+// @author Leonardo Florez Valencia
+// @email florez-l@javeriana.edu.co
+// =========================================================================
+
+#ifndef __fpa__Image__PathsToImageFilter__h__
+#define __fpa__Image__PathsToImageFilter__h__
+
+#include <itkRGBAPixel.h>
+#include <itkImageToImageFilter.h>
+#include <vector>
+
+namespace fpa
+{
+ namespace Image
+ {
+ /**
+ */
+ template< class _TMST, class _TOutputPixelValue >
+ class PathsToImageFilter
+ : public itk::ImageToImageFilter< _TMST, itk::Image< itk::RGBAPixel< _TOutputPixelValue >, _TMST::ImageDimension > >
+ {
+ public:
+ typedef _TMST TMST;
+ typedef _TOutputPixelValue TOutputPixelValue;
+ typedef itk::RGBAPixel< TOutputPixelValue > TOutputPixel;
+ typedef itk::Image< TOutputPixel, TMST::ImageDimension > TOutputImage;
+
+ typedef PathsToImageFilter Self;
+ typedef itk::SmartPointer< Self > Pointer;
+ typedef itk::SmartPointer< const Self > ConstPointer;
+ typedef itk::ImageToImageFilter< TMST, TOutputImage > Superclass;
+
+ typedef typename TMST::IndexType TIndex;
+ struct TPathData
+ {
+ TIndex Start;
+ TIndex End;
+ TOutputPixelValue Red;
+ TOutputPixelValue Green;
+ TOutputPixelValue Blue;
+ };
+ typedef std::vector< TPathData > TPaths;
+
+ public:
+ itkNewMacro( Self );
+ itkTypeMacro(
+ fpa::Image::PathsToImageFilter,
+ itk::ImageToImageFilter
+ );
+
+ public:
+ void AddPath(
+ const TIndex& start, const TIndex& end,
+ const TOutputPixelValue& r = TOutputPixelValue( 1 ),
+ const TOutputPixelValue& g = TOutputPixelValue( 0 ),
+ const TOutputPixelValue& b = TOutputPixelValue( 0 )
+ );
+
+ protected:
+ PathsToImageFilter( );
+ virtual ~PathsToImageFilter( );
+
+ virtual void GenerateData( ) override;
+
+ private:
+ PathsToImageFilter( const Self& other );
+ Self& operator=( const Self& other );
+
+ protected:
+ TPaths m_Paths;
+ };
+
+ } // ecapseman
+
+} // ecapseman
+
+#ifndef ITK_MANUAL_INSTANTIATION
+# include <fpa/Image/PathsToImageFilter.hxx>
+#endif // ITK_MANUAL_INSTANTIATION
+
+#endif // __fpa__Image__PathsToImageFilter__h__
+
+// eof - $RCSfile$
--- /dev/null
+// =========================================================================
+// @author Leonardo Florez Valencia
+// @email florez-l@javeriana.edu.co
+// =========================================================================
+
+#ifndef __fpa__Image__PathsToImageFilter__hxx__
+#define __fpa__Image__PathsToImageFilter__hxx__
+
+// -------------------------------------------------------------------------
+template< class _TMST, class _TOutputPixelValue >
+void fpa::Image::PathsToImageFilter< _TMST, _TOutputPixelValue >::
+AddPath(
+ const TIndex& start, const TIndex& end,
+ const TOutputPixelValue& r,
+ const TOutputPixelValue& g,
+ const TOutputPixelValue& b
+ )
+{
+ if( start != end )
+ {
+ TPathData d;
+ d.Start = start;
+ d.End = end;
+ d.Red = r;
+ d.Green = g;
+ d.Blue = b;
+ this->m_Paths.push_back( d );
+ this->Modified( );
+
+ } // fi
+}
+
+// -------------------------------------------------------------------------
+template< class _TMST, class _TOutputPixelValue >
+fpa::Image::PathsToImageFilter< _TMST, _TOutputPixelValue >::
+PathsToImageFilter( )
+ : Superclass( )
+{
+}
+
+// -------------------------------------------------------------------------
+template< class _TMST, class _TOutputPixelValue >
+fpa::Image::PathsToImageFilter< _TMST, _TOutputPixelValue >::
+~PathsToImageFilter( )
+{
+}
+
+// -------------------------------------------------------------------------
+template< class _TMST, class _TOutputPixelValue >
+void fpa::Image::PathsToImageFilter< _TMST, _TOutputPixelValue >::
+GenerateData( )
+{
+ TOutputPixel color;
+ color.Fill( 0 );
+
+ const TMST* mst = this->GetInput( );
+ TOutputImage* output = this->GetOutput( );
+ output->SetBufferedRegion( mst->GetBufferedRegion( ) );
+ output->Allocate( );
+ output->FillBuffer( color );
+
+ typename TPaths::const_iterator d = this->m_Paths.begin( );
+ for( ; d != this->m_Paths.end( ); ++d )
+ {
+ typename TMST::TVertices path = mst->GetPath( d->Start, d->End );
+ color[ 0 ] = d->Red;
+ color[ 1 ] = d->Green;
+ color[ 2 ] = d->Blue;
+ color[ 3 ] = std::numeric_limits< TOutputPixelValue >::max( );
+ typename TMST::TVertices::const_iterator i = path.begin( );
+ for( ; i != path.end( ); ++i )
+ output->SetPixel( *i, color );
+
+ } // rof
+}
+
+#endif // __fpa__Image__PathsToImageFilter__hxx__
+
+// eof - $RCSfile$
--- /dev/null
+// =========================================================================
+// @author Leonardo Florez Valencia
+// @email florez-l@javeriana.edu.co
+// =========================================================================
+
+#ifndef __fpa__Image__PolyLineParametricPath__h__
+#define __fpa__Image__PolyLineParametricPath__h__
+
+#include <itkPolyLineParametricPath.h>
+#include <itkImageBase.h>
+
+namespace fpa
+{
+ 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;
+
+ 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( ) );
+ }
+
+ 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
+
+#ifndef ITK_MANUAL_INSTANTIATION
+# include <fpa/Image/PolyLineParametricPath.hxx>
+#endif // ITK_MANUAL_INSTANTIATION
+
+#endif // __fpa__Image__PolyLineParametricPath__h__
+
+// eof - $RCSfile$
--- /dev/null
+// =========================================================================
+// @author Leonardo Florez Valencia
+// @email florez-l@javeriana.edu.co
+// =========================================================================
+
+#ifndef __fpa__Image__PolyLineParametricPath__hxx__
+#define __fpa__Image__PolyLineParametricPath__hxx__
+
+#include <itkMath.h>
+#include <itkNumericTraits.h>
+
+// -------------------------------------------------------------------------
+template< unsigned int _VDim >
+unsigned long fpa::Image::PolyLineParametricPath< _VDim >::
+GetSize( ) const
+{
+ return( this->GetVertexList( )->Size( ) );
+}
+
+// -------------------------------------------------------------------------
+template< unsigned int _VDim >
+typename fpa::Image::PolyLineParametricPath< _VDim >::
+TContinuousIndex
+fpa::Image::PolyLineParametricPath< _VDim >::
+GetContinuousVertex( unsigned long i ) const
+{
+ return( this->GetVertexList( )->GetElement( i ) );
+}
+
+// -------------------------------------------------------------------------
+template< unsigned int _VDim >
+typename fpa::Image::PolyLineParametricPath< _VDim >::
+TIndex fpa::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::Image::PolyLineParametricPath< _VDim >::
+TPoint fpa::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::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::Image::PolyLineParametricPath< _VDim >::
+SetSpacing( const double spac[ _VDim ] )
+{
+ this->SetSpacing( TSpacing( spac ) );
+}
+
+// -------------------------------------------------------------------------
+template< unsigned int _VDim >
+void fpa::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::Image::PolyLineParametricPath< _VDim >::
+SetOrigin( const double ori[ _VDim ] )
+{
+ this->SetOrigin( TPoint( ori ) );
+}
+
+// -------------------------------------------------------------------------
+template< unsigned int _VDim >
+void fpa::Image::PolyLineParametricPath< _VDim >::
+SetOrigin( const float ori[ _VDim ] )
+{
+ this->SetOrigin( TPoint( ori ) );
+}
+
+// -------------------------------------------------------------------------
+template< unsigned int _VDim >
+void fpa::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 >
+fpa::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::Image::PolyLineParametricPath< _VDim >::
+~PolyLineParametricPath( )
+{
+}
+
+// -------------------------------------------------------------------------
+template< unsigned int _VDim >
+void fpa::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__Image__PolyLineParametricPath__hxx__
+
+// eof - $RCSfile$
--- /dev/null
+// =========================================================================
+// @author Leonardo Florez Valencia
+// @email florez-l@javeriana.edu.co
+// =========================================================================
+
+#ifndef __fpa__Image__RandomWalker__h__
+#define __fpa__Image__RandomWalker__h__
+
+#include <itkImage.h>
+
+#include <fpa/Base/DijkstraBase.h>
+#include <fpa/Base/MarksInterface.h>
+#include <fpa/Image/Algorithm.h>
+#include <fpa/Image/LabelledSeedsInterface.h>
+#include <fpa/Image/Functors/Dijkstra/Function.h>
+
+namespace fpa
+{
+ namespace Image
+ {
+ /**
+ */
+ template< class _TInputImage, class _TLabelImage, class _TScalar >
+ class RandomWalker
+ : public fpa::Base::DijkstraBase< fpa::Image::Algorithm< _TInputImage, itk::Image< _TScalar, _TInputImage::ImageDimension >, fpa::Base::MarksInterface< typename _TInputImage::IndexType >, fpa::Image::LabelledSeedsInterface< typename _TInputImage::IndexType, typename _TInputImage::PixelType, _TScalar, typename _TLabelImage::PixelType, typename _TInputImage::IndexType::LexicographicCompare > > >
+ {
+ public:
+ typedef _TInputImage TInputImage;
+ typedef _TLabelImage TLabelImage;
+ typedef _TScalar TScalar;
+ typedef typename TInputImage::IndexType TVertex;
+ typedef typename TVertex::LexicographicCompare TVertexCompare;
+ typedef typename TInputImage::PixelType TInputValue;
+ typedef typename TLabelImage::PixelType TFrontId;
+
+ typedef itk::Image< TScalar, _TInputImage::ImageDimension > TOutputImage;
+ typedef fpa::Base::MarksInterface< TVertex > TMarksInterface;
+ typedef fpa::Image::LabelledSeedsInterface< TVertex, TInputValue, _TScalar, TFrontId, TVertexCompare > TSeedsInterface;
+ typedef fpa::Image::Algorithm< _TInputImage, TOutputImage, TMarksInterface, TSeedsInterface > TAlgorithm;
+
+ typedef RandomWalker Self;
+ typedef fpa::Base::DijkstraBase< TAlgorithm > Superclass;
+ typedef itk::SmartPointer< Self > Pointer;
+ typedef itk::SmartPointer< const Self > ConstPointer;
+
+ typedef fpa::Image::Functors::Dijkstra::Function< TInputImage, TScalar > TWeightFunction;
+
+ public:
+ itkNewMacro( Self );
+ itkTypeMacro( fpa::Image::RandomWalker, fpa::Base::RandomWalker );
+
+ public:
+ virtual itk::ModifiedTimeType GetMTime( ) const override;
+
+ protected:
+ RandomWalker( );
+ virtual ~RandomWalker( );
+
+ virtual void _BeforeGenerateData( ) override;
+ virtual void _QueueInit( ) override;
+
+ private:
+ // Purposely not implemented.
+ RandomWalker( const Self& other );
+ Self& operator=( const Self& other );
+ };
+
+ } // ecapseman
+
+} // ecapseman
+
+#ifndef ITK_MANUAL_INSTANTIATION
+# include <fpa/Image/RandomWalker.hxx>
+#endif // ITK_MANUAL_INSTANTIATION
+
+#endif // __fpa__Image__RandomWalker__h__
+
+// eof - $RCSfile$
--- /dev/null
+// =========================================================================
+// @author Leonardo Florez Valencia
+// @email florez-l@javeriana.edu.co
+// =========================================================================
+
+#ifndef __fpa__Image__RandomWalker__hxx__
+#define __fpa__Image__RandomWalker__hxx__
+
+#include <sstream>
+
+#include <itkImageRegionConstIteratorWithIndex.h>
+#include <itkExceptionObject.h>
+
+#include <fpa/Image/Functors/Dijkstra/Gaussian.h>
+
+// -------------------------------------------------------------------------
+template< class _TInputImage, class _TLabelImage, class _TScalar >
+itk::ModifiedTimeType
+fpa::Image::RandomWalker< _TInputImage, _TLabelImage, _TScalar >::
+GetMTime( ) const
+{
+ const TLabelImage* labels = this->GetLabels( );
+ itk::ModifiedTimeType t = this->Superclass::GetMTime( );
+ if( labels != NULL )
+ {
+ itk::ModifiedTimeType q = labels->GetMTime( );
+ t = ( q < t )? q: t;
+
+ } // fi
+ return( t );
+}
+
+// -------------------------------------------------------------------------
+template< class _TInputImage, class _TLabelImage, class _TScalar >
+fpa::Image::RandomWalker< _TInputImage, _TLabelImage, _TScalar >::
+RandomWalker( )
+ : Superclass( )
+{
+ typedef fpa::Image::Functors::Dijkstra::Gaussian< TInputImage, TScalar > _TDefaultFunction;
+ this->SetWeightFunction( _TDefaultFunction::New( ) );
+}
+
+// -------------------------------------------------------------------------
+template< class _TInputImage, class _TLabelImage, class _TScalar >
+fpa::Image::RandomWalker< _TInputImage, _TLabelImage, _TScalar >::
+~RandomWalker( )
+{
+}
+
+// -------------------------------------------------------------------------
+template< class _TInputImage, class _TLabelImage, class _TScalar >
+void fpa::Image::RandomWalker< _TInputImage, _TLabelImage, _TScalar >::
+_BeforeGenerateData( )
+{
+ this->Superclass::_BeforeGenerateData( );
+ TWeightFunction* wf =
+ dynamic_cast< TWeightFunction* >( this->GetWeightFunction( ) );
+ if( wf != NULL )
+ wf->SetImage( this->GetInput( ) );
+}
+
+// -------------------------------------------------------------------------
+template< class _TInputImage, class _TLabelImage, class _TScalar >
+void fpa::Image::RandomWalker< _TInputImage, _TLabelImage, _TScalar >::
+_QueueInit( )
+{
+ this->m_Seeds.clear( );
+ const TLabelImage* lbl = this->GetLabels( );
+ if( lbl == NULL )
+ {
+ std::ostringstream msg;
+ msg << "itk::ERROR: fpa::Image::RandomWalker (" << this
+ << "): Labelled image not defined.";
+ ::itk::ExceptionObject e(
+ __FILE__, __LINE__, msg.str( ).c_str( ), ITK_LOCATION
+ );
+ throw e;
+
+ } // fi
+
+ // Iterate over labels
+ typename TLabelImage::RegionType reg = lbl->GetRequestedRegion( );
+ itk::ImageRegionConstIteratorWithIndex< TLabelImage > lIt( lbl, reg );
+ for( lIt.GoToBegin( ); !lIt.IsAtEnd( ); ++lIt )
+ {
+ if( lIt.Get( ) > 0 )
+ {
+ bool is_seed = false;
+ for( unsigned int d = 0; d < TLabelImage::ImageDimension; ++d )
+ {
+ for( int s = -1; s <= 1; s += 2 )
+ {
+ TVertex neigh = lIt.GetIndex( );
+ neigh[ d ] += s;
+ is_seed |= ( lbl->GetPixel( neigh ) == 0 );
+
+ } // rof
+
+ } // rof
+
+ typename TSeedsInterface::TNode node;
+ node.Vertex = lIt.GetIndex( );
+ node.Parent = lIt.GetIndex( );
+ node.FrontId = lIt.Get( );
+ node.Value = TScalar( 0 );
+ if( !is_seed )
+ {
+ this->_Mark( lIt.GetIndex( ), lIt.Get( ) );
+ this->_UpdateOutputValue( node );
+ }
+ else
+ this->m_Seeds.insert( node );
+
+ } // fi
+
+ } // rof
+
+ // Ok, finish initialization
+ this->Superclass::_QueueInit( );
+}
+
+#endif // __fpa__Image__RandomWalker__hxx__
+
+// eof - $RCSfile$
--- /dev/null
+// =========================================================================
+// @author Leonardo Florez Valencia
+// @email florez-l@javeriana.edu.co
+// =========================================================================
+
+#ifndef __fpa__Image__RegionGrow__h__
+#define __fpa__Image__RegionGrow__h__
+
+#include <fpa/Base/RegionGrow.h>
+#include <fpa/Base/MarksInterfaceWithCollisions.h>
+#include <fpa/Base/SeedsInterface.h>
+#include <fpa/Image/Algorithm.h>
+
+namespace fpa
+{
+ namespace Image
+ {
+ /**
+ */
+ template< class _TInputImage, class _TOutputImage, class _TFrontId = unsigned char >
+ class RegionGrow
+ : public fpa::Base::RegionGrow< fpa::Image::Algorithm< _TInputImage, _TOutputImage, fpa::Base::MarksInterfaceWithCollisions< typename _TInputImage::IndexType >, fpa::Base::SeedsInterface< typename _TInputImage::IndexType, typename _TInputImage::PixelType, typename _TOutputImage::PixelType, _TFrontId, typename _TInputImage::IndexType::LexicographicCompare > > >
+ {
+ public:
+ typedef _TInputImage TInputImage;
+ typedef _TOutputImage TOutputImage;
+ typedef _TFrontId TFrontId;
+
+ typedef typename TInputImage::IndexType TVertex;
+ typedef typename TVertex::LexicographicCompare TVertexCompare;
+ typedef typename TInputImage::PixelType TInputValue;
+ typedef typename TOutputImage::PixelType TOutputValue;
+
+ typedef fpa::Base::MarksInterfaceWithCollisions< TVertex > TMarksInterface;
+ typedef fpa::Base::SeedsInterface< TVertex, TInputValue, TOutputValue, TFrontId, TVertexCompare > TSeedsInterface;
+ typedef fpa::Image::Algorithm< TInputImage, TOutputImage, TMarksInterface, TSeedsInterface > TAlgorithm;
+
+ typedef RegionGrow Self;
+ typedef fpa::Base::RegionGrow< TAlgorithm > Superclass;
+ typedef itk::SmartPointer< Self > Pointer;
+ typedef itk::SmartPointer< const Self > ConstPointer;
+
+ public:
+ itkNewMacro( Self );
+ itkTypeMacro( fpa::Image::RegionGrow, fpa::Base::RegionGrow );
+
+ protected:
+ RegionGrow( )
+ : Superclass( )
+ {
+ }
+ virtual ~RegionGrow( )
+ {
+ }
+
+ private:
+ // Purposely not implemented.
+ RegionGrow( const Self& other );
+ Self& operator=( const Self& other );
+ };
+
+ } // ecapseman
+
+} // ecapseman
+
+#endif // __fpa__Image__RegionGrow__h__
+
+// eof - $RCSfile$
--- /dev/null
+// =========================================================================
+// @author Leonardo Florez Valencia
+// @email florez-l@javeriana.edu.co
+// =========================================================================
+
+#ifndef __fpa__Image__Skeleton__h__
+#define __fpa__Image__Skeleton__h__
+
+#include <vector>
+#include <fpa/Base/Graph.h>
+#include <fpa/Image/PolyLineParametricPath.h>
+
+namespace fpa
+{
+ namespace Image
+ {
+ /**
+ */
+ template< unsigned int _VDim >
+ class Skeleton
+ : public fpa::Base::Graph< typename fpa::Image::PolyLineParametricPath< _VDim >::TIndex, typename fpa::Image::PolyLineParametricPath< _VDim >::Pointer, typename fpa::Image::PolyLineParametricPath< _VDim >::TIndex, typename fpa::Image::PolyLineParametricPath< _VDim >::TIndex::LexicographicCompare >
+ {
+ public:
+ typedef fpa::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::Base::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
+
+#ifndef ITK_MANUAL_INSTANTIATION
+# include <fpa/Image/Skeleton.hxx>
+#endif // ITK_MANUAL_INSTANTIATION
+
+#endif // __fpa__Image__Skeleton__h__
+
+// eof - $RCSfile$
--- /dev/null
+// =========================================================================
+// @author Leonardo Florez Valencia
+// @email florez-l@javeriana.edu.co
+// =========================================================================
+
+#ifndef __fpa__Image__Skeleton__hxx__
+#define __fpa__Image__Skeleton__hxx__
+
+// -------------------------------------------------------------------------
+template< unsigned int _VDim >
+void fpa::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 );
+ // TODO: this->Modified( );
+}
+
+// -------------------------------------------------------------------------
+template< unsigned int _VDim >
+const typename fpa::Image::Skeleton< _VDim >::
+TPath* fpa::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::Image::Skeleton< _VDim >::TIndex >
+fpa::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::Image::Skeleton< _VDim >::TIndex >
+fpa::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::Image::Skeleton< _VDim >::
+Skeleton( )
+ : Superclass( )
+{
+}
+
+// -------------------------------------------------------------------------
+template< unsigned int _VDim >
+fpa::Image::Skeleton< _VDim >::
+~Skeleton( )
+{
+}
+
+#endif // __fpa__Image__Skeleton__hxx__
+
+// eof - $RCSfile$
--- /dev/null
+// =========================================================================
+// @author Leonardo Florez Valencia
+// @email florez-l@javeriana.edu.co
+// =========================================================================
+
+#ifndef __fpa__Image__SkeletonFilter__h__
+#define __fpa__Image__SkeletonFilter__h__
+
+#include <itkProcessObject.h>
+#include <itkSignedMaurerDistanceMapImageFilter.h>
+#include <fpa/Image/Dijkstra.h>
+#include <fpa/Image/Skeleton.h>
+
+/*
+ #include <functional>
+ #include <map>
+
+
+ #include <fpa/Image/MinimumSpanningTree.h>
+
+ #include <itkMinimumMaximumImageCalculator.h>
+ #include <fpa/Image/Functors/Dijkstra/Invert.h>
+*/
+
+namespace fpa
+{
+ namespace Image
+ {
+ /**
+ */
+ template< class _TInputImage, class _TDistanceMap = itk::SignedMaurerDistanceMapImageFilter< _TInputImage, itk::Image< double, _TInputImage::ImageDimension > > >
+ class SkeletonFilter
+ : public itk::ProcessObject
+ {
+ public:
+ typedef SkeletonFilter 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::Image::Skeleton< Self::Dimension > TSkeleton;
+
+ protected:
+ typedef std::multimap< TScalar, TIndex > _TSkeletonQueue;
+
+ /**
+ */
+ class _TDijkstra
+ : public fpa::Image::Dijkstra< TOutputImage, TOutputImage >
+ {
+ public:
+ typedef _TDijkstra Self;
+ typedef fpa::Image::Dijkstra< TOutputImage, TOutputImage > Superclass;
+ 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( const 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::SkeletonFilter, 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:
+ SkeletonFilter( );
+ virtual ~SkeletonFilter( );
+
+ 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.
+ SkeletonFilter( const Self& other );
+ Self& operator=( const Self& other );
+
+ protected:
+ typename TDistanceMap::Pointer m_DistanceMap;
+ bool m_SeedFromMaximumDistance;
+ TIndex m_Seed;
+ };
+
+ } // ecapseman
+
+} // ecapseman
+
+#ifndef ITK_MANUAL_INSTANTIATION
+# include <fpa/Image/SkeletonFilter.hxx>
+#endif // ITK_MANUAL_INSTANTIATION
+
+#endif // __fpa__Image__SkeletonFilter__h__
+
+// eof - $RCSfile$
--- /dev/null
+// =========================================================================
+// @author Leonardo Florez Valencia
+// @email florez-l@javeriana.edu.co
+// =========================================================================
+
+#ifndef __fpa__Image__SkeletonFilter__hxx__
+#define __fpa__Image__SkeletonFilter__hxx__
+
+#include <itkImage.h>
+#include <itkImageRegionIteratorWithIndex.h>
+#include <itkMinimumMaximumImageCalculator.h>
+#include <fpa/Image/Functors/Dijkstra/Invert.h>
+
+// -------------------------------------------------------------------------
+template< class _TInputImage, class _TDistanceMap >
+fpa::Image::SkeletonFilter< _TInputImage, _TDistanceMap >::_TDijkstra::
+_TDijkstra( )
+ : Superclass( )
+{
+ // Prepare weight function
+ typedef fpa::Image::Functors::Dijkstra::Invert< TOutputImage, TScalar > _TWeight;
+ typename _TWeight::Pointer weight = _TWeight::New( );
+ weight->SetAlpha( 1 );
+ weight->SetBeta( 1 );
+ this->SetWeightFunction( weight );
+}
+
+// -------------------------------------------------------------------------
+template< class _TInputImage, class _TDistanceMap >
+fpa::Image::SkeletonFilter< _TInputImage, _TDistanceMap >::_TDijkstra::
+~_TDijkstra( )
+{
+}
+
+// -------------------------------------------------------------------------
+template< class _TInputImage, class _TDistanceMap >
+void fpa::Image::SkeletonFilter< _TInputImage, _TDistanceMap >::_TDijkstra::
+_BeforeGenerateData( )
+{
+ this->Superclass::_BeforeGenerateData( );
+ this->m_SkeletonQueue.clear( );
+}
+
+// -------------------------------------------------------------------------
+template< class _TInputImage, class _TDistanceMap >
+void fpa::Image::SkeletonFilter< _TInputImage, _TDistanceMap >::_TDijkstra::
+_UpdateOutputValue( const 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::Image::SkeletonFilter< _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::Image::SkeletonFilter< _TInputImage, _TDistanceMap >::
+SetInput( TInputImage* input )
+{
+ this->Superclass::SetNthInput( 0, input );
+}
+
+// -------------------------------------------------------------------------
+template< class _TInputImage, class _TDistanceMap >
+typename fpa::Image::SkeletonFilter< _TInputImage, _TDistanceMap >::
+TInputImage* fpa::Image::SkeletonFilter< _TInputImage, _TDistanceMap >::
+GetInput( )
+{
+ return( dynamic_cast< TInputImage* >( this->Superclass::GetInput( 0 ) ) );
+}
+
+// -------------------------------------------------------------------------
+template< class _TInputImage, class _TDistanceMap >
+const typename fpa::Image::SkeletonFilter< _TInputImage, _TDistanceMap >::
+TInputImage* fpa::Image::SkeletonFilter< _TInputImage, _TDistanceMap >::
+GetInput( ) const
+{
+ return(
+ dynamic_cast< const TInputImage* >( this->Superclass::GetInput( 0 ) )
+ );
+}
+
+// -------------------------------------------------------------------------
+template< class _TInputImage, class _TDistanceMap >
+typename fpa::Image::SkeletonFilter< _TInputImage, _TDistanceMap >::
+TSkeleton* fpa::Image::SkeletonFilter< _TInputImage, _TDistanceMap >::
+GetOutput( )
+{
+ return( dynamic_cast< TSkeleton* >( this->Superclass::GetOutput( 0 ) ) );
+}
+
+// -------------------------------------------------------------------------
+template< class _TInputImage, class _TDistanceMap >
+const typename fpa::Image::SkeletonFilter< _TInputImage, _TDistanceMap >::
+TSkeleton* fpa::Image::SkeletonFilter< _TInputImage, _TDistanceMap >::
+GetOutput( ) const
+{
+ return(
+ dynamic_cast< const TSkeleton* >( this->Superclass::GetOutput( 0 ) )
+ );
+}
+
+// -------------------------------------------------------------------------
+template< class _TInputImage, class _TDistanceMap >
+fpa::Image::SkeletonFilter< _TInputImage, _TDistanceMap >::
+SkeletonFilter( )
+ : 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::Image::SkeletonFilter< _TInputImage, _TDistanceMap >::
+~SkeletonFilter( )
+{
+}
+
+// -------------------------------------------------------------------------
+template< class _TInputImage, class _TDistanceMap >
+void fpa::Image::SkeletonFilter< _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
+ std::vector< TIndex > end_points;
+ this->_EndPoints(
+ end_points,
+ this->m_DistanceMap->GetOutput( ),
+ dijkstra->GetMinimumSpanningTree( ),
+ dijkstra->GetSkeletonQueue( )
+ );
+}
+
+// -------------------------------------------------------------------------
+template< class _TInputImage, class _TDistanceMap >
+template< class _TMarksPointer >
+void fpa::Image::SkeletonFilter< _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::Image::SkeletonFilter< _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
+}
+
+
+
+/* TODO
+ this->m_DistanceMap = TDistanceMap::New( );
+ this->m_DistanceMap->InsideIsPositiveOn( );
+ this->m_DistanceMap->SquaredDistanceOff( );
+ this->m_DistanceMap->UseImageSpacingOn( );
+
+ template< class _TImage, class _TScalar >
+ void fpa::Image::SkeletonFilter< _TImage, _TScalar >::
+ _Skeleton( const std::vector< TVertex >& end_points, _TAdjacencies& A )
+ {
+ typedef typename TSkeleton::TPath _TPath;
+ typedef itk::Image< unsigned long, TImage::ImageDimension > _TTagsImage;
+
+ TMST* mst = this->GetMinimumSpanningTree( );
+ TSkeleton* skeleton = this->GetSkeleton( );
+
+ // Tag branches
+ typename _TTagsImage::Pointer tags = _TTagsImage::New( );
+ tags->SetLargestPossibleRegion( mst->GetLargestPossibleRegion( ) );
+ tags->SetRequestedRegion( mst->GetRequestedRegion( ) );
+ tags->SetBufferedRegion( mst->GetBufferedRegion( ) );
+ tags->Allocate( );
+ tags->FillBuffer( 0 );
+ typename std::vector< TVertex >::const_iterator eIt = end_points.begin( );
+ for( ; eIt != end_points.end( ); ++eIt )
+ {
+ TVertex it = *eIt;
+ TVertex p = mst->GetParent( it );
+ while( it != p )
+ {
+ tags->SetPixel( it, tags->GetPixel( it ) + 1 );
+ it = p;
+ p = mst->GetParent( it );
+
+ } // elihw
+ tags->SetPixel( it, tags->GetPixel( it ) + 1 );
+
+ } // rof
+
+ // Build paths (branches)
+ eIt = end_points.begin( );
+ for( ; eIt != end_points.end( ); ++eIt )
+ {
+ TVertex it = *eIt;
+ TVertex p = mst->GetParent( it );
+ TVertex sIdx = it;
+ typename _TPath::Pointer path = _TPath::New( );
+ path->SetReferenceImage( mst );
+ while( it != p )
+ {
+ if( tags->GetPixel( sIdx ) != tags->GetPixel( it ) )
+ {
+ // Ok, a new branch has been added
+ path->AddVertex( it );
+ skeleton->AddBranch( path );
+
+ // Update a new starting index
+ path = _TPath::New( );
+ path->SetReferenceImage( mst );
+ sIdx = it;
+ }
+ else
+ path->AddVertex( it );
+ it = p;
+ p = mst->GetParent( it );
+
+ } // elihw
+
+ // Finally, add last branch
+ path->AddVertex( it );
+ skeleton->AddBranch( path );
+
+ } // rof
+ }
+*/
+
+#endif // __fpa__Image__SkeletonFilter__hxx__
+
+// eof - $RCSfile$
--- /dev/null
+// =========================================================================
+// @author Leonardo Florez Valencia
+// @email florez-l@javeriana.edu.co
+// =========================================================================
+
+#ifndef __fpa__Image__VisualDebugger__h__
+#define __fpa__Image__VisualDebugger__h__
+
+#include <fpa/Config.h>
+
+#include <vector>
+
+#include <itkCommand.h>
+#include <itkImage.h>
+#include <itkRGBAPixel.h>
+
+#ifdef USE_ivq
+#include <itkImageToVTKImageFilter.h>
+#endif // USE_ivq
+
+class vtkRenderer;
+class vtkRenderWindowInteractor;
+
+namespace fpa
+{
+ namespace Image
+ {
+ /**
+ */
+ template< class _TFilter >
+ class VisualDebugger
+ : public itk::Command
+ {
+ public:
+ typedef VisualDebugger Self;
+ typedef itk::Command Superclass;
+ typedef itk::SmartPointer< Self > Pointer;
+ typedef itk::SmartPointer< const Self > ConstPointer;
+
+ typedef _TFilter TFilter;
+ typedef typename TFilter::TInputImage TImage;
+
+ typedef itk::RGBAPixel< unsigned char > TLabel;
+ typedef itk::Image< TLabel, TImage::ImageDimension > TLabels;
+#ifdef USE_ivq
+ typedef itk::ImageToVTKImageFilter< TLabels > TVTKLabels;
+#endif // USE_ivq
+
+ public:
+ itkTypeMacro( fpa::Image::VisualDebugger, itk::Command );
+
+ itkGetConstObjectMacro( Labels, TLabels );
+
+ public:
+ void SetVisualization(
+ vtkRenderer* renderer, vtkRenderWindowInteractor* iren
+ );
+ virtual void Execute(
+ itk::Object* caller, const itk::EventObject& event
+ ) override;
+ virtual void Execute(
+ const itk::Object* caller, const itk::EventObject& event
+ ) override;
+
+ virtual void Render( ) = 0;
+ virtual void StartVisualization( ) = 0;
+ virtual void EndVisualization( ) = 0;
+
+ protected:
+ VisualDebugger( );
+ virtual ~VisualDebugger( );
+
+ private:
+ // Purposely not implemented.
+ VisualDebugger( const Self& other );
+ Self& operator=( const Self& other );
+
+ protected:
+ std::vector< TLabel > m_Colors;
+ typename TLabels::Pointer m_Labels;
+#ifdef USE_ivq
+ vtkRenderer* m_Renderer;
+ vtkRenderWindowInteractor* m_Interactor;
+ typename TVTKLabels::Pointer m_VTKLabels;
+#endif // USE_ivq
+ };
+
+ } // ecapseman
+
+} // ecapseman
+
+#ifndef ITK_MANUAL_INSTANTIATION
+# include <fpa/Image/VisualDebugger.hxx>
+#endif // ITK_MANUAL_INSTANTIATION
+
+#endif // __fpa__Image__VisualDebugger__h__
+
+// eof - $RCSfile$
--- /dev/null
+// =========================================================================
+// @author Leonardo Florez Valencia
+// @email florez-l@javeriana.edu.co
+// =========================================================================
+
+#ifndef __fpa__Image__VisualDebugger__hxx__
+#define __fpa__Image__VisualDebugger__hxx__
+
+// -------------------------------------------------------------------------
+template< class _TFilter >
+void fpa::Image::VisualDebugger< _TFilter >::
+SetVisualization( vtkRenderer* renderer, vtkRenderWindowInteractor* iren )
+{
+#ifdef USE_ivq
+ this->m_Renderer = renderer;
+ this->m_Interactor = iren;
+ this->Modified( );
+#endif // USE_ivq
+}
+
+// -------------------------------------------------------------------------
+template< class _TFilter >
+void fpa::Image::VisualDebugger< _TFilter >::
+Execute( itk::Object* caller, const itk::EventObject& event )
+{
+ this->Execute( const_cast< const itk::Object* >( caller ), event );
+}
+
+// -------------------------------------------------------------------------
+template< class _TFilter >
+void fpa::Image::VisualDebugger< _TFilter >::
+Execute( const itk::Object* caller, const itk::EventObject& event )
+{
+ typedef itk::StartEvent _TStart;
+ typedef itk::EndEvent _TEnd;
+ typedef typename _TFilter::TEvent _TEvent;
+
+ // Check validity
+ const TFilter* filter = dynamic_cast< const TFilter* >( caller );
+ if( filter == NULL )
+ return;
+
+ // Get correct event type
+ const _TEvent* ev_fpa = dynamic_cast< const _TEvent* >( &event );
+ const _TStart* ev_start = dynamic_cast< const _TStart* >( &event );
+ const _TEnd* ev_end = dynamic_cast< const _TEnd* >( &event );
+ if( ev_fpa != NULL )
+ {
+ if( this->m_Labels.IsNotNull( ) )
+ {
+ TLabel new_color;
+ if( ev_fpa->IntoQueue )
+ new_color = this->m_Colors[ this->m_Colors.size( ) - 2 ];
+ else
+ new_color =
+ this->m_Colors[
+ ( ev_fpa->FrontId - 1 ) % ( this->m_Colors.size( ) - 2 )
+ ];
+ TLabel old_color = this->m_Labels->GetPixel( ev_fpa->Vertex );
+ if( !( new_color == old_color ) )
+ {
+ this->m_Labels->SetPixel( ev_fpa->Vertex, new_color );
+ this->m_VTKLabels->Modified( );
+ this->Render( );
+
+ } // fi
+
+ } // fi
+ }
+ else if( ev_start != NULL )
+ {
+ const TImage* image = filter->GetInput( );
+ this->m_Labels = TLabels::New( );
+ this->m_Labels->
+ SetLargestPossibleRegion( image->GetLargestPossibleRegion( ) );
+ this->m_Labels->SetRequestedRegion( image->GetRequestedRegion( ) );
+ this->m_Labels->SetBufferedRegion( image->GetBufferedRegion( ) );
+ this->m_Labels->SetOrigin( image->GetOrigin( ) );
+ this->m_Labels->SetSpacing( image->GetSpacing( ) );
+ this->m_Labels->SetDirection( image->GetDirection( ) );
+ this->m_Labels->Allocate( );
+ this->m_Labels->FillBuffer( this->m_Colors.back( ) );
+#ifdef USE_ivq
+ this->m_VTKLabels = TVTKLabels::New( );
+ this->m_VTKLabels->SetInput( this->m_Labels );
+ this->m_VTKLabels->Update( );
+ this->StartVisualization( );
+#endif // USE_ivq
+ }
+ else if( ev_end != NULL )
+ {
+ this->EndVisualization( );
+ this->m_Labels = NULL;
+ this->m_VTKLabels = NULL;
+
+ } // fi
+}
+
+// -------------------------------------------------------------------------
+template< class _TFilter >
+fpa::Image::VisualDebugger< _TFilter >::
+VisualDebugger( )
+ : Superclass( )
+{
+ unsigned char colors[ 8 ][ 4 ] =
+ {
+ { 255, 0, 0, 128 },
+ { 0, 255, 0, 128 },
+ { 0, 0, 255, 128 },
+ { 0, 255, 255, 128 },
+ { 255, 0, 255, 128 },
+ { 255, 255, 0, 128 },
+ { 255, 128, 64, 255 },
+ { 0, 0, 0, 0 }
+ };
+ for( unsigned int i = 0; i < 8; ++i )
+ this->m_Colors.push_back( TLabel( colors[ i ] ) );
+
+#ifdef USE_ivq
+ this->m_Renderer = NULL;
+ this->m_Interactor = NULL;
+#endif // USE_ivq
+}
+
+// -------------------------------------------------------------------------
+template< class _TFilter >
+fpa::Image::VisualDebugger< _TFilter >::
+~VisualDebugger( )
+{
+}
+
+#endif // __fpa__Image__VisualDebugger__h__
+
+// eof - $RCSfile$
--- /dev/null
+// =========================================================================
+// @author Leonardo Florez Valencia
+// @email florez-l@javeriana.edu.co
+// =========================================================================
+
+#ifndef __fpa__Image__VisualDebugger2D__h__
+#define __fpa__Image__VisualDebugger2D__h__
+
+#include <fpa/Image/VisualDebugger.h>
+#ifdef USE_ivq
+#include <vtkSmartPointer.h>
+#include <ivq/VTK/ImageActor.h>
+#endif // USE_ivq
+
+namespace fpa
+{
+ namespace Image
+ {
+ /**
+ */
+ template< class _TFilter >
+ class VisualDebugger2D
+ : public fpa::Image::VisualDebugger< _TFilter >
+ {
+ public:
+ typedef VisualDebugger2D Self;
+ typedef fpa::Image::VisualDebugger< _TFilter > Superclass;
+ typedef itk::SmartPointer< Self > Pointer;
+ typedef itk::SmartPointer< const Self > ConstPointer;
+
+ typedef typename Superclass::TFilter TFilter;
+ typedef typename Superclass::TImage TImage;
+ typedef typename Superclass::TLabel TLabel;
+ typedef typename Superclass::TLabels TLabels;
+#ifdef USE_ivq
+ typedef typename Superclass::TVTKLabels TVTKLabels;
+ typedef ivq::VTK::ImageActor TImageActor;
+#endif // USE_ivq
+
+ public:
+ itkNewMacro( Self );
+ itkTypeMacro( fpa::Image::VisualDebugger2D, fpa::Image::VisualDebugger );
+
+ public:
+ virtual void Render( ) override;
+ virtual void StartVisualization( ) override;
+ virtual void EndVisualization( ) override;
+
+ protected:
+ VisualDebugger2D( );
+ virtual ~VisualDebugger2D( );
+
+ private:
+ // Purposely not implemented.
+ VisualDebugger2D( const Self& other );
+ Self& operator=( const Self& other );
+
+ protected:
+#ifdef USE_ivq
+ vtkSmartPointer< TImageActor > m_Actor;
+ unsigned long m_NumberOfPixels;
+ unsigned long m_RenderCount;
+#endif // USE_ivq
+ };
+
+ } // ecapseman
+
+} // ecapseman
+
+#ifndef ITK_MANUAL_INSTANTIATION
+# include <fpa/Image/VisualDebugger2D.hxx>
+#endif // ITK_MANUAL_INSTANTIATION
+
+#endif // __fpa__Image__VisualDebugger2D__h__
+
+// eof - $RCSfile$
--- /dev/null
+// =========================================================================
+// @author Leonardo Florez Valencia
+// @email florez-l@javeriana.edu.co
+// =========================================================================
+
+#ifndef __fpa__Image__VisualDebugger2D__hxx__
+#define __fpa__Image__VisualDebugger2D__hxx__
+
+#include <vtkRenderer.h>
+#include <vtkRenderWindowInteractor.h>
+
+// -------------------------------------------------------------------------
+template< class _TFilter >
+void fpa::Image::VisualDebugger2D< _TFilter >::
+Render( )
+{
+#ifdef USE_ivq
+ if( this->m_Renderer == NULL || this->m_Interactor == NULL )
+ return;
+ this->m_Actor->Modified( );
+ this->m_RenderCount = ( this->m_RenderCount + 1 ) % this->m_NumberOfPixels;
+ if( this->m_RenderCount == 0 )
+ this->m_Interactor->Render( );
+#endif // USE_ivq
+}
+
+// -------------------------------------------------------------------------
+template< class _TFilter >
+void fpa::Image::VisualDebugger2D< _TFilter >::
+StartVisualization( )
+{
+#ifdef USE_ivq
+ if( this->m_Renderer == NULL || this->m_Interactor == NULL )
+ return;
+ this->m_Actor = vtkSmartPointer< TImageActor >::New( );
+ this->m_Actor->SetInputData( this->m_VTKLabels->GetOutput( ) );
+ this->m_Actor->Update( );
+ this->m_Renderer->AddViewProp( this->m_Actor );
+
+ this->m_NumberOfPixels =
+ double(
+ this->m_VTKLabels->GetInput( )->
+ GetRequestedRegion( ).GetNumberOfPixels( )
+ ) * 0.005;
+ this->m_RenderCount = 0;
+
+#endif // USE_ivq
+}
+
+// -------------------------------------------------------------------------
+template< class _TFilter >
+void fpa::Image::VisualDebugger2D< _TFilter >::
+EndVisualization( )
+{
+}
+
+// -------------------------------------------------------------------------
+template< class _TFilter >
+fpa::Image::VisualDebugger2D< _TFilter >::
+VisualDebugger2D( )
+ : Superclass( )
+{
+}
+
+// -------------------------------------------------------------------------
+template< class _TFilter >
+fpa::Image::VisualDebugger2D< _TFilter >::
+~VisualDebugger2D( )
+{
+}
+
+#endif // __fpa__Image__VisualDebugger2D__hxx__
+
+// eof - $RCSfile$
--- /dev/null
+
+#include <fpa/fpa_export.h>
+#include <string>
+
+std::string FPA_EXPORT version( ) { return( "@prj_VERSION@" ); }
+
+// eof - $RCSfile$
--- /dev/null
+option(BUILD_TESTS "Build command line tests." OFF)
+if(BUILD_TESTS)
+ include_directories(
+ ${PROJECT_SOURCE_DIR}/lib
+ ${PROJECT_BINARY_DIR}/lib
+ )
+ subdirs(image)
+endif(BUILD_TESTS)
+
+## eof - $RCSfile$
--- /dev/null
+// =========================================================================
+// @author Leonardo Florez Valencia
+// @email florez-l@javeriana.edu.co
+// =========================================================================
+
+#ifndef __fpa__tests__image__BaseFunctions__h__
+#define __fpa__tests__image__BaseFunctions__h__
+
+#include <cstdarg>
+#include <string>
+
+#include <itkImageFileReader.h>
+#include <itkImageFileWriter.h>
+
+#include <fpa/Config.h>
+#ifdef USE_ivq
+# include <itkImageToVTKImageFilter.h>
+# include <itkVTKImageToImageFilter.h>
+# include <vtkSmartPointer.h>
+# include <vtkRenderWindow.h>
+# include <ivq/VTK/ImageViewer.h>
+# include <ivq/VTK/BrushWidget.h>
+# include <ivq/VTK/SeedWidgetOverImageActor.h>
+# include <fpa/Image/VisualDebugger2D.h>
+#endif // USE_ivq
+
+namespace fpa
+{
+ namespace tests
+ {
+ namespace image
+ {
+ // -------------------------------------------------------------------
+ template< class _TPointer >
+ void CreateImage(
+ _TPointer& img,
+ const typename _TPointer::ObjectType::PixelType& zero,
+ ...
+ )
+ {
+ typedef typename _TPointer::ObjectType _TImage;
+
+ va_list vl;
+ va_start( vl, zero );
+
+ typename _TImage::SizeType size;
+ for( unsigned int d = 0; d < _TImage::ImageDimension; ++d )
+ size[ d ] = va_arg( vl, int );
+
+ typename _TImage::SpacingType spac;
+ for( unsigned int d = 0; d < _TImage::ImageDimension; ++d )
+ spac[ d ] = va_arg( vl, double );
+
+ img = _TImage::New( );
+ img->SetRegions( size );
+ img->SetSpacing( spac );
+ img->Allocate( );
+ img->FillBuffer( zero );
+
+ va_end( vl );
+ }
+
+ // -------------------------------------------------------------------
+ template< class _TPointer >
+ std::string Read( _TPointer& img, const std::string& fname )
+ {
+ typedef typename _TPointer::ObjectType _TImage;
+ typedef itk::ImageFileReader< _TImage > _TReader;
+
+ typename _TReader::Pointer reader = _TReader::New( );
+ reader->SetFileName( fname );
+ try
+ {
+ reader->Update( );
+ }
+ catch( std::exception& err )
+ {
+ return( err.what( ) );
+
+ } // ytr
+ img = reader->GetOutput( );
+ img->DisconnectPipeline( );
+ return( "" );
+ }
+
+ // -------------------------------------------------------------------
+ template< class _TImage >
+ std::string Write( const _TImage* img, const std::string& fname )
+ {
+ typedef itk::ImageFileWriter< _TImage > _TWriter;
+
+ typename _TWriter::Pointer writer = _TWriter::New( );
+ writer->SetInput( img );
+ writer->SetFileName( fname );
+ try
+ {
+ writer->Update( );
+ }
+ catch( std::exception& err )
+ {
+ return( err.what( ) );
+
+ } // ytr
+ return( "" );
+ }
+
+ // -------------------------------------------------------------------
+ template< class _TFilter >
+ class Viewer
+ {
+ public:
+ typedef _TFilter TFilter;
+ typedef typename _TFilter::TInputImage TInputImage;
+
+ public:
+ Viewer( const TInputImage* image )
+ {
+#ifdef USE_ivq
+ this->m_VTKInputImage = TVTKInputImage::New( );
+ this->m_VTKInputImage->SetInput( image );
+ this->m_VTKInputImage->Update( );
+
+ this->m_Viewer = vtkSmartPointer< ivq::VTK::ImageViewer >::New( );
+ this->m_Viewer->SetInputData( this->m_VTKInputImage->GetOutput( ) );
+#endif // USE_ivq
+ }
+
+ virtual ~Viewer( )
+ {
+ }
+
+ void ActivateSeedWidget( )
+ {
+#ifdef USE_ivq
+ this->m_SeedWidget =
+ vtkSmartPointer< ivq::VTK::SeedWidgetOverImageActor >::New( );
+ this->m_SeedWidget->SetActor( this->m_Viewer->GetImageActor( ) );
+ this->m_SeedWidget->SetInteractor(
+ this->m_Viewer->GetRenderWindow( )->GetInteractor( )
+ );
+#endif // USE_ivq
+ }
+
+ void ActivateBrushWidget( )
+ {
+#ifdef USE_ivq
+ this->m_BrushWidget =
+ vtkSmartPointer< ivq::VTK::BrushWidget >::New( );
+ this->m_BrushWidget->SetImageActor( this->m_Viewer->GetImageActor( ) );
+ this->m_BrushWidget->SetInteractor(
+ this->m_Viewer->GetRenderWindow( )->GetInteractor( )
+ );
+#endif // USE_ivq
+ }
+
+ void Show( )
+ {
+#ifdef USE_ivq
+ this->m_Viewer->Render( );
+ this->m_Viewer->ResetCamera( );
+ this->m_Viewer->Initialize( );
+ this->m_Viewer->Render( );
+ if( this->m_SeedWidget.GetPointer( ) != NULL )
+ this->m_SeedWidget->EnabledOn( );
+ if( this->m_BrushWidget.GetPointer( ) != NULL )
+ this->m_BrushWidget->EnabledOn( );
+ this->m_Viewer->Start( );
+ if( this->m_SeedWidget.GetPointer( ) != NULL )
+ this->m_SeedWidget->EnabledOff( );
+ if( this->m_BrushWidget.GetPointer( ) != NULL )
+ this->m_BrushWidget->EnabledOff( );
+#endif // USE_ivq
+ }
+
+ void AssociateSeedsTo( TFilter* filter )
+ {
+#ifdef USE_ivq
+ if( this->m_SeedWidget.GetPointer( ) != NULL )
+ {
+ const ivq::VTK::SeedWidgetOverImageActor::TSeeds& wdg_seeds =
+ this->m_SeedWidget->GetSeeds( );
+ ivq::VTK::SeedWidgetOverImageActor::TSeeds::const_iterator wsIt;
+ for( wsIt = wdg_seeds.begin( ); wsIt != wdg_seeds.end( ); ++wsIt )
+ {
+ typename TInputImage::PointType pnt;
+ for( unsigned int i = 0; i < wsIt->second.size( ); i += 3 )
+ {
+ pnt[ 0 ] = wsIt->second[ i ];
+ pnt[ 1 ] = wsIt->second[ i + 1 ];
+
+ typename TInputImage::IndexType idx;
+ filter->GetInput( )->TransformPhysicalPointToIndex( pnt, idx );
+ filter->AddSeed( idx );
+
+ } // rof
+
+ } // rof
+
+ } // fi
+#endif // USE_ivq
+ }
+
+ void AssociateLabelsTo( TFilter* filter )
+ {
+#ifdef USE_ivq
+ if( this->m_BrushWidget.GetPointer( ) != NULL )
+ {
+ typedef typename TFilter::TLabelImage _TLabelImage;
+ typedef itk::VTKImageToImageFilter< _TLabelImage > TITKImage;
+ typename TITKImage::Pointer itk_image = TITKImage::New( );
+ itk_image->SetInput( this->m_BrushWidget->GetCanvas( ) );
+ itk_image->Update( );
+ filter->SetLabels( itk_image->GetOutput( ) );
+
+ } // fi
+#endif // USE_ivq
+ }
+
+ void ObserveFilter( TFilter* filter )
+ {
+#ifdef USE_ivq
+ typedef fpa::Image::VisualDebugger2D< TFilter > _TDeb;
+ typedef typename TFilter::TEvent _TEvent;
+ typename _TDeb::Pointer deb = _TDeb::New( );
+ deb->SetVisualization(
+ this->m_Viewer->GetRenderer( ),
+ this->m_Viewer->GetRenderWindow( )->GetInteractor( )
+ );
+ this->m_Observer1 = filter->AddObserver( itk::StartEvent( ), deb );
+ this->m_Observer2 = filter->AddObserver( itk::EndEvent( ), deb );
+ this->m_Observer3 = filter->AddObserver( _TEvent( ), deb );
+ filter->VisualDebugOn( );
+#endif // USE_ivq
+ }
+
+ protected:
+#ifdef USE_ivq
+ typedef itk::ImageToVTKImageFilter< TInputImage > TVTKInputImage;
+ typename TVTKInputImage::Pointer m_VTKInputImage;
+ vtkSmartPointer< ivq::VTK::ImageViewer > m_Viewer;
+ vtkSmartPointer< ivq::VTK::SeedWidgetOverImageActor > m_SeedWidget;
+ vtkSmartPointer< ivq::VTK::BrushWidget > m_BrushWidget;
+ unsigned long m_Observer1;
+ unsigned long m_Observer2;
+ unsigned long m_Observer3;
+#endif // USE_ivq
+
+
+ /* TODO
+ #ifdef USE_ivq
+ // VTK image
+ typedef itk::ImageToVTKImageFilter< TImage > TVTKImage;
+ TVTKImage::Pointer vtk_input;
+ vtkSmartPointer< ivq::VTK::ImageViewer > view;
+ vtkSmartPointer< ivq::VTK::SeedWidgetOverImageActor > widget;
+
+ if( visual_debug )
+ {
+ vtk_input = TVTKImage::New( );
+ vtk_input->SetInput( input );
+ vtk_input->Update( );
+
+ // Viewer
+ view = vtkSmartPointer< ivq::VTK::ImageViewer >::New( );
+ view->SetInputData( vtk_input->GetOutput( ) );
+ view->SetSlice( 0 );
+
+ // Widget
+ widget = vtkSmartPointer< ivq::VTK::SeedWidgetOverImageActor >::New( );
+ widget->SetActor( view->GetImageActor( ) );
+ widget->SetInteractor( view->GetRenderWindow( )->GetInteractor( ) );
+
+ // Visualize
+ view->Render( );
+ view->ResetCamera( );
+ view->Initialize( );
+ view->Render( );
+ widget->EnabledOn( );
+ view->Start( );
+ widget->EnabledOff( );
+
+ const ivq::VTK::SeedWidgetOverImageActor::TSeeds& wdg_seeds =
+ widget->GetSeeds( );
+ ivq::VTK::SeedWidgetOverImageActor::TSeeds::const_iterator wsIt;
+ for( wsIt = wdg_seeds.begin( ); wsIt != wdg_seeds.end( ); ++wsIt )
+ {
+ TImage::PointType pnt;
+ for( unsigned int i = 0; i < wsIt->second.size( ); i += 3 )
+ {
+ pnt[ 0 ] = wsIt->second[ i ];
+ pnt[ 1 ] = wsIt->second[ i + 1 ];
+
+ TImage::IndexType idx;
+ input->TransformPhysicalPointToIndex( pnt, idx );
+ seeds.push_back( idx );
+
+ } // rof
+
+ } // rof
+
+ } // fi
+ #endif // USE_ivq
+ */
+ };
+
+ } // ecapseman
+
+ } // ecapseman
+
+} // ecapseman
+
+
+#endif // __fpa__tests__image__BaseFunctions__h__
+
+// eof - $RCSfile$
--- /dev/null
+set(_pfx test_fpa_image_)
+set(
+ _examples
+ RegionGrow_Tautology
+ Dijkstra_Identity
+ Dijkstra_Gaussian
+ RandomWalker
+ SkeletonFilter
+ )
+foreach(_e ${_examples})
+ add_executable(${_pfx}${_e} ${_e}.cxx)
+ if(ivq_FOUND)
+ target_link_libraries(${_pfx}${_e} fpa ivq::ivq)
+ else(ivq_FOUND)
+ target_link_libraries(${_pfx}${_e} fpa)
+ endif(ivq_FOUND)
+endforeach(_e)
+
+## eof - $RCSfile$
--- /dev/null
+#include "BaseFunctions.h"
+#include <itkImage.h>
+#include <fpa/Image/Dijkstra.h>
+#include <fpa/Image/Functors/Dijkstra/Gaussian.h>
+
+// -------------------------------------------------------------------------
+const unsigned int Dim = 2;
+typedef unsigned char TPixel;
+typedef float TScalar;
+
+typedef itk::Image< TPixel, Dim > TInputImage;
+typedef itk::Image< TScalar, Dim > TScalarImage;
+typedef fpa::Image::Dijkstra< TInputImage, TScalarImage > TFilter;
+typedef fpa::Image::Functors::Dijkstra::Gaussian< TInputImage, TScalar > TWeight;
+
+// -------------------------------------------------------------------------
+int main( int argc, char* argv[] )
+{
+ // Get arguments
+ if( argc < 8 )
+ {
+ std::cerr
+ << "Usage: " << argv[ 0 ]
+ << " input_image output_image output_marks alpha beta"
+ << " stop_at_one_front visual_debug ..."
+ << 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 ];
+ double alpha = std::atoi( argv[ 4 ] );
+ double beta = std::atoi( argv[ 5 ] );
+ bool stop_at_one_front = ( argv[ 6 ][ 0 ] == '1' );
+ bool visual_debug = ( argv[ 7 ][ 0 ] == '1' );
+
+ // Create image
+ TInputImage::Pointer image;
+ std::string err0 = fpa::tests::image::Read( image, input_image_filename );
+ if( err0 != "" )
+ {
+ std::cerr << "Error caught: " << err0 << std::endl;
+ return( 1 );
+
+ } // fi
+
+ // Interact with image
+ fpa::tests::image::Viewer< TFilter > viewer( image );
+ if( visual_debug )
+ {
+ viewer.ActivateSeedWidget( );
+ viewer.Show( );
+
+ } // fi
+
+ // Prepare weight
+ TWeight::Pointer weight = TWeight::New( );
+ weight->SetAlpha( alpha );
+ weight->SetBeta( beta );
+
+ // Prepare filter
+ TFilter::Pointer filter = TFilter::New( );
+ filter->SetInput( image );
+ filter->SetWeightFunction( weight );
+ filter->SetStopAtOneFront( stop_at_one_front );
+
+ // Get all seeds
+ for( int i = 8; i < argc; i += 2 )
+ {
+ if( i + 1 < argc )
+ {
+ TInputImage::IndexType seed;
+ seed[ 0 ] = std::atoi( argv[ i ] );
+ seed[ 1 ] = std::atoi( argv[ i + 1 ] );
+ filter->AddSeed( seed );
+
+ } // fi
+
+ } // rof
+ viewer.AssociateSeedsTo( filter );
+
+ // Prepare visual debug and update
+ if( visual_debug )
+ viewer.ObserveFilter( filter );
+ filter->Update( );
+
+ // Save results
+ std::string err1 =
+ fpa::tests::image::Write( filter->GetOutput( ), output_image_filename );
+ std::string err2 =
+ fpa::tests::image::Write( filter->GetMarks( ), output_marks_filename );
+ if( err1 != "" ) std::cerr << "Error caught: " << err1 << std::endl;
+ if( err2 != "" ) std::cerr << "Error caught: " << err2 << std::endl;
+
+ return( 0 );
+}
+
+// eof - $RCSfile$
--- /dev/null
+#include "BaseFunctions.h"
+#include <itkImage.h>
+#include <fpa/Image/Dijkstra.h>
+#include <fpa/Image/Functors/Dijkstra/Identity.h>
+
+// -------------------------------------------------------------------------
+const unsigned int Dim = 2;
+typedef unsigned char TPixel;
+typedef float TScalar;
+
+typedef itk::Image< TPixel, Dim > TInputImage;
+typedef itk::Image< TScalar, Dim > TScalarImage;
+typedef fpa::Image::Dijkstra< TInputImage, TScalarImage > TFilter;
+typedef fpa::Image::Functors::Dijkstra::Identity< TInputImage, TScalar > TWeight;
+
+// -------------------------------------------------------------------------
+int main( int argc, char* argv[] )
+{
+ // Get arguments
+ if( argc < 6 )
+ {
+ std::cerr
+ << "Usage: " << argv[ 0 ]
+ << " output_image output_marks width height visual_debug ..."
+ << std::endl;
+ return( 1 );
+
+ } // fi
+ std::string output_image_filename = argv[ 1 ];
+ std::string output_marks_filename = argv[ 2 ];
+ int width = std::atoi( argv[ 3 ] );
+ int height = std::atoi( argv[ 4 ] );
+ bool visual_debug = ( argv[ 5 ][ 0 ] == '1' );
+
+ // Create image
+ TInputImage::Pointer image;
+ fpa::tests::image::CreateImage( image, 1, width, height, 1.0, 1.0 );
+
+ // Interact with image
+ fpa::tests::image::Viewer< TFilter > viewer( image );
+ if( visual_debug )
+ {
+ viewer.ActivateSeedWidget( );
+ viewer.Show( );
+
+ } // fi
+
+ // Prepare weight
+ TWeight::Pointer weight = TWeight::New( );
+
+ // Prepare filter
+ TFilter::Pointer filter = TFilter::New( );
+ filter->SetInput( image );
+ filter->SetWeightFunction( weight );
+
+ // Get all seeds
+ for( int i = 6; i < argc; i += 2 )
+ {
+ if( i + 1 < argc )
+ {
+ TInputImage::IndexType seed;
+ seed[ 0 ] = std::atoi( argv[ i ] );
+ seed[ 1 ] = std::atoi( argv[ i + 1 ] );
+ filter->AddSeed( seed );
+
+ } // fi
+
+ } // rof
+ viewer.AssociateSeedsTo( filter );
+
+ // Prepare visual debug and update
+ if( visual_debug )
+ viewer.ObserveFilter( filter );
+ filter->Update( );
+
+ // Save results
+ std::string err1 =
+ fpa::tests::image::Write( filter->GetOutput( ), output_image_filename );
+ std::string err2 =
+ fpa::tests::image::Write( filter->GetMarks( ), output_marks_filename );
+ if( err1 != "" ) std::cerr << err1 << std::endl;
+ if( err2 != "" ) std::cerr << err2 << std::endl;
+
+ return( 0 );
+}
+
+// eof - $RCSfile$
--- /dev/null
+#include "BaseFunctions.h"
+#include <itkImage.h>
+#include <fpa/Image/RandomWalker.h>
+#include <fpa/Image/Functors/Dijkstra/Gaussian.h>
+
+// -------------------------------------------------------------------------
+const unsigned int Dim = 2;
+typedef short TPixel;
+typedef unsigned char TLabel;
+typedef float TScalar;
+
+typedef itk::Image< TPixel, Dim > TInputImage;
+typedef itk::Image< TLabel, Dim > TLabelImage;
+typedef fpa::Image::RandomWalker< TInputImage, TLabelImage, TScalar > TFilter;
+typedef fpa::Image::Functors::Dijkstra::Gaussian< TInputImage, TScalar > TWeight;
+
+// -------------------------------------------------------------------------
+int main( int argc, char* argv[] )
+{
+ // Get arguments
+ if( argc < 7 )
+ {
+ std::cerr
+ << "Usage: " << argv[ 0 ]
+ << " input_image [labels_image] output_image output_costs"
+ << " alpha beta visual_debug"
+ << std::endl;
+ return( 1 );
+
+ } // fi
+ int idx = ( argc == 7 )? 2: 3;
+ std::string input_image_filename = argv[ 1 ];
+ std::string labels_image_filename = ( argc == 8 )? argv[ 2 ]: "";
+ std::string output_image_filename = argv[ idx ];
+ std::string output_costs_filename = argv[ idx + 1 ];
+ double alpha = std::atof( argv[ idx + 2 ] );
+ double beta = std::atof( argv[ idx + 3 ] );
+ bool visual_debug = ( argv[ idx + 4 ][ 0 ] == '1' );
+
+ // Read image
+ TInputImage::Pointer image;
+ std::string err0 = fpa::tests::image::Read( image, input_image_filename );
+ if( err0 != "" )
+ {
+ std::cerr << "Error caught: " << err0 << std::endl;
+ return( 1 );
+
+ } // fi
+
+ // Read label
+ TLabelImage::Pointer labels;
+ if( labels_image_filename != "" )
+ {
+ std::string err1 = fpa::tests::image::Read( labels, labels_image_filename );
+ if( err1 != "" )
+ {
+ std::cerr << "Error caught: " << err1 << std::endl;
+ return( 1 );
+
+ } // fi
+
+ } // fi
+
+ // Interact with image
+ fpa::tests::image::Viewer< TFilter > viewer( image );
+ if( visual_debug )
+ {
+ if( labels.IsNull( ) )
+ viewer.ActivateBrushWidget( );
+ viewer.Show( );
+
+ } // fi
+
+ // Prepare weight
+ TWeight::Pointer weight = TWeight::New( );
+ weight->SetAlpha( alpha );
+ weight->SetBeta( beta );
+
+ // Prepare filter
+ TFilter::Pointer filter = TFilter::New( );
+ filter->SetInput( image );
+ filter->SetWeightFunction( weight );
+ if( labels.IsNull( ) )
+ viewer.AssociateLabelsTo( filter );
+ else
+ filter->SetLabels( labels );
+
+ // Prepare visual debug and update
+ if( visual_debug )
+ viewer.ObserveFilter( filter );
+ try
+ {
+ filter->Update( );
+ }
+ catch( std::exception& err )
+ {
+ std::cerr << "Error caught: " << err.what( ) << std::endl;
+ return( 1 );
+
+ } // yrt
+
+ // Save results
+ std::string err1 =
+ fpa::tests::image::Write( filter->GetMarks( ), output_image_filename );
+ std::string err2 =
+ fpa::tests::image::Write( filter->GetOutput( ), output_costs_filename );
+ if( err1 != "" ) std::cerr << "Error caught: " << err1 << std::endl;
+ if( err2 != "" ) std::cerr << "Error caught: " << err2 << std::endl;
+
+ return( 0 );
+}
+
+// eof - $RCSfile$
--- /dev/null
+#include "BaseFunctions.h"
+#include <itkImage.h>
+#include <fpa/Image/RegionGrow.h>
+#include <fpa/Base/Functors/RegionGrow/Tautology.h>
+
+// -------------------------------------------------------------------------
+const unsigned int Dim = 2;
+typedef unsigned char TPixel;
+
+typedef itk::Image< TPixel, Dim > TImage;
+typedef fpa::Image::RegionGrow< TImage, TImage > TFilter;
+typedef fpa::Base::Functors::RegionGrow::Tautology< TPixel > TPredicate;
+
+// -------------------------------------------------------------------------
+int main( int argc, char* argv[] )
+{
+ // Get arguments
+ if( argc < 6 )
+ {
+ std::cerr
+ << "Usage: " << argv[ 0 ]
+ << " output_image output_marks width height visual_debug ..."
+ << std::endl;
+ return( 1 );
+
+ } // fi
+ std::string output_image_filename = argv[ 1 ];
+ std::string output_marks_filename = argv[ 2 ];
+ int width = std::atoi( argv[ 3 ] );
+ int height = std::atoi( argv[ 4 ] );
+ bool visual_debug = ( argv[ 5 ][ 0 ] == '1' );
+
+ // Create image
+ TImage::Pointer image;
+ fpa::tests::image::CreateImage( image, 0, width, height, 1.0, 1.0 );
+
+ // Interact with image
+ fpa::tests::image::Viewer< TFilter > viewer( image );
+ if( visual_debug )
+ {
+ viewer.ActivateSeedWidget( );
+ viewer.Show( );
+
+ } // fi
+
+ // Prepare predicate
+ TPredicate::Pointer predicate = TPredicate::New( );
+
+ // Prepare filter
+ TFilter::Pointer filter = TFilter::New( );
+ filter->SetInput( image );
+ filter->SetPredicate( predicate );
+ filter->SetInsideValue( 255 );
+ filter->SetOutsideValue( 0 );
+
+ // Get all seeds
+ for( int i = 6; i < argc; i += 2 )
+ {
+ if( i + 1 < argc )
+ {
+ TImage::IndexType seed;
+ seed[ 0 ] = std::atoi( argv[ i ] );
+ seed[ 1 ] = std::atoi( argv[ i + 1 ] );
+ filter->AddSeed( seed );
+
+ } // fi
+
+ } // rof
+ viewer.AssociateSeedsTo( filter );
+
+ // Prepare visual debug and update
+ if( visual_debug )
+ viewer.ObserveFilter( filter );
+ filter->Update( );
+
+ // Save results
+ std::string err1 =
+ fpa::tests::image::Write( filter->GetOutput( ), output_image_filename );
+ std::string err2 =
+ fpa::tests::image::Write( filter->GetMarks( ), output_marks_filename );
+ if( err1 != "" ) std::cerr << err1 << std::endl;
+ if( err2 != "" ) std::cerr << err2 << std::endl;
+
+ return( 0 );
+}
+
+// eof - $RCSfile$
--- /dev/null
+#include "BaseFunctions.h"
+#include <itkImage.h>
+#include <fpa/Image/SkeletonFilter.h>
+
+// -------------------------------------------------------------------------
+const unsigned int Dim = 3;
+typedef short TPixel;
+
+typedef itk::Image< TPixel, Dim > TInputImage;
+typedef fpa::Image::SkeletonFilter< TInputImage > TFilter;
+
+// -------------------------------------------------------------------------
+int main( int argc, char* argv[] )
+{
+ // Get arguments
+ if( argc < 3 )
+ {
+ std::cerr
+ << "Usage: " << argv[ 0 ]
+ << " input_image output_skeleton ..."
+ << std::endl;
+ return( 1 );
+
+ } // fi
+ std::string input_image_filename = argv[ 1 ];
+ std::string output_skeleton_filename = argv[ 2 ];
+
+ // Read image
+ TInputImage::Pointer image;
+ std::string err1 = fpa::tests::image::Read( image, input_image_filename );
+ if( err1 != "" )
+ {
+ std::cerr << "Error caught: " << err1 << std::endl;
+ return( 1 );
+
+ } // fi
+
+ // Prepare filter
+ TFilter::Pointer filter = TFilter::New( );
+ filter->SetInput( image );
+
+ // Configure seed
+ if( argc == 6 )
+ {
+ TInputImage::PointType pnt;
+ pnt[ 0 ] = std::atof( argv[ 3 ] );
+ pnt[ 1 ] = std::atof( argv[ 4 ] );
+ pnt[ 2 ] = std::atof( argv[ 5 ] );
+
+ TInputImage::IndexType seed;
+ image->TransformPhysicalPointToIndex( pnt, seed );
+
+ filter->SeedFromMaximumDistanceOff( );
+ filter->SetSeed( seed );
+ }
+ else
+ filter->SeedFromMaximumDistanceOn( );
+
+ // Update
+ filter->Update( );
+
+ // Save results
+ /* TODO
+ std::string err1 =
+ fpa::tests::image::Write( filter->GetOutput( ), output_image_filename );
+ std::string err2 =
+ fpa::tests::image::Write( filter->GetMarks( ), output_marks_filename );
+ if( err1 != "" ) std::cerr << err1 << std::endl;
+ if( err2 != "" ) std::cerr << err2 << std::endl;
+ */
+ return( 0 );
+}
+
+// eof - $RCSfile$