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.49.0