From 3bcd064e000912302f2f0d3556d518ff46c146aa Mon Sep 17 00:00:00 2001 From: =?utf8?q?Leonardo=20Fl=C3=B3rez-Valencia?= Date: Thu, 5 Oct 2017 16:22:00 -0500 Subject: [PATCH] ... --- CMakeLists.txt | 24 +-- appli/CTArteries/CMakeLists.txt | 12 +- appli/CTArteries/CTArteries.cxx | 113 +++++++---- appli/CTArteries/CTArteries.h | 4 +- appli/CTArteries/Parameters.ui | 4 +- .../algorithms/DijkstraWithMeanAndVariance.h | 4 +- .../algorithms/RandomWalkLabelling.hxx | 27 +-- .../algorithms/RandomWalkSegmentation.h | 5 +- .../algorithms/RandomWalkSegmentation.hxx | 106 +++++----- cmake/Definitions.cmake | 53 ----- cmake/Functions.cmake | 160 --------------- cmake/InstallCommands.cmake | 40 ---- cmake_uninstall.cmake.in | 27 +++ data/axial_CT_slice.mhd | 13 ++ data/axial_CT_slice.raw | Bin 0 -> 65536 bytes data/axial_CT_slice_labels_00.mhd | 13 ++ data/axial_CT_slice_labels_00.raw | Bin 0 -> 65536 bytes examples/image/Dijkstra/CMakeLists.txt | 3 +- examples/image/RandomWalker/CMakeLists.txt | 3 +- examples/image/RegionGrow/CMakeLists.txt | 3 +- lib/fpa/CMakeLists.txt | 12 +- lib/fpa/Common/IncrementalMeanAndVariance.cxx | 74 ------- lib/fpa/Common/IncrementalMeanAndVariance.h | 44 ----- lib/fpa/Common/PeakDetector.cxx | 187 ------------------ lib/fpa/Common/PeakDetector.h | 75 ------- lib/fpa/Filters/Mori.h | 5 +- 26 files changed, 255 insertions(+), 756 deletions(-) delete mode 100644 cmake/Definitions.cmake delete mode 100644 cmake/Functions.cmake delete mode 100644 cmake/InstallCommands.cmake create mode 100644 cmake_uninstall.cmake.in create mode 100644 data/axial_CT_slice.mhd create mode 100644 data/axial_CT_slice.raw create mode 100644 data/axial_CT_slice_labels_00.mhd create mode 100644 data/axial_CT_slice_labels_00.raw delete mode 100644 lib/fpa/Common/IncrementalMeanAndVariance.cxx delete mode 100644 lib/fpa/Common/IncrementalMeanAndVariance.h delete mode 100644 lib/fpa/Common/PeakDetector.cxx delete mode 100644 lib/fpa/Common/PeakDetector.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 184f556..6031b51 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -21,17 +21,8 @@ foreach(_p ${_policies}) endif(POLICY ${_p}) endforeach(_p) -## == Some general configuration -include(cmake/Definitions.cmake) -include(cmake/Functions.cmake) - ## == Find cpPlugins -find_package(cpPlugins CONFIG) -if(NOT cpPlugins_FOUND) - ## == Find individual ITK (for a minimal build) - find_package(ITK CONFIG REQUIRED) - include(${ITK_USE_FILE}) -endif(NOT cpPlugins_FOUND) +find_package(cpPlugins CONFIG REQUIRED) ## == Find eigen3 (http://eigen.tuxfamily.org) find_package(Eigen3 CONFIG) @@ -40,10 +31,21 @@ if(Eigen3_FOUND) endif(Eigen3_FOUND) ## == Build packages +set(fpa_BUILD 1) subdirs(lib examples appli) ## == Installation commands -include(cmake/InstallCommands.cmake) +include(${cpPlugins_INSTALL_FILE}) + +## == Uninstall target +configure_file( + "${CMAKE_CURRENT_SOURCE_DIR}/cmake_uninstall.cmake.in" + "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake" + IMMEDIATE @ONLY + ) +add_custom_target( + uninstall + COMMAND ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake) ## eof - $RCSfile$ diff --git a/appli/CTArteries/CMakeLists.txt b/appli/CTArteries/CMakeLists.txt index 25a4109..f968ebc 100644 --- a/appli/CTArteries/CMakeLists.txt +++ b/appli/CTArteries/CMakeLists.txt @@ -2,9 +2,15 @@ ## @author Leonardo Florez-Valencia (florez-l@javeriana.edu.co) ## ========================================================================= -if(cpPlugins_FOUND) +if(cpPlugins_USE_VTK AND cpPlugins_USE_Qt5) find_package(Qt5 CONFIG REQUIRED COMPONENTS PrintSupport) - BuildApplication(CTArteries fpa cpPlugins::ivq Qt5::PrintSupport) -endif(cpPlugins_FOUND) + BuildApplication( + CTArteries + SOURCE . + INSTALL + RECURRENT + LINKS fpa Qt5::PrintSupport + ) +endif(cpPlugins_USE_VTK AND cpPlugins_USE_Qt5) ## eof - $RCSfile$ diff --git a/appli/CTArteries/CTArteries.cxx b/appli/CTArteries/CTArteries.cxx index 345b94e..8b8a333 100644 --- a/appli/CTArteries/CTArteries.cxx +++ b/appli/CTArteries/CTArteries.cxx @@ -122,6 +122,16 @@ CTArteries( int argc, char* argv[], QWidget* parent ) QT_ACTION_CONN( Open ); QT_ACTION_CONN( Config ); QT_ACTION_CONN( Process ); + + // Load log + if( argc == 3 ) + { + std::string cmd( argv[ 1 ] ); + std::string fname( argv[ 2 ] ); + if( cmd == "-log" ) + this->_ExecuteLog( fname ); + + } // fi } // ------------------------------------------------------------------------- @@ -138,6 +148,13 @@ template< class _TStrings > void CTArteries:: _openImage( const _TStrings& fnames ) { + // Save log + std::ofstream str_log( "CTArteries.log" ); + str_log << fnames.size( ) << std::endl; + for( const std::string& s: fnames ) + str_log << s << std::endl; + str_log.close( ); + // Create appropriate reader itk::ImageSource< TImage >::Pointer reader; if( fnames.size( ) == 1 ) @@ -221,36 +238,17 @@ _showInputImage( ) // ------------------------------------------------------------------------- void CTArteries:: -_process( ) +_process( const std::vector< TImage::PointType >& seeds ) { - // Get seeds - typedef ivq::VTK::SeedWidgetOverImageActor::TSeeds _TSeeds; - if( this->m_Image.IsNull( ) || this->m_Seeds.GetPointer( ) == NULL ) - { - QMessageBox::critical( this, "Error processing", "No valid input image." ); - return; - - } // fi - std::vector< TImage::PointType > seeds; - for( _TSeeds::value_type sValue: this->m_Seeds->GetSeeds( ) ) - { - for( unsigned int i = 0; i < sValue.second.size( ); i += 3 ) - { - TImage::PointType pnt; - pnt[ 0 ] = sValue.second[ i + 0 ]; - pnt[ 1 ] = sValue.second[ i + 1 ]; - pnt[ 2 ] = sValue.second[ i + 2 ]; - seeds.push_back( pnt ); - - } // rof - - } // rof - if( seeds.size( ) < 2 ) - { - QMessageBox::critical( this, "Error processing", "Not enough seeds." ); - return; - - } // fi + // Save log + std::ofstream str_log( "CTArteries.log", std::ios_base::app ); + str_log << this->m_UIParameters->Beta->value( ) << std::endl; + str_log << this->m_UIParameters->Sigma->value( ) << std::endl; + str_log << this->m_UIParameters->Radius->value( ) << std::endl; + str_log << seeds.size( ) << std::endl; + for( TImage::PointType seed: seeds ) + str_log << seed << std::endl; + str_log.close( ); // Create algorithm typedef RandomWalkSegmentation< TImage, TScalarImage > _TSegmentation; @@ -265,7 +263,9 @@ _process( ) seg->AddSeed( seed ); try { + seg->DebugOn( ); seg->Update( ); + seg->DebugOff( ); } catch( std::exception& err ) { @@ -370,12 +370,17 @@ _prepareQuantification( ) while( lines->GetNextCell( npts, ids ) != 0 ) mesh->AddEdge( ids[ 0 ], ids[ 1 ] ); delete ids; - mesh->AddFace( mesh->GetEdge( ) ); _TQEMesh::QEPrimal* edge = mesh->GetEdge( ); - for( auto eIt = edge->BeginGeomLnext( ); eIt != edge->EndGeomLnext( ); ++eIt ) - points.push_back( mesh->GetPoint( *eIt ) ); + if( edge != NULL ) + { + mesh->AddFace( edge ); + edge = mesh->GetEdge( ); + for( auto eIt = edge->BeginGeomLnext( ); eIt != edge->EndGeomLnext( ); ++eIt ) + points.push_back( mesh->GetPoint( *eIt ) ); + + } // fi - TFourier f( points.begin( ), points.end( ), 3 ); + TFourier f( points.begin( ), points.end( ), 6 ); f.SetOrderingToCounterClockWise( ); this->m_Fourier.push_back( f ); @@ -531,6 +536,18 @@ _showProcessResults( ) this->_prepareQuantification( ); } +// ------------------------------------------------------------------------- +void CTArteries:: +_ExecuteLog( const std::string& fname ) +{ + std::ifstream str_log( fname.c_str( ) ); + if( str_log ) + { + str_log.close( ); + + } // fi +} + // ------------------------------------------------------------------------- void CTArteries:: _sOpen( ) @@ -579,7 +596,35 @@ _sConfig( ) void CTArteries:: _sProcess( ) { - this->_process( ); + // Get seeds + typedef ivq::VTK::SeedWidgetOverImageActor::TSeeds _TSeeds; + if( this->m_Image.IsNull( ) || this->m_Seeds.GetPointer( ) == NULL ) + { + QMessageBox::critical( this, "Error processing", "No valid input image." ); + return; + + } // fi + std::vector< TImage::PointType > seeds; + for( _TSeeds::value_type sValue: this->m_Seeds->GetSeeds( ) ) + { + for( unsigned int i = 0; i < sValue.second.size( ); i += 3 ) + { + TImage::PointType pnt; + pnt[ 0 ] = sValue.second[ i + 0 ]; + pnt[ 1 ] = sValue.second[ i + 1 ]; + pnt[ 2 ] = sValue.second[ i + 2 ]; + seeds.push_back( pnt ); + + } // rof + + } // rof + if( seeds.size( ) < 2 ) + { + QMessageBox::critical( this, "Error processing", "Not enough seeds." ); + return; + + } // fi + this->_process( seeds ); this->_showProcessResults( ); } diff --git a/appli/CTArteries/CTArteries.h b/appli/CTArteries/CTArteries.h index 4875917..b3e97c5 100644 --- a/appli/CTArteries/CTArteries.h +++ b/appli/CTArteries/CTArteries.h @@ -72,10 +72,12 @@ protected: void _openDicom( const std::string& dirname ); void _showInputImage( ); - void _process( ); + void _process( const std::vector< TImage::PointType >& seeds ); void _prepareQuantification( ); void _showProcessResults( ); + void _ExecuteLog( const std::string& fname ); + protected slots: void _sOpen( ); void _sConfig( ); diff --git a/appli/CTArteries/Parameters.ui b/appli/CTArteries/Parameters.ui index 2a40238..566bf01 100644 --- a/appli/CTArteries/Parameters.ui +++ b/appli/CTArteries/Parameters.ui @@ -71,7 +71,7 @@ 100000.000000000000000 - 20.000000000000000 + 90.000000000000000 @@ -131,7 +131,7 @@ 100000.000000000000000 - 5.000000000000000 + 7.000000000000000 diff --git a/appli/CTArteries/algorithms/DijkstraWithMeanAndVariance.h b/appli/CTArteries/algorithms/DijkstraWithMeanAndVariance.h index a82c8aa..e5c3274 100644 --- a/appli/CTArteries/algorithms/DijkstraWithMeanAndVariance.h +++ b/appli/CTArteries/algorithms/DijkstraWithMeanAndVariance.h @@ -4,9 +4,9 @@ #ifndef __DijkstraWithMeanAndVariance__h__ #define __DijkstraWithMeanAndVariance__h__ -#include #include #include +#include /** */ @@ -22,7 +22,7 @@ public: typedef typename Superclass::TTraits TTraits; fpaTraitsMacro( typename TTraits ); - typedef fpa::Common::IncrementalMeanAndVariance TMeanAndVar; + typedef ivq::ITK::IncrementalMeanAndVariance TMeanAndVar; public: itkNewMacro( Self ); diff --git a/appli/CTArteries/algorithms/RandomWalkLabelling.hxx b/appli/CTArteries/algorithms/RandomWalkLabelling.hxx index 3cd2c6a..de662f1 100644 --- a/appli/CTArteries/algorithms/RandomWalkLabelling.hxx +++ b/appli/CTArteries/algorithms/RandomWalkLabelling.hxx @@ -47,6 +47,7 @@ void RandomWalkLabelling< _TRawImage, _TCostsImage, _TLabelsImage >:: SetOutsideLabel( const TLabel& v ) { this->SetInitValue( v ); + this->SetFillValue( v ); } // ------------------------------------------------------------------------- @@ -111,9 +112,9 @@ _PostComputeOutputValue( TNode& n ) if( costs->GetPixel( n.Vertex ) == this->m_MaxCost ) { double v = double( raw->GetPixel( n.Vertex ) ); - if( v <= this->m_LowerThreshold ) + if( v < this->m_LowerThreshold ) n.Value = this->GetLowerLabel( ); - else if( v >= this->m_UpperThreshold ) + else if( this->m_UpperThreshold < v ) n.Value = this->GetUpperLabel( ); else n.Value = TLabel( 0 ); @@ -135,17 +136,21 @@ void RandomWalkLabelling< _TRawImage, _TCostsImage, _TLabelsImage >:: _Reinitialize( ) { const TPath* path = this->GetInputPath( ); - while( - this->_GetMark( path->GetVertex( this->m_CurrIdx ) ) > 0 && - this->m_CurrIdx < path->GetSize( ) - ) - this->m_CurrIdx += 1; if( this->m_CurrIdx < path->GetSize( ) ) { - TNode node; - node.Vertex = node.Parent = path->GetVertex( this->m_CurrIdx ); - node.FrontId = 1; - this->_QueuePush( node ); + while( + this->_GetMark( path->GetVertex( this->m_CurrIdx ) ) > 0 && + this->m_CurrIdx < path->GetSize( ) + ) + this->m_CurrIdx += 1; + if( this->m_CurrIdx < path->GetSize( ) ) + { + TNode node; + node.Vertex = node.Parent = path->GetVertex( this->m_CurrIdx ); + node.FrontId = 1; + this->_QueuePush( node ); + + } // fi } // fi } diff --git a/appli/CTArteries/algorithms/RandomWalkSegmentation.h b/appli/CTArteries/algorithms/RandomWalkSegmentation.h index 6644dba..b7199de 100644 --- a/appli/CTArteries/algorithms/RandomWalkSegmentation.h +++ b/appli/CTArteries/algorithms/RandomWalkSegmentation.h @@ -75,7 +75,7 @@ private: void _SynchSeed( const _TIn* in, _TSeed& seed ); template< class _TIn, class _TOutPtr > - void _Smooth( const _TIn* in, _TOutPtr& out ); + void _Smooth( const _TIn* in, _TOutPtr& out, double s ); template< class _TIn, class _TOutPtr, class _TAxisPtr, class _TSeeds > typename _TIn::RegionType _RawSegmentation( @@ -121,6 +121,9 @@ private: _TOutPtr& out_dist, _TAxisPtr& out_axis ); + template< class _TInPtr > + void _Save( const _TInPtr& in, const std::string& fname ); + private: // Purposely not implemented RandomWalkSegmentation( const Self& other ); diff --git a/appli/CTArteries/algorithms/RandomWalkSegmentation.hxx b/appli/CTArteries/algorithms/RandomWalkSegmentation.hxx index 15fb9af..30738e9 100644 --- a/appli/CTArteries/algorithms/RandomWalkSegmentation.hxx +++ b/appli/CTArteries/algorithms/RandomWalkSegmentation.hxx @@ -12,15 +12,7 @@ #include "DijkstraWithMeanAndVariance.h" #include "RandomWalkLabelling.h" -/* TODO - #include - #include - - - #include - - #include -*/ +#include // ------------------------------------------------------------------------- template< class _TInputImage, class _TOutputImage > @@ -140,9 +132,12 @@ GenerateData( ) // Smooth input typename TOutputImage::Pointer smooth_in; - this->_Smooth( this->GetInput( ), smooth_in ); + std::cout << "smooth" << std::endl; + this->_Smooth( this->GetInput( ), smooth_in, 2 ); + this->_Save( smooth_in, "smooth.mhd" ); // Initial segmentation + std::cout << "raw" << std::endl; typename TOutputImage::Pointer init_seg; typename TPath::Pointer init_axis; _TScalar init_mean, init_std; @@ -153,9 +148,12 @@ GenerateData( ) this->m_Beta, init_seg, init_axis, init_mean, init_std ); + std::cout << "Stat: " << init_mean << " +/- " << init_std << std::endl; init_std *= _TScalar( this->m_Sigma ); + this->_Save( init_seg, "raw.mhd" ); // Extract input ROIs + std::cout << "ROI" << std::endl; typename TOutputImage::Pointer smooth_in_roi, init_seg_roi; roi = this->_ROI( smooth_in.GetPointer( ), roi, 10, smooth_in_roi ); this->_ROI( init_seg.GetPointer( ), roi, 0, init_seg_roi ); @@ -164,6 +162,7 @@ GenerateData( ) this->_AxisROI( init_axis.GetPointer( ), roi, init_axis_roi ); // Labelling + std::cout << "labelling" << std::endl; typename _TLabels::Pointer init_labels; _TScalar radius = _TScalar( this->m_Radius ); this->_Label( @@ -173,17 +172,20 @@ GenerateData( ) init_mean, init_std, radius, init_labels ); + this->_Save( init_labels, "init_labels.mhd" ); // Random walker + std::cout << "random walker " << init_std << " " << this->m_Beta << std::endl; typename _TLabels::Pointer rw_seg; this->_RandomWalker( smooth_in_roi.GetPointer( ), init_labels.GetPointer( ), - init_std / _TScalar( 2 ), + this->m_Beta, // init_std / _TScalar( 2 ), rw_seg ); // ROI outputs + std::cout << "axis" << std::endl; typename TOutputImage::Pointer out_dist; typename TPath::Pointer out_axis; this->_DistanceAndAxis( @@ -193,37 +195,34 @@ GenerateData( ) ); // Put everything back to requested region - /* TODO - std::cout << "6" << std::endl; - { // begin - TOutputImage* output = this->GetOutput( ); - output->SetBufferedRegion( output->GetRequestedRegion( ) ); - output->Allocate( ); - output->FillBuffer( -std::numeric_limits< _TScalar >::max( ) ); - - itk::ImageRegionConstIterator< TOutputImage > rIt( - output_roi, output_roi->GetRequestedRegion( ) - ); - itk::ImageRegionIterator< TOutputImage > oIt( output, roi ); - rIt.GoToBegin( ); - oIt.GoToBegin( ); - for( ; !rIt.IsAtEnd( ); ++rIt, ++oIt ) - oIt.Set( rIt.Get( ) ); - - TPath* output_axis = this->GetOutputAxis( ); - output_axis->SetReferenceImage( output ); - for( unsigned long i = 0; i < output_axis_roi->GetSize( ); ++i ) - { - TIndex v = output_axis_roi->GetVertex( i ); - for( unsigned int d = 0; d < TInputImage::ImageDimension; ++d ) - v[ d ] += roi.GetIndex( )[ d ]; - output_axis->AddVertex( v ); - - } // rof - - } // end - std::cout << "7" << std::endl; - */ + std::cout << "output" << std::endl; + { // begin + TOutputImage* output = this->GetOutput( ); + output->SetBufferedRegion( output->GetRequestedRegion( ) ); + output->Allocate( ); + output->FillBuffer( -std::numeric_limits< _TScalar >::max( ) ); + + itk::ImageRegionConstIterator< TOutputImage > rIt( + out_dist, out_dist->GetRequestedRegion( ) + ); + itk::ImageRegionIterator< TOutputImage > oIt( output, roi ); + rIt.GoToBegin( ); + oIt.GoToBegin( ); + for( ; !rIt.IsAtEnd( ); ++rIt, ++oIt ) + oIt.Set( rIt.Get( ) ); + + TPath* output_axis = this->GetOutputAxis( ); + output_axis->SetReferenceImage( output ); + for( unsigned long i = 0; i < out_axis->GetSize( ); ++i ) + { + TIndex v = out_axis->GetVertex( i ); + for( unsigned int d = 0; d < TInputImage::ImageDimension; ++d ) + v[ d ] += roi.GetIndex( )[ d ]; + output_axis->AddVertex( v ); + + } // rof + + } // end } // ------------------------------------------------------------------------- @@ -243,7 +242,7 @@ _SynchSeed( const _TIn* in, _TSeed& seed ) template< class _TInputImage, class _TOutputImage > template< class _TIn, class _TOutPtr > void RandomWalkSegmentation< _TInputImage, _TOutputImage >:: -_Smooth( const _TIn* in, _TOutPtr& out ) +_Smooth( const _TIn* in, _TOutPtr& out, double s ) { typedef typename _TOutPtr::ObjectType _TOut; typedef itk::SmoothingRecursiveGaussianImageFilter< _TIn, _TOut > _TSmooth; @@ -251,7 +250,7 @@ _Smooth( const _TIn* in, _TOutPtr& out ) typename _TSmooth::Pointer smooth = _TSmooth::New( ); smooth->SetInput( in ); smooth->SetNormalizeAcrossScale( true ); - smooth->SetSigmaArray( in->GetSpacing( ) * double( 2 ) ); + smooth->SetSigmaArray( in->GetSpacing( ) * s ); smooth->Update( ); out = smooth->GetOutput( ); out->DisconnectPipeline( ); @@ -380,6 +379,10 @@ _Label( label->Update( ); out = label->GetOutputLabels( ); out->DisconnectPipeline( ); + + std::cout << label->GetLowerThreshold( ) << std::endl; + std::cout << label->GetUpperThreshold( ) << std::endl; + } // ------------------------------------------------------------------------- @@ -447,7 +450,20 @@ _DistanceAndAxis( extract->Update( ); out_axis = TPath::New( ); out_axis->Graft( extract->GetOutput( ) ); - this->_Smooth( extract->GetCenterness( )->GetOutput( ), out_dist ); + this->_Smooth( extract->GetCenterness( )->GetOutput( ), out_dist, 1 ); +} + +// ------------------------------------------------------------------------- +template< class _TInputImage, class _TOutputImage > +template< class _TInPtr > +void RandomWalkSegmentation< _TInputImage, _TOutputImage >:: +_Save( const _TInPtr& in, const std::string& fname ) +{ + typedef itk::ImageFileWriter< typename _TInPtr::ObjectType > _TWriter; + typename _TWriter::Pointer w = _TWriter::New( ); + w->SetInput( in ); + w->SetFileName( fname ); + w->Update( ); } #endif // __RandomWalkSegmentation__hxx__ diff --git a/cmake/Definitions.cmake b/cmake/Definitions.cmake deleted file mode 100644 index 46fb5cf..0000000 --- a/cmake/Definitions.cmake +++ /dev/null @@ -1,53 +0,0 @@ -## ========================================================================= -## @author Leonardo Florez-Valencia (florez-l@javeriana.edu.co) -## ========================================================================= - -## == If working on a MacOSX, activate the use of RPATH's -## == Furthermore: prepare the type of executables -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." 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 -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$ diff --git a/cmake/Functions.cmake b/cmake/Functions.cmake deleted file mode 100644 index 1649a0b..0000000 --- a/cmake/Functions.cmake +++ /dev/null @@ -1,160 +0,0 @@ -## ========================================================================= -## @author Leonardo Florez-Valencia (florez-l@javeriana.edu.co) -## ========================================================================= - -## ------------------------------------------------------------------------- -function(BuildLibrary lib typ src maj min rel) - -## -- Get sources -set(_files) -foreach(_s ${src}) - - ## -- Canonicalize path - get_filename_component(_p "${_s}" ABSOLUTE) - - ## -- Check type of input - if(IS_DIRECTORY ${_p}) - file(GLOB _f "${_p}/*") - foreach(_x ${_f}) - if(NOT IS_DIRECTORY ${_x}) - list(APPEND _files ${_x}) - endif(NOT IS_DIRECTORY ${_x}) - endforeach(_x) - else(IS_DIRECTORY ${_p}) - list(APPEND _files ${_p}) - endif(IS_DIRECTORY ${_p}) - -endforeach(_s) - -## -- Process sources -set(_cpp) -set(_hpp) -set(_qui) -foreach(_f ${_files}) - - ## -- Separate filename from extension - string(REGEX REPLACE "\\.[^.]*$" "" _name ${_f}) - string(REPLACE ${_name} "" _ext ${_f}) - set(_out_name ${_name}) - set(_out_ext ${_ext}) - - ## -- Process .in files - string(COMPARE EQUAL "${_ext}" ".in" _in_cmp) - if(_in_cmp) - string(REPLACE ${PROJECT_SOURCE_DIR} ${PROJECT_BINARY_DIR} _out ${_name}) - configure_file(${_f} ${_out} @ONLY) - string(REGEX REPLACE "\\.[^.]*$" "" _out_name ${_out}) - string(REPLACE ${_out_name} "" _out_ext ${_out}) - endif(_in_cmp) - - ## -- Now, get real extension - string(SUBSTRING ${_out_ext} 0 2 _ext_cmp) - - ## -- Process .c?? files - string(COMPARE EQUAL "${_ext_cmp}" ".c" _c_cmp) - if(_c_cmp) - list(APPEND _cpp ${_out_name}${_out_ext}) - endif(_c_cmp) - - ## -- Process .h?? files - string(COMPARE EQUAL "${_ext_cmp}" ".h" _h_cmp) - if(_h_cmp) - list(APPEND _hpp ${_out_name}${_out_ext}) - endif(_h_cmp) - - ## -- Process .ui files - string(COMPARE EQUAL "${_out_ext}" ".ui" _u_cmp) - if(_u_cmp) - list(APPEND _qui ${_out_name}${_out_ext}) - endif(_u_cmp) - -endforeach(_f) - -## -- Process Qt ui files -list(LENGTH _qui _qui_len) -if(${_qui_len} GREATER 0) - qt5_wrap_ui(_qui_hpp ${_qui}) -endif(${_qui_len} GREATER 0) - -## -- Real build -add_library(${lib} ${typ} ${_cpp} ${_hpp} ${_qui_hpp}) - -## -- Header creation -generate_export_header(${lib}) -set_property(TARGET ${lib} PROPERTY VERSION "${maj}.${min}.${rel}") -set_property(TARGET ${lib} PROPERTY SOVERSION ${maj}) -set_property(TARGET ${lib} PROPERTY INTERFACE_${lib}_MAJOR_VERSION ${maj}) -set_property(TARGET ${lib} APPEND PROPERTY COMPATIBLE_INTERFACE_STRING ${maj}) - -## -- Link library -target_link_libraries(${lib} PUBLIC ${ARGN}) - -## -- Installation rules -option(${lib}_INSTALL_DEVEL "Install development files for ${lib}" OFF) -string(COMPARE EQUAL "${type}" "SHARED" _cmp) -if(_cmp OR ${lib}_INSTALL_DEVEL) - install( - TARGETS ${lib} - EXPORT "${targets_export_name}" - LIBRARY DESTINATION "lib" - ARCHIVE DESTINATION "lib" - RUNTIME DESTINATION "bin" - INCLUDES DESTINATION "${include_install_dir}" - ) -endif(_cmp OR ${lib}_INSTALL_DEVEL) -if(${lib}_INSTALL_DEVEL) - string(TOLOWER ${lib} _lower_lib) - set( - _install_hdr - ${_hpp} - ${CMAKE_CURRENT_BINARY_DIR}/${_lower_lib}_export.h - ) - set(_install_dirs) - foreach(_h ${_install_hdr}) - string(REPLACE ${CMAKE_CURRENT_SOURCE_DIR} "" _h_name ${_h}) - string(COMPARE EQUAL "${_h_name}" "${_h}" _h_cmp) - if(_h_cmp) - string(REPLACE ${CMAKE_CURRENT_BINARY_DIR} "" _h_name ${_h}) - endif(_h_cmp) - set(_h_out ${include_install_dir}/${lib}${_h_name}) - get_filename_component(_h_dir ${_h_out} DIRECTORY) - install( - FILES "${_h}" - DESTINATION "${_h_dir}" - ) - endforeach(_h) -endif(${lib}_INSTALL_DEVEL) - -endfunction() - -## ------------------------------------------------------------------------- -function(BuildLibraryRecursive lib typ dir maj min rel) - -## -- Globbing directory -file(GLOB_RECURSE _files "${dir}/*") - -## -- Build library -BuildLibrary(${lib} ${typ} "${_files}" ${maj} ${min} ${rel} ${ARGN}) - -endfunction() - -## ------------------------------------------------------------------------- -function(BuildApplication app) -option(BUILD_${app} "Build ${app}" OFF) -if(BUILD_${app}) - ## -- Use a static library - BuildLibraryRecursive( - _${app}_ STATIC ${CMAKE_CURRENT_SOURCE_DIR} 0 0 0 ${ARGN} - ) - - ## -- Create an empty application - set(_m ${CMAKE_CURRENT_BINARY_DIR}/__main__${app}.cxx) - file(WRITE ${_m} "// Automatically generated dummy file") - add_executable(${app} ${EXECUTABLE_TYPE} ${_m}) - - ## -- Link it against static library - target_link_libraries(${app} PUBLIC _${app}_) -endif(BUILD_${app}) -endfunction() - -## eof - $RCSfile$ diff --git a/cmake/InstallCommands.cmake b/cmake/InstallCommands.cmake deleted file mode 100644 index 97500ae..0000000 --- a/cmake/InstallCommands.cmake +++ /dev/null @@ -1,40 +0,0 @@ -## ========================================================================= -## @author Leonardo Florez-Valencia (florez-l@javeriana.edu.co) -## ========================================================================= - -## ========================= -## == Installation values == -## ========================= - -set(config_install_dir "lib/cmake/${PROJECT_NAME}") -set(include_install_dir "include") -set(generated_dir "${PROJECT_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}::") - -## =============================== -## == 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( - EXPORT "${targets_export_name}" - NAMESPACE "${namespace}" - DESTINATION "${config_install_dir}" - ) -install( - FILES "${project_config}" - DESTINATION "${config_install_dir}" - ) - -## eof - $RCSfile$ diff --git a/cmake_uninstall.cmake.in b/cmake_uninstall.cmake.in new file mode 100644 index 0000000..34c9330 --- /dev/null +++ b/cmake_uninstall.cmake.in @@ -0,0 +1,27 @@ +## ========================================================================= +## @author Leonardo Florez-Valencia (florez-l@javeriana.edu.co) +## ========================================================================= + +if(NOT EXISTS "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt") + message(FATAL_ERROR "Cannot find install manifest: @CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt") +endif(NOT EXISTS "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt") + +file(READ "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt" files) +string(REGEX REPLACE "\n" ";" files "${files}") +foreach(file ${files}) + message(STATUS "Uninstalling $ENV{DESTDIR}${file}") + if(IS_SYMLINK "$ENV{DESTDIR}${file}" OR EXISTS "$ENV{DESTDIR}${file}") + exec_program( + "@CMAKE_COMMAND@" ARGS "-E remove \"$ENV{DESTDIR}${file}\"" + OUTPUT_VARIABLE rm_out + RETURN_VALUE rm_retval + ) + if(NOT "${rm_retval}" STREQUAL 0) + message(FATAL_ERROR "Problem when removing $ENV{DESTDIR}${file}") + endif(NOT "${rm_retval}" STREQUAL 0) + else(IS_SYMLINK "$ENV{DESTDIR}${file}" OR EXISTS "$ENV{DESTDIR}${file}") + message(STATUS "File $ENV{DESTDIR}${file} does not exist.") + endif(IS_SYMLINK "$ENV{DESTDIR}${file}" OR EXISTS "$ENV{DESTDIR}${file}") +endforeach(file) + +## eof - $RCSfile$ diff --git a/data/axial_CT_slice.mhd b/data/axial_CT_slice.mhd new file mode 100644 index 0000000..ee256bf --- /dev/null +++ b/data/axial_CT_slice.mhd @@ -0,0 +1,13 @@ +ObjectType = Image +NDims = 2 +BinaryData = True +BinaryDataByteOrderMSB = False +CompressedData = False +TransformMatrix = 1 0 0 1 +Offset = 0 0 +CenterOfRotation = 0 0 +ElementSpacing = 1 1 +DimSize = 256 256 +AnatomicalOrientation = ?? +ElementType = MET_UCHAR +ElementDataFile = axial_CT_slice.raw diff --git a/data/axial_CT_slice.raw b/data/axial_CT_slice.raw new file mode 100644 index 0000000000000000000000000000000000000000..ffce46323a72974459506cc1411f06ad54ab905a GIT binary patch literal 65536 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 literal 0 HcmV?d00001 diff --git a/data/axial_CT_slice_labels_00.mhd b/data/axial_CT_slice_labels_00.mhd new file mode 100644 index 0000000..47eca6b --- /dev/null +++ b/data/axial_CT_slice_labels_00.mhd @@ -0,0 +1,13 @@ +ObjectType = Image +NDims = 2 +BinaryData = True +BinaryDataByteOrderMSB = False +CompressedData = False +TransformMatrix = 1 0 0 1 +Offset = 0 0 +CenterOfRotation = 0 0 +ElementSpacing = 1 1 +DimSize = 256 256 +AnatomicalOrientation = ?? +ElementType = MET_UCHAR +ElementDataFile = axial_CT_slice_labels_00.raw diff --git a/data/axial_CT_slice_labels_00.raw b/data/axial_CT_slice_labels_00.raw new file mode 100644 index 0000000000000000000000000000000000000000..a1ce172836b2f35c9fc2f2a47a801289beb0cfa0 GIT binary patch literal 65536 zcmeIsK@9)^2*fbJzi31dl6$lQmQ?`&00000000000000000000000000000000000 t000000000y>8CCL00000000000000 -#include - -// ------------------------------------------------------------------------- -fpa::Common::IncrementalMeanAndVariance:: -IncrementalMeanAndVariance( ) -{ - this->Clear( ); -} - -// ------------------------------------------------------------------------- -fpa::Common::IncrementalMeanAndVariance:: -~IncrementalMeanAndVariance( ) -{ -} - -// ------------------------------------------------------------------------- -double fpa::Common::IncrementalMeanAndVariance:: -GetMean( ) const -{ - return( this->m_M ); -} - -// ------------------------------------------------------------------------- -double fpa::Common::IncrementalMeanAndVariance:: -GetVariance( ) const -{ - return( this->m_V ); -} - -// ------------------------------------------------------------------------- -double fpa::Common::IncrementalMeanAndVariance:: -GetDeviation( ) const -{ - return( std::sqrt( this->m_V ) ); -} - -// ------------------------------------------------------------------------- -unsigned long fpa::Common::IncrementalMeanAndVariance:: -GetNumberOfSamples( ) const -{ - return( ( unsigned long )( this->m_N ) ); -} - -// ------------------------------------------------------------------------- -void fpa::Common::IncrementalMeanAndVariance:: -Clear( ) -{ - this->m_M = double( 0 ); - this->m_V = double( 0 ); - this->m_N = double( 0 ); -} - -// ------------------------------------------------------------------------- -void fpa::Common::IncrementalMeanAndVariance:: -AddValue( double v ) -{ - this->m_N += double( 1 ); - double d = v - this->m_M; - if( this->m_N > double( 1 ) ) - { - double o = ( this->m_N - double( 2 ) ) / ( this->m_N - double( 1 ) ); - this->m_V = ( o * this->m_V ) + ( ( d * d ) / this->m_N ); - } - else - this->m_V = double( 0 ); - this->m_M += d / this->m_N; -} - -// eof - $RCSfile$ diff --git a/lib/fpa/Common/IncrementalMeanAndVariance.h b/lib/fpa/Common/IncrementalMeanAndVariance.h deleted file mode 100644 index 83383c3..0000000 --- a/lib/fpa/Common/IncrementalMeanAndVariance.h +++ /dev/null @@ -1,44 +0,0 @@ -// ========================================================================= -// @author Leonardo Florez Valencia -// @email florez-l@javeriana.edu.co -// ========================================================================= -#ifndef __fpa__Common__IncrementalMeanAndVariance__h__ -#define __fpa__Common__IncrementalMeanAndVariance__h__ - -#include - -namespace fpa -{ - namespace Common - { - /** - */ - class FPA_EXPORT IncrementalMeanAndVariance - { - public: - typedef IncrementalMeanAndVariance Self; - - public: - IncrementalMeanAndVariance( ); - virtual ~IncrementalMeanAndVariance( ); - - double GetMean( ) const; - double GetVariance( ) const; - double GetDeviation( ) const; - unsigned long GetNumberOfSamples( ) const; - - void Clear( ); - void AddValue( double v ); - - protected: - double m_M; - double m_V; - double m_N; - }; - - } // ecapseman - -} // ecapseman - -#endif // __fpa__Common__IncrementalMeanAndVariance__h__ -// eof - $RCSfile$ diff --git a/lib/fpa/Common/PeakDetector.cxx b/lib/fpa/Common/PeakDetector.cxx deleted file mode 100644 index 0a53e1e..0000000 --- a/lib/fpa/Common/PeakDetector.cxx +++ /dev/null @@ -1,187 +0,0 @@ -// ========================================================================= -// @author Leonardo Florez Valencia -// @email florez-l@javeriana.edu.co -// ========================================================================= -#include -#include - -// ------------------------------------------------------------------------- -fpa::Common::PeakDetector:: -PeakDetector( ) - : m_K( 3 ), - m_T( 3.5 ), - m_I( 0.5 ) -{ -} - -// ------------------------------------------------------------------------- -fpa::Common::PeakDetector:: -~PeakDetector( ) -{ -} - -// ------------------------------------------------------------------------- -unsigned long fpa::Common::PeakDetector:: -GetKernelSize( ) const -{ - return( this->m_K ); -} - -// ------------------------------------------------------------------------- -double fpa::Common::PeakDetector:: -GetThreshold( ) const -{ - return( this->m_T ); -} - -// ------------------------------------------------------------------------- -double fpa::Common::PeakDetector:: -GetInfluence( ) const -{ - return( this->m_I ); -} - -// ------------------------------------------------------------------------- -void fpa::Common::PeakDetector:: -SetKernelSize( unsigned long k ) -{ - this->m_K = k; - this->Clear( ); -} - -// ------------------------------------------------------------------------- -void fpa::Common::PeakDetector:: -SetThreshold( double t ) -{ - this->m_T = t; - this->Clear( ); -} - -// ------------------------------------------------------------------------- -void fpa::Common::PeakDetector:: -SetInfluence( double i ) -{ - this->m_I = i; - this->Clear( ); -} - -// ------------------------------------------------------------------------- -void fpa::Common::PeakDetector:: -Clear( ) -{ - this->m_X.clear( ); - this->m_Y.clear( ); - this->m_YF.clear( ); - this->m_Avg.clear( ); - this->m_STD.clear( ); - this->m_Peaks.clear( ); - this->m_MeanAndVar.Clear( ); -} - -// ------------------------------------------------------------------------- -const std::vector< double >& fpa::Common::PeakDetector:: -GetXValues( ) const -{ - return( this->m_X ); -} - -// ------------------------------------------------------------------------- -const std::vector< double >& fpa::Common::PeakDetector:: -GetYValues( ) const -{ - return( this->m_Y ); -} - -// ------------------------------------------------------------------------- -const std::vector< double >& fpa::Common::PeakDetector:: -GetFilteredYValues( ) const -{ - return( this->m_YF ); -} - -// ------------------------------------------------------------------------- -const std::vector< double >& fpa::Common::PeakDetector:: -GetAverages( ) const -{ - return( this->m_Avg ); -} - -// ------------------------------------------------------------------------- -const std::vector< double >& fpa::Common::PeakDetector:: -GetDeviations( ) const -{ - return( this->m_STD ); -} - -// ------------------------------------------------------------------------- -const std::vector< fpa::Common::PeakDetector::TPeak >& fpa::Common:: -PeakDetector::GetPeaks( ) const -{ - return( this->m_Peaks ); -} - -// ------------------------------------------------------------------------- -unsigned long fpa::Common::PeakDetector:: -GetNumberOfSamples( ) const -{ - return( this->m_X.size( ) ); -} - -// ------------------------------------------------------------------------- -fpa::Common::PeakDetector:: -TPeak fpa::Common::PeakDetector:: -AddValue( double x, double y ) -{ - this->m_X.push_back( x ); - this->m_Y.push_back( y ); - - if( this->m_YF.size( ) < this->m_K ) - { - this->m_YF.push_back( y ); - this->m_Avg.push_back( double( 0 ) ); - this->m_STD.push_back( double( 0 ) ); - this->m_Peaks.push_back( Self::NoPeak ); - - this->m_MeanAndVar.AddValue( y ); - if( this->m_YF.size( ) == this->m_K ) - { - this->m_Avg.push_back( this->m_MeanAndVar.GetMean( ) ); - this->m_STD.push_back( this->m_MeanAndVar.GetDeviation( ) ); - - } // fi - } - else - { - unsigned long i = this->m_X.size( ) - 1; - if( - ( std::fabs( y - this->m_Avg[ i - 1 ] ) ) > - ( this->m_T * this->m_STD[ i - 1 ] ) - ) - { - this->m_Peaks.push_back( - ( y > this->m_Avg[ i - 1 ] )? Self::PosPeak: Self::NegPeak - ); - this->m_YF.push_back( - ( this->m_I * y ) + - ( ( double( 1 ) - this->m_I ) * this->m_YF[ i - 1 ] ) - ); - } - else - { - this->m_Peaks.push_back( Self::NoPeak ); - this->m_YF.push_back( y ); - - } // fi - - this->m_MeanAndVar.Clear( ); - unsigned long k = 0; - for( unsigned long j = i - this->m_K; j <= i; ++j, ++k ) - this->m_MeanAndVar.AddValue( this->m_YF[ j ] ); - this->m_Avg.push_back( this->m_MeanAndVar.GetMean( ) ); - this->m_STD.push_back( this->m_MeanAndVar.GetDeviation( ) ); - - } // fi - return( this->m_Peaks.back( ) ); -} - -// eof - $RCSfile$ diff --git a/lib/fpa/Common/PeakDetector.h b/lib/fpa/Common/PeakDetector.h deleted file mode 100644 index 8796cc3..0000000 --- a/lib/fpa/Common/PeakDetector.h +++ /dev/null @@ -1,75 +0,0 @@ -// ========================================================================= -// @author Leonardo Florez Valencia -// @email florez-l@javeriana.edu.co -// ========================================================================= -#ifndef __fpa__Common__PeakDetector__h__ -#define __fpa__Common__PeakDetector__h__ - -#include -#include -#include - -namespace fpa -{ - namespace Common - { - /** - */ - /** - * https://stackoverflow.com/questions/22583391/peak-signal-detection-in-realtime-timeseries-data - */ - class FPA_EXPORT PeakDetector - { - public: - typedef PeakDetector Self; - - enum TPeak - { - NoPeak = 0, - PosPeak, - NegPeak - }; - - public: - PeakDetector( ); - virtual ~PeakDetector( ); - - unsigned long GetKernelSize( ) const; - double GetThreshold( ) const; - double GetInfluence( ) const; - - void SetKernelSize( unsigned long k ); - void SetThreshold( double t ); - void SetInfluence( double i ); - - const std::vector< double >& GetXValues( ) const; - const std::vector< double >& GetYValues( ) const; - const std::vector< double >& GetFilteredYValues( ) const; - const std::vector< double >& GetAverages( ) const; - const std::vector< double >& GetDeviations( ) const; - const std::vector< TPeak >& GetPeaks( ) const; - - void Clear( ); - unsigned long GetNumberOfSamples( ) const; - TPeak AddValue( double x, double y ); - - protected: - unsigned long m_K; - double m_T; - double m_I; - - std::vector< double > m_X; - std::vector< double > m_Y; - std::vector< double > m_YF; - std::vector< double > m_Avg; - std::vector< double > m_STD; - std::vector< TPeak > m_Peaks; - fpa::Common::IncrementalMeanAndVariance m_MeanAndVar; - }; - - } // ecapseman - -} // ecapseman - -#endif // __fpa__Common__PeakDetector__h__ -// eof - $RCSfile$ diff --git a/lib/fpa/Filters/Mori.h b/lib/fpa/Filters/Mori.h index 14e8c53..df99fb7 100644 --- a/lib/fpa/Filters/Mori.h +++ b/lib/fpa/Filters/Mori.h @@ -6,10 +6,11 @@ #define __fpa__Filters__Mori__h__ #include -#include #include #include +#include + namespace fpa { namespace Filters @@ -31,7 +32,7 @@ namespace fpa fpaTraitsMacro( typename TTraits ); typedef std::set< TInputValue > TThresholds; - typedef fpa::Common::PeakDetector TPeakDetector; + typedef ivq::ITK::PeakDetector TPeakDetector; typedef TPeakDetector::TPeak TPeak; typedef fpa::Functors::RegionGrow::BinaryThreshold< TInputValue > TPredicate; -- 2.50.0