From 41bb8ed7b212665b08d71ed2e550c6973105aec6 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Leonardo=20Fl=C3=B3rez-Valencia?= Date: Tue, 4 Oct 2016 18:20:07 -0500 Subject: [PATCH] ... --- CMakeLists.txt | 2 +- cmake/CMakeLists.txt | 11 +++ cmake/FrontAlgorithmsConfig.cmake.in | 60 ++++++++++++ lib/fpa/Image/EndPointsFilter.h | 77 +++++++++++++++ lib/fpa/Image/EndPointsFilter.hxx | 135 +++++++++++++++++++++++++++ plugins/Plugins/EndPointsFilter.cxx | 109 +++++++++++++++++++++ plugins/Plugins/EndPointsFilter.h | 32 +++++++ 7 files changed, 425 insertions(+), 1 deletion(-) create mode 100644 cmake/CMakeLists.txt create mode 100644 cmake/FrontAlgorithmsConfig.cmake.in create mode 100644 lib/fpa/Image/EndPointsFilter.h create mode 100644 lib/fpa/Image/EndPointsFilter.hxx create mode 100644 plugins/Plugins/EndPointsFilter.cxx create mode 100644 plugins/Plugins/EndPointsFilter.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 0d6fd70..914bfe6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -64,6 +64,6 @@ ENDFOREACH(_dir) ## == Manage source code == ## ======================== -SUBDIRS(lib plugins appli) +SUBDIRS(cmake lib plugins appli) ## eof - $RCSfile$ diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt new file mode 100644 index 0000000..5d4261d --- /dev/null +++ b/cmake/CMakeLists.txt @@ -0,0 +1,11 @@ +## ===================== +## == Configure files == +## ===================== + +CONFIGURE_FILE( + FrontAlgorithmsConfig.cmake.in + ${PROJECT_BINARY_DIR}/FrontAlgorithmsConfig.cmake + @ONLY + ) + +## eof - $RCSfile$ diff --git a/cmake/FrontAlgorithmsConfig.cmake.in b/cmake/FrontAlgorithmsConfig.cmake.in new file mode 100644 index 0000000..097bce7 --- /dev/null +++ b/cmake/FrontAlgorithmsConfig.cmake.in @@ -0,0 +1,60 @@ +## ================================ +## == Find cpPlugins-cmake tools == +## ================================ + +## ==================== +## == Find libraries == +## ==================== + +SET( + _all_libs + "@fpa_LIB@" + "@fpa_Instances@" + ) +SET(fpa_Instances "@fpa_Instances@") + +SET(_l_locations) +FOREACH(_l ${_all_libs}) + IF(MSVC) + FIND_LIBRARY( + ${_l}_LIB NAMES ${_l} + HINTS + @PROJECT_BINARY_DIR@/$(ConfigurationName) + @CMAKE_INSTALL_PREFIX@/bin + @CMAKE_INSTALL_PREFIX@/lib + ) + ELSE(MSVC) + FIND_LIBRARY( + ${_l}_LIB NAMES ${_l} + HINTS + @PROJECT_BINARY_DIR@ + @CMAKE_INSTALL_PREFIX@/bin + @CMAKE_INSTALL_PREFIX@/lib + ) + ENDIF(MSVC) + IF(${_l}_LIB) + MARK_AS_ADVANCED(FORCE ${_l}_LIB) + GET_FILENAME_COMPONENT(_dir ${${_l}_LIB} DIRECTORY) + LIST(APPEND _l_locations ${_dir}) + ENDIF(${_l}_LIB) +ENDFOREACH(_l) +IF(_l_locations) + LIST(REMOVE_DUPLICATES _l_locations) + LINK_DIRECTORIES(${_l_locations}) +ENDIF(_l_locations) + +## ========================= +## == Include directories == +## ========================= + +## TODO: this is not completely correct!!! +INCLUDE_DIRECTORIES( + @CMAKE_INSTALL_PREFIX@/include + @CMAKE_INSTALL_PREFIX@/include/fpa/Instances + @PROJECT_SOURCE_DIR@/lib + @PROJECT_BINARY_DIR@/lib + @PROJECT_SOURCE_DIR@/lib/Instances + @PROJECT_BINARY_DIR@/lib/Instances + ) + +## eof - $RCSfile$ diff --git a/lib/fpa/Image/EndPointsFilter.h b/lib/fpa/Image/EndPointsFilter.h new file mode 100644 index 0000000..afbfb10 --- /dev/null +++ b/lib/fpa/Image/EndPointsFilter.h @@ -0,0 +1,77 @@ +#ifndef __fpa__Image__EndPointsFilter__h__ +#define __fpa__Image__EndPointsFilter__h__ + +#include +#include + +namespace fpa +{ + namespace Image + { + /** + */ + template< class _TDistanceMap, class _TCostMap > + class EndPointsFilter + : public itk::Object + { + public: + typedef EndPointsFilter Self; + typedef itk::Object Superclass; + typedef itk::SmartPointer< Self > Pointer; + typedef itk::SmartPointer< const Self > ConstPointer; + + typedef _TDistanceMap TDistanceMap; + typedef _TCostMap TCostMap; + typedef typename TCostMap::IndexType TIndex; + typedef MinimumSpanningTree< TCostMap::ImageDimension > TMST; + + typedef itk::Functor::IndexLexicographicCompare< _TCostMap::ImageDimension > TIndexCompare; + typedef std::set< TIndex, TIndexCompare > TIndices; + + public: + itkNewMacro( Self ); + itkTypeMacro( fpa::Image::EndPointsFilter, itk::Object ); + + itkGetConstObjectMacro( DistanceMap, _TDistanceMap ); + itkGetConstObjectMacro( CostMap, _TCostMap ); + itkGetConstObjectMacro( MST, TMST ); + + itkSetConstObjectMacro( DistanceMap, _TDistanceMap ); + itkSetConstObjectMacro( CostMap, _TCostMap ); + itkSetConstObjectMacro( MST, TMST ); + + public: + const TIndices& GetBifurcations( ) const; + const TIndices& GetEndPoints( ) const; + + void Compute( ); + + protected: + EndPointsFilter( ); + virtual ~EndPointsFilter( ); + + private: + // Purposely not defined + EndPointsFilter( const Self& other ); + Self& operator=( const Self& other ); + + protected: + typename _TDistanceMap::ConstPointer m_DistanceMap; + typename _TCostMap::ConstPointer m_CostMap; + typename TMST::ConstPointer m_MST; + + TIndices m_Bifurcations; + TIndices m_EndPoints; + }; + + } // ecapseman + +} // ecapseman + +#ifndef ITK_MANUAL_INSTANTIATION +# include +#endif // ITK_MANUAL_INSTANTIATION + +#endif // __fpa__Image__EndPointsFilter__h__ + +// eof - $RCSfile$ diff --git a/lib/fpa/Image/EndPointsFilter.hxx b/lib/fpa/Image/EndPointsFilter.hxx new file mode 100644 index 0000000..c3cb406 --- /dev/null +++ b/lib/fpa/Image/EndPointsFilter.hxx @@ -0,0 +1,135 @@ +#ifndef __fpa__Image__EndPointsFilter__hxx__ +#define __fpa__Image__EndPointsFilter__hxx__ + +#include +#include +#include + +// ------------------------------------------------------------------------- +template< class _TDistanceMap, class _TCostMap > +const typename fpa::Image::EndPointsFilter< _TDistanceMap, _TCostMap >:: +TIndices& fpa::Image::EndPointsFilter< _TDistanceMap, _TCostMap >:: +GetBifurcations( ) const +{ + return( this->m_Bifurcations ); +} + +// ------------------------------------------------------------------------- +template< class _TDistanceMap, class _TCostMap > +const typename fpa::Image::EndPointsFilter< _TDistanceMap, _TCostMap >:: +TIndices& fpa::Image::EndPointsFilter< _TDistanceMap, _TCostMap >:: +GetEndPoints( ) const +{ + return( this->m_EndPoints ); +} + +// ------------------------------------------------------------------------- +template< class _TDistanceMap, class _TCostMap > +void fpa::Image::EndPointsFilter< _TDistanceMap, _TCostMap >:: +Compute( ) +{ + typedef itk::ImageRegionConstIteratorWithIndex< _TDistanceMap > _TDistMapIt; + typedef itk::ImageRegionConstIteratorWithIndex< _TCostMap > _TCostMapIt; + typedef std::multimap< double, TIndex, std::greater< double > > _TQueue; + typedef typename _TQueue::value_type _TQueueValue; + + // Create queue + _TQueue queue; + _TDistMapIt dIt( + this->m_DistanceMap, this->m_DistanceMap->GetRequestedRegion( ) + ); + _TCostMapIt cIt( + this->m_CostMap, this->m_CostMap->GetRequestedRegion( ) + ); + dIt.GoToBegin( ); + cIt.GoToBegin( ); + for( ; !dIt.IsAtEnd( ) && !cIt.IsAtEnd( ); ++dIt, ++cIt ) + { + double d = double( dIt.Get( ) ); + if( d > 0 ) + { + double v = double( cIt.Get( ) ) * d; + queue.insert( _TQueueValue( v, dIt.GetIndex( ) ) ); + + } // fi + + } // rof + + TIndices marks; + while( queue.size( ) > 0 ) + { + auto nIt = queue.begin( ); + auto n = *nIt; + queue.erase( nIt ); + + if( marks.find( n.second ) == marks.end( ) ) + { + std::cout << queue.size( ) << " " << n.first << std::endl; + marks.insert( n.second ); + this->m_EndPoints.insert( n.second ); + auto path = this->m_MST->GetPath( n.second ); + std::cout << path.size( ) << std::endl; + for( auto pIt = path.begin( ); pIt != path.end( ); ++pIt ) + { + double d = double( this->m_DistanceMap->GetPixel( *pIt ) ); + d = std::sqrt( std::fabs( d ) ); + typename _TCostMap::PointType center; + this->m_CostMap->TransformIndexToPhysicalPoint( *pIt, center ); + + std::queue< TIndex > q; + TIndices m; + q.push( *pIt ); + while( q.size( ) > 0 ) + { + TIndex idx = q.front( ); + q.pop( ); + if( m.find( idx ) != m.end( ) ) + continue; + m.insert( idx ); + marks.insert( idx ); + for( unsigned int x = 0; x < _TCostMap::ImageDimension; ++x ) + { + for( int y = -1; y <= 1; y += 2 ) + { + TIndex idx2 = idx; + idx2[ x ] += y; + typename _TCostMap::PointType c; + this->m_CostMap->TransformIndexToPhysicalPoint( idx2, c ); + if( this->m_CostMap->GetRequestedRegion( ).IsInside( idx2 ) ) + { + if( center.EuclideanDistanceTo( c ) <= ( d * 1.5 ) ) + q.push( idx2 ); + + } // fi + + } // rof + + } // rof + + } // elihw + + } // rof + + } // fi + + } // elihw +} + +// ------------------------------------------------------------------------- +template< class _TDistanceMap, class _TCostMap > +fpa::Image::EndPointsFilter< _TDistanceMap, _TCostMap >:: +EndPointsFilter( ) + : Superclass( ) +{ +} + +// ------------------------------------------------------------------------- +template< class _TDistanceMap, class _TCostMap > +fpa::Image::EndPointsFilter< _TDistanceMap, _TCostMap >:: +~EndPointsFilter( ) +{ +} + +#endif // __fpa__Image__EndPointsFilter__hxx__ + +// eof - $RCSfile$ diff --git a/plugins/Plugins/EndPointsFilter.cxx b/plugins/Plugins/EndPointsFilter.cxx new file mode 100644 index 0000000..6d34f8c --- /dev/null +++ b/plugins/Plugins/EndPointsFilter.cxx @@ -0,0 +1,109 @@ +#include +#include +#include +#include +#include + +// ------------------------------------------------------------------------- +fpaPlugins::EndPointsFilter:: +EndPointsFilter( ) + : Superclass( ) +{ + typedef cpPlugins::DataObjects::Image _TImage; + typedef cpPlugins::DataObjects::Mesh _TMesh; + + this->_ConfigureInput< _TImage >( "DistanceMap", true, false ); + this->_ConfigureInput< _TImage >( "CostMap", true, false ); + this->_ConfigureInput< _TImage >( "MST", true, false ); + this->_ConfigureOutput< _TMesh >( "EndPoints" ); + this->_ConfigureOutput< _TMesh >( "Bifurcations" ); +} + +// ------------------------------------------------------------------------- +fpaPlugins::EndPointsFilter:: +~EndPointsFilter( ) +{ +} + +// ------------------------------------------------------------------------- +void fpaPlugins::EndPointsFilter:: +_GenerateData( ) +{ + auto o = this->GetInputData( "DistanceMap" ); + cpPlugins_Demangle_ImageScalars_Dims( o, _GD0 ); + else this->_Error( "Invalid input image." ); +} + +// ------------------------------------------------------------------------- +template< class _TDistanceMap > +void fpaPlugins::EndPointsFilter:: +_GD0( _TDistanceMap* dmap ) +{ + auto cmap = this->GetInputData< _TDistanceMap >( "CostMap" ); + if( cmap != NULL ) + this->_GD1( dmap, cmap ); + else + this->_Error( "Temporary error: invalid cost map." ); +} + +// ------------------------------------------------------------------------- +template< class _TDistanceMap, class _TCostMap > +void fpaPlugins::EndPointsFilter:: +_GD1( _TDistanceMap* dmap, _TCostMap* cmap ) +{ + typedef fpa::Image::EndPointsFilter< _TDistanceMap, _TCostMap > _TFilter; + typedef typename _TFilter::TMST _TMST; + + auto mst = this->GetInputData< _TMST >( "MST" ); + if( mst == NULL ) + this->_Error( "Invalid MST." ); + + + auto filter = this->_CreateITK< _TFilter >( ); + filter->SetDistanceMap( dmap ); + filter->SetCostMap( cmap ); + filter->SetMST( mst ); + filter->Compute( ); + + auto ep = filter->GetEndPoints( ); + auto bi = filter->GetBifurcations( ); + + auto ep_pd = this->GetOutputData< vtkPolyData >( "EndPoints" ); + if( ep_pd == NULL ) + { + auto points = vtkSmartPointer< vtkPoints >::New( ); + auto verts = vtkSmartPointer< vtkCellArray >::New( ); + auto lines = vtkSmartPointer< vtkCellArray >::New( ); + auto polys = vtkSmartPointer< vtkCellArray >::New( ); + auto strips = vtkSmartPointer< vtkCellArray >::New( ); + auto pd = vtkSmartPointer< vtkPolyData >::New( ); + pd->SetPoints( points ); + pd->SetVerts( verts ); + pd->SetLines( lines ); + pd->SetPolys( polys ); + pd->SetStrips( strips ); + + this->GetOutput( "EndPoints" )->SetVTK( pd ); + ep_pd = this->GetOutputData< vtkPolyData >( "EndPoints" ); + + } // fi + + for( auto iIt = ep.begin( ); iIt != ep.end( ); ++iIt ) + { + typename _TCostMap::PointType p; + cmap->TransformIndexToPhysicalPoint( *iIt, p ); + + if( _TCostMap::ImageDimension == 1 ) + ep_pd->GetPoints( )->InsertNextPoint( p[ 0 ], 0, 0 ); + else if( _TCostMap::ImageDimension == 2 ) + ep_pd->GetPoints( )->InsertNextPoint( p[ 0 ], p[ 1 ], 0 ); + else if( _TCostMap::ImageDimension > 2 ) + ep_pd->GetPoints( )->InsertNextPoint( p[ 0 ], p[ 1 ], p[ 2 ] ); + + ep_pd->GetVerts( )->InsertNextCell( 1 ); + ep_pd->GetVerts( )->InsertCellPoint( ep_pd->GetNumberOfPoints( ) - 1 ); + + } // rof +} + +// eof - $RCSfile$ diff --git a/plugins/Plugins/EndPointsFilter.h b/plugins/Plugins/EndPointsFilter.h new file mode 100644 index 0000000..209c9a7 --- /dev/null +++ b/plugins/Plugins/EndPointsFilter.h @@ -0,0 +1,32 @@ +#ifndef __fpa__Plugins__EndPointsFilter__h__ +#define __fpa__Plugins__EndPointsFilter__h__ + +#include +#include + +namespace fpaPlugins +{ + /** + */ + class fpaPlugins_EXPORT EndPointsFilter + : public cpPlugins::BaseObjects::ProcessObject + { + cpPluginsObject( + EndPointsFilter, + cpPlugins::BaseObjects::ProcessObject, + fpa + ); + + protected: + template< class _TDistanceMap > + inline void _GD0( _TDistanceMap* dmap ); + + template< class _TDistanceMap, class _TCostMap > + inline void _GD1( _TDistanceMap* dmap, _TCostMap* cmap ); + }; + +} // ecapseman + +#endif // __fpa__Plugins__EndPointsFilter__h__ + +// eof - $RCSfile$ -- 2.45.1