From 03200c96631e0c6e35b5be9c78d651185efcbdf2 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Leonardo=20Fl=C3=B3rez-Valencia?= Date: Thu, 17 Aug 2017 16:11:47 -0500 Subject: [PATCH] ... --- CMakeLists.txt | 2 +- appli/CTBronchi/CMakeLists.txt | 6 +- appli/CTBronchi/MoriLabelling.h | 128 ++++++----- appli/CTBronchi/MoriLabelling.hxx | 368 +++++++++++++++--------------- appli/CTBronchi/Process.cxx | 253 ++++++++++++++++++-- lib/fpa/Filters/Image/Mori.h | 14 +- lib/fpa/Filters/Image/Mori.hxx | 46 ++++ lib/fpa/Filters/Mori.h | 1 - 8 files changed, 537 insertions(+), 281 deletions(-) create mode 100644 lib/fpa/Filters/Image/Mori.hxx diff --git a/CMakeLists.txt b/CMakeLists.txt index 13e90cb..3e9783b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -119,7 +119,7 @@ set(namespace "${PROJECT_NAME}::") ## == Build different parts == ## =========================== -subdirs(lib tests) +subdirs(appli lib tests) ## =============================== ## == Global installation rules == diff --git a/appli/CTBronchi/CMakeLists.txt b/appli/CTBronchi/CMakeLists.txt index 5b20064..5044d58 100644 --- a/appli/CTBronchi/CMakeLists.txt +++ b/appli/CTBronchi/CMakeLists.txt @@ -14,13 +14,11 @@ if(fpa_BUILD_CTBronchi) set(_pfx fpa_CTBronchi_) set( _examples - MoriSegmentation - MoriLabelling - RandomWalker + Process ) foreach(_e ${_examples}) add_executable(${_pfx}${_e} ${_e}.cxx) - target_link_libraries(${_pfx}${_e} ivq::ivq fpa) + target_link_libraries(${_pfx}${_e} fpa) endforeach(_e) endif(fpa_BUILD_CTBronchi) diff --git a/appli/CTBronchi/MoriLabelling.h b/appli/CTBronchi/MoriLabelling.h index 127ec0f..0a9c586 100644 --- a/appli/CTBronchi/MoriLabelling.h +++ b/appli/CTBronchi/MoriLabelling.h @@ -6,73 +6,77 @@ #ifndef __CTBronchi__MoriLabelling__h__ #define __CTBronchi__MoriLabelling__h__ -#include -#include -#include -#include -#include -#include +/* TODO + #include + #include + #include + #include + #include + #include +*/ namespace CTBronchi { /** */ - template< class _TInputImage, class _TLabelImage, class _TTraits = fpa::Image::DefaultTraits< _TInputImage, _TLabelImage, typename _TLabelImage::PixelType > > - class MoriLabelling - : public fpa::Base::RegionGrow< fpa::Image::Algorithm< _TTraits, fpa::Base::MarksInterface< _TTraits >, fpa::Image::LabelledSeedsInterface< _TTraits > > > - { - public: - typedef _TInputImage TInputImage; - typedef _TLabelImage TLabelImage; - typedef _TTraits TTraits; - fpa_Base_TraitTypes( typename TTraits ); - - typedef fpa::Base::MarksInterface< TTraits > TMarksInterface; - typedef fpa::Image::LabelledSeedsInterface< TTraits > TSeedsInterface; - typedef fpa::Image::Algorithm< TTraits, TMarksInterface, TSeedsInterface > TAlgorithm; - - typedef MoriLabelling Self; - typedef fpa::Base::RegionGrow< TAlgorithm > Superclass; - typedef itk::SmartPointer< Self > Pointer; - typedef itk::SmartPointer< const Self > ConstPointer; - - typedef fpa::Base::Functors::RegionGrow::BinaryThreshold< TInputValue > TThresholdFunction; - - public: - itkNewMacro( Self ); - itkTypeMacro( MoriLabelling, fpa::Base::RegionGrow ); - - itkGetConstMacro( InsideLabel, TOutputValue ); - itkSetMacro( InsideLabel, TOutputValue ); - - public: - const TLabelImage* GetInputLabelImage( ) const; - void SetInputLabelImage( TLabelImage* image ); - - const TInputImage* GetInputRawImage( ) const; - void SetInputRawImage( TInputImage* image ); - - TInputValue GetUpperThreshold( ) const; - void SetUpperThreshold( TInputValue t ); - - TOutputValue GetOutsideValue( ) const; - void SetOutsideLabel( TOutputValue o ); - - protected: - MoriLabelling( ); - virtual ~MoriLabelling( ); - - virtual TNodes _UnifySeeds( ) override; - virtual void _UpdateOutputValue( TNode& n ) override; - - private: - // Purposely not implemented. - MoriLabelling( const Self& other ); - Self& operator=( const Self& other ); - - protected: - TOutputValue m_InsideLabel; - }; + /* TODO + template< class _TInputImage, class _TLabelImage, class _TTraits = fpa::Image::DefaultTraits< _TInputImage, _TLabelImage, typename _TLabelImage::PixelType > > + class MoriLabelling + : public fpa::Base::RegionGrow< fpa::Image::Algorithm< _TTraits, fpa::Base::MarksInterface< _TTraits >, fpa::Image::LabelledSeedsInterface< _TTraits > > > + { + public: + typedef _TInputImage TInputImage; + typedef _TLabelImage TLabelImage; + typedef _TTraits TTraits; + fpa_Base_TraitTypes( typename TTraits ); + + typedef fpa::Base::MarksInterface< TTraits > TMarksInterface; + typedef fpa::Image::LabelledSeedsInterface< TTraits > TSeedsInterface; + typedef fpa::Image::Algorithm< TTraits, TMarksInterface, TSeedsInterface > TAlgorithm; + + typedef MoriLabelling Self; + typedef fpa::Base::RegionGrow< TAlgorithm > Superclass; + typedef itk::SmartPointer< Self > Pointer; + typedef itk::SmartPointer< const Self > ConstPointer; + + typedef fpa::Base::Functors::RegionGrow::BinaryThreshold< TInputValue > TThresholdFunction; + + public: + itkNewMacro( Self ); + itkTypeMacro( MoriLabelling, fpa::Base::RegionGrow ); + + itkGetConstMacro( InsideLabel, TOutputValue ); + itkSetMacro( InsideLabel, TOutputValue ); + + public: + const TLabelImage* GetInputLabelImage( ) const; + void SetInputLabelImage( TLabelImage* image ); + + const TInputImage* GetInputRawImage( ) const; + void SetInputRawImage( TInputImage* image ); + + TInputValue GetUpperThreshold( ) const; + void SetUpperThreshold( TInputValue t ); + + TOutputValue GetOutsideValue( ) const; + void SetOutsideLabel( TOutputValue o ); + + protected: + MoriLabelling( ); + virtual ~MoriLabelling( ); + + virtual TNodes _UnifySeeds( ) override; + virtual void _UpdateOutputValue( TNode& n ) override; + + private: + // Purposely not implemented. + MoriLabelling( const Self& other ); + Self& operator=( const Self& other ); + + protected: + TOutputValue m_InsideLabel; + }; + */ } // ecapseman diff --git a/appli/CTBronchi/MoriLabelling.hxx b/appli/CTBronchi/MoriLabelling.hxx index 6f7246c..228ed2d 100644 --- a/appli/CTBronchi/MoriLabelling.hxx +++ b/appli/CTBronchi/MoriLabelling.hxx @@ -6,189 +6,191 @@ #ifndef __CTBronchi__MoriLabelling__hxx__ #define __CTBronchi__MoriLabelling__hxx__ -#include - -// ------------------------------------------------------------------------- -template< class _TInputImage, class _TLabelImage, class _TTraits > -const typename CTBronchi::MoriLabelling< _TInputImage, _TLabelImage, _TTraits >:: -TLabelImage* CTBronchi::MoriLabelling< _TInputImage, _TLabelImage, _TTraits >:: -GetInputLabelImage( ) const -{ - return( this->GetLabels( ) ); -} - -// ------------------------------------------------------------------------- -template< class _TInputImage, class _TLabelImage, class _TTraits > -void CTBronchi::MoriLabelling< _TInputImage, _TLabelImage, _TTraits >:: -SetInputLabelImage( TLabelImage* image ) -{ - this->SetLabels( image ); -} - -// ------------------------------------------------------------------------- -template< class _TInputImage, class _TLabelImage, class _TTraits > -const typename CTBronchi::MoriLabelling< _TInputImage, _TLabelImage, _TTraits >:: -TInputImage* CTBronchi::MoriLabelling< _TInputImage, _TLabelImage, _TTraits >:: -GetInputRawImage( ) const -{ - return( this->GetInput( ) ); -} - -// ------------------------------------------------------------------------- -template< class _TInputImage, class _TLabelImage, class _TTraits > -void CTBronchi::MoriLabelling< _TInputImage, _TLabelImage, _TTraits >:: -SetInputRawImage( TInputImage* image ) -{ - this->SetInput( image ); -} - -// ------------------------------------------------------------------------- -template< class _TInputImage, class _TLabelImage, class _TTraits > -typename CTBronchi::MoriLabelling< _TInputImage, _TLabelImage, _TTraits >:: -TInputValue CTBronchi::MoriLabelling< _TInputImage, _TLabelImage, _TTraits >:: -GetUpperThreshold( ) const -{ - const TThresholdFunction* func = - dynamic_cast< const TThresholdFunction* >( this->GetValuePredicate( ) ); - if( func != NULL ) - return( func->GetUpper( ) ); - else - return( TInputValue( 0 ) ); -} - -// ------------------------------------------------------------------------- -template< class _TInputImage, class _TLabelImage, class _TTraits > -void CTBronchi::MoriLabelling< _TInputImage, _TLabelImage, _TTraits >:: -SetUpperThreshold( TInputValue t ) -{ - TThresholdFunction* func = - dynamic_cast< TThresholdFunction* >( this->GetValuePredicate( ) ); - if( func != NULL ) - func->SetUpper( t ); -} - -// ------------------------------------------------------------------------- -template< class _TInputImage, class _TLabelImage, class _TTraits > -typename CTBronchi::MoriLabelling< _TInputImage, _TLabelImage, _TTraits >:: -TOutputValue CTBronchi::MoriLabelling< _TInputImage, _TLabelImage, _TTraits >:: -GetOutsideValue( ) const -{ - return( this->GetInitValue( ) ); -} - -// ------------------------------------------------------------------------- -template< class _TInputImage, class _TLabelImage, class _TTraits > -void CTBronchi::MoriLabelling< _TInputImage, _TLabelImage, _TTraits >:: -SetOutsideLabel( TOutputValue o ) -{ - this->SetInitValue( o ); -} - -// ------------------------------------------------------------------------- -template< class _TInputImage, class _TLabelImage, class _TTraits > -CTBronchi::MoriLabelling< _TInputImage, _TLabelImage, _TTraits >:: -MoriLabelling( ) - : Superclass( ), - m_InsideLabel( TOutputValue( 0 ) ) -{ - typename TThresholdFunction::Pointer func = TThresholdFunction::New( ); - this->SetPredicate( func ); -} - -// ------------------------------------------------------------------------- -template< class _TInputImage, class _TLabelImage, class _TTraits > -CTBronchi::MoriLabelling< _TInputImage, _TLabelImage, _TTraits >:: -~MoriLabelling( ) -{ -} - -// ------------------------------------------------------------------------- -template< class _TInputImage, class _TLabelImage, class _TTraits > -typename CTBronchi::MoriLabelling< _TInputImage, _TLabelImage, _TTraits >:: -TNodes CTBronchi::MoriLabelling< _TInputImage, _TLabelImage, _TTraits >:: -_UnifySeeds( ) -{ - this->m_Seeds.clear( ); - const TLabelImage* lbl = this->GetLabels( ); - if( lbl == NULL ) - { - std::ostringstream msg; - msg << "itk::ERROR: CTBronchi::MoriLabelling (" << this - << "): Labelled image not defined."; - ::itk::ExceptionObject e( - __FILE__, __LINE__, msg.str( ).c_str( ), ITK_LOCATION - ); - throw e; - - } // fi - - // Iterate over labels - typename TLabelImage::RegionType reg = lbl->GetRequestedRegion( ); - itk::ImageRegionConstIteratorWithIndex< TLabelImage > lIt( lbl, reg ); - for( lIt.GoToBegin( ); !lIt.IsAtEnd( ); ++lIt ) - { - if( lIt.Get( ) > 0 ) - { - bool is_seed = false; - for( unsigned int d = 0; d < TLabelImage::ImageDimension; ++d ) - { - for( int s = -1; s <= 1; s += 2 ) - { - TVertex neigh = lIt.GetIndex( ); - neigh[ d ] += s; - if( reg.IsInside( neigh ) ) - is_seed |= ( lbl->GetPixel( neigh ) == 0 ); - - } // rof - - } // rof - - if( !is_seed ) - { - typename TSeedsInterface::TNode node; - node.Vertex = lIt.GetIndex( ); - node.Parent = lIt.GetIndex( ); - node.FrontId = lIt.Get( ); - node.Value = this->m_InsideLabel; - this->_Mark( node.Vertex, node.FrontId ); - this->_UpdateOutputValue( node ); - } - else - { - typename TSeedsInterface::TSeed seed; - seed.Vertex = lIt.GetIndex( ); - seed.IsPoint = false; - seed.FrontId = lIt.Get( ); - this->m_Seeds.push_back( seed ); - - } // fi - - } // fi - - } // rof - - // Ok, finish initialization - return( this->Superclass::_UnifySeeds( ) ); -} - -// ------------------------------------------------------------------------- -template< class _TInputImage, class _TLabelImage, class _TTraits > -void CTBronchi::MoriLabelling< _TInputImage, _TLabelImage, _TTraits >:: -_UpdateOutputValue( TNode& n ) -{ - const TLabelImage* input_labels = this->GetInputLabelImage( ); - - this->Superclass::_UpdateOutputValue( n ); - if( n.FrontId != 0 ) - { - if( input_labels->GetPixel( n.Vertex ) == this->GetInsideValue( ) ) - n.Value = this->GetInsideLabel( ); - else - n.Value = TOutputValue( 0 ); - this->TAlgorithm::_UpdateOutputValue( n ); - - } // fi -} +/* TODO + #include + + // ------------------------------------------------------------------------- + template< class _TInputImage, class _TLabelImage, class _TTraits > + const typename CTBronchi::MoriLabelling< _TInputImage, _TLabelImage, _TTraits >:: + TLabelImage* CTBronchi::MoriLabelling< _TInputImage, _TLabelImage, _TTraits >:: + GetInputLabelImage( ) const + { + return( this->GetLabels( ) ); + } + + // ------------------------------------------------------------------------- + template< class _TInputImage, class _TLabelImage, class _TTraits > + void CTBronchi::MoriLabelling< _TInputImage, _TLabelImage, _TTraits >:: + SetInputLabelImage( TLabelImage* image ) + { + this->SetLabels( image ); + } + + // ------------------------------------------------------------------------- + template< class _TInputImage, class _TLabelImage, class _TTraits > + const typename CTBronchi::MoriLabelling< _TInputImage, _TLabelImage, _TTraits >:: + TInputImage* CTBronchi::MoriLabelling< _TInputImage, _TLabelImage, _TTraits >:: + GetInputRawImage( ) const + { + return( this->GetInput( ) ); + } + + // ------------------------------------------------------------------------- + template< class _TInputImage, class _TLabelImage, class _TTraits > + void CTBronchi::MoriLabelling< _TInputImage, _TLabelImage, _TTraits >:: + SetInputRawImage( TInputImage* image ) + { + this->SetInput( image ); + } + + // ------------------------------------------------------------------------- + template< class _TInputImage, class _TLabelImage, class _TTraits > + typename CTBronchi::MoriLabelling< _TInputImage, _TLabelImage, _TTraits >:: + TInputValue CTBronchi::MoriLabelling< _TInputImage, _TLabelImage, _TTraits >:: + GetUpperThreshold( ) const + { + const TThresholdFunction* func = + dynamic_cast< const TThresholdFunction* >( this->GetValuePredicate( ) ); + if( func != NULL ) + return( func->GetUpper( ) ); + else + return( TInputValue( 0 ) ); + } + + // ------------------------------------------------------------------------- + template< class _TInputImage, class _TLabelImage, class _TTraits > + void CTBronchi::MoriLabelling< _TInputImage, _TLabelImage, _TTraits >:: + SetUpperThreshold( TInputValue t ) + { + TThresholdFunction* func = + dynamic_cast< TThresholdFunction* >( this->GetValuePredicate( ) ); + if( func != NULL ) + func->SetUpper( t ); + } + + // ------------------------------------------------------------------------- + template< class _TInputImage, class _TLabelImage, class _TTraits > + typename CTBronchi::MoriLabelling< _TInputImage, _TLabelImage, _TTraits >:: + TOutputValue CTBronchi::MoriLabelling< _TInputImage, _TLabelImage, _TTraits >:: + GetOutsideValue( ) const + { + return( this->GetInitValue( ) ); + } + + // ------------------------------------------------------------------------- + template< class _TInputImage, class _TLabelImage, class _TTraits > + void CTBronchi::MoriLabelling< _TInputImage, _TLabelImage, _TTraits >:: + SetOutsideLabel( TOutputValue o ) + { + this->SetInitValue( o ); + } + + // ------------------------------------------------------------------------- + template< class _TInputImage, class _TLabelImage, class _TTraits > + CTBronchi::MoriLabelling< _TInputImage, _TLabelImage, _TTraits >:: + MoriLabelling( ) + : Superclass( ), + m_InsideLabel( TOutputValue( 0 ) ) + { + typename TThresholdFunction::Pointer func = TThresholdFunction::New( ); + this->SetPredicate( func ); + } + + // ------------------------------------------------------------------------- + template< class _TInputImage, class _TLabelImage, class _TTraits > + CTBronchi::MoriLabelling< _TInputImage, _TLabelImage, _TTraits >:: + ~MoriLabelling( ) + { + } + + // ------------------------------------------------------------------------- + template< class _TInputImage, class _TLabelImage, class _TTraits > + typename CTBronchi::MoriLabelling< _TInputImage, _TLabelImage, _TTraits >:: + TNodes CTBronchi::MoriLabelling< _TInputImage, _TLabelImage, _TTraits >:: + _UnifySeeds( ) + { + this->m_Seeds.clear( ); + const TLabelImage* lbl = this->GetLabels( ); + if( lbl == NULL ) + { + std::ostringstream msg; + msg << "itk::ERROR: CTBronchi::MoriLabelling (" << this + << "): Labelled image not defined."; + ::itk::ExceptionObject e( + __FILE__, __LINE__, msg.str( ).c_str( ), ITK_LOCATION + ); + throw e; + + } // fi + + // Iterate over labels + typename TLabelImage::RegionType reg = lbl->GetRequestedRegion( ); + itk::ImageRegionConstIteratorWithIndex< TLabelImage > lIt( lbl, reg ); + for( lIt.GoToBegin( ); !lIt.IsAtEnd( ); ++lIt ) + { + if( lIt.Get( ) > 0 ) + { + bool is_seed = false; + for( unsigned int d = 0; d < TLabelImage::ImageDimension; ++d ) + { + for( int s = -1; s <= 1; s += 2 ) + { + TVertex neigh = lIt.GetIndex( ); + neigh[ d ] += s; + if( reg.IsInside( neigh ) ) + is_seed |= ( lbl->GetPixel( neigh ) == 0 ); + + } // rof + + } // rof + + if( !is_seed ) + { + typename TSeedsInterface::TNode node; + node.Vertex = lIt.GetIndex( ); + node.Parent = lIt.GetIndex( ); + node.FrontId = lIt.Get( ); + node.Value = this->m_InsideLabel; + this->_Mark( node.Vertex, node.FrontId ); + this->_UpdateOutputValue( node ); + } + else + { + typename TSeedsInterface::TSeed seed; + seed.Vertex = lIt.GetIndex( ); + seed.IsPoint = false; + seed.FrontId = lIt.Get( ); + this->m_Seeds.push_back( seed ); + + } // fi + + } // fi + + } // rof + + // Ok, finish initialization + return( this->Superclass::_UnifySeeds( ) ); + } + + // ------------------------------------------------------------------------- + template< class _TInputImage, class _TLabelImage, class _TTraits > + void CTBronchi::MoriLabelling< _TInputImage, _TLabelImage, _TTraits >:: + _UpdateOutputValue( TNode& n ) + { + const TLabelImage* input_labels = this->GetInputLabelImage( ); + + this->Superclass::_UpdateOutputValue( n ); + if( n.FrontId != 0 ) + { + if( input_labels->GetPixel( n.Vertex ) == this->GetInsideValue( ) ) + n.Value = this->GetInsideLabel( ); + else + n.Value = TOutputValue( 0 ); + this->TAlgorithm::_UpdateOutputValue( n ); + + } // fi + } +*/ #endif // __CTBronchi__MoriLabelling__hxx__ diff --git a/appli/CTBronchi/Process.cxx b/appli/CTBronchi/Process.cxx index 8fb3e17..4261a97 100644 --- a/appli/CTBronchi/Process.cxx +++ b/appli/CTBronchi/Process.cxx @@ -1,28 +1,235 @@ +// ========================================================================= +// @author Leonardo Florez Valencia +// @email florez-l@javeriana.edu.co +// ========================================================================= + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// ------------------------------------------------------------------------- +const unsigned int Dim = 3; +typedef short TInputPixel; +typedef unsigned char TLabelPixel; +typedef itk::Image< TInputPixel, Dim > TInputImage; +typedef itk::Image< TLabelPixel, Dim > TLabelImage; +typedef std::map< std::string, std::string > TMap; + +// ------------------------------------------------------------------------- +TMap Args; +TInputImage::PointType global_seed; +TLabelPixel inside_value = std::numeric_limits< TLabelPixel >::max( ); +TLabelPixel outside_value = TLabelPixel( 0 ); + +// ------------------------------------------------------------------------- +double MeasureTime( itk::ProcessObject* f ) +{ + std::chrono::time_point< std::chrono::high_resolution_clock > s, e; + std::chrono::duration< double > t; + s = std::chrono::high_resolution_clock::now( ); + f->Update( ); + e = std::chrono::high_resolution_clock::now( ); + t = e - s; + return( t.count( ) ); +} + +// ------------------------------------------------------------------------- +template< class _TImagePtr > +void ReadImage( _TImagePtr& image, const std::string& fname ) +{ + typedef typename _TImagePtr::ObjectType _TImage; + typedef itk::ImageFileReader< _TImage > _TReader; + typename _TReader::Pointer reader = _TReader::New( ); + reader->SetFileName( fname ); + double t = MeasureTime( reader ); + std::cout << "Read " << fname << " in " << t << " s" << std::endl; + image = reader->GetOutput( ); + image->DisconnectPipeline( ); +} + +// ------------------------------------------------------------------------- +template< class _TImagePtr > +void WriteImage( const _TImagePtr& image, const std::string& fname ) +{ + typedef typename _TImagePtr::ObjectType _TImage; + typedef itk::ImageFileWriter< _TImage > _TWriter; + typename _TWriter::Pointer writer = _TWriter::New( ); + writer->SetFileName( fname ); + writer->SetInput( image ); + double t = MeasureTime( writer ); + std::cout << "Wrote " << fname << " in " << t << " s" << std::endl; +} + +// ------------------------------------------------------------------------- +template< class _TInputPtr, class _TOutputPtr > +void Mori( _TOutputPtr& output, const _TInputPtr& input ) +{ + typedef typename _TInputPtr::ObjectType _TInput; + typedef typename _TOutputPtr::ObjectType _TOutput; + typedef fpa::Filters::Image::Mori< _TInput, _TOutput > _TMori; + + typename _TMori::Pointer mori = _TMori::New( ); + mori->SetInput( input ); + mori->SetSeed( global_seed ); + mori->SetInsideValue( inside_value ); + mori->SetOutsideValue( outside_value ); + mori->SetMinimumThreshold( + TInputPixel( std::atof( Args[ "mori_minimum_threshold" ].c_str( ) ) ) + ); + mori->SetSignalKernelSize( + std::atoi( Args[ "mori_signal_kernel_size" ].c_str( ) ) + ); + mori->SetSignalThreshold( + std::atof( Args[ "mori_signal_threshold" ].c_str( ) ) + ); + mori->SetSignalInfluence( + std::atof( Args[ "mori_signal_influence" ].c_str( ) ) + ); + mori->SetThresholds( + TInputPixel( std::atof( Args[ "mori_lower_threshold" ].c_str( ) ) ), + TInputPixel( std::atof( Args[ "mori_upper_threshold" ].c_str( ) ) ), + TInputPixel( std::atof( Args[ "mori_delta_threshold" ].c_str( ) ) ) + ); + double t = MeasureTime( mori ); + std::cout << "Mori executed in " << t << " s" << std::endl; + output = mori->GetOutput( ); + + TMap::const_iterator i = Args.find( "out_mori" ); + if( i != Args.end( ) ) + WriteImage( output, i->second ); + + i = Args.find( "out_signal" ); + if( i != Args.end( ) ) + { + std::stringstream signal; + unsigned long nthr = mori->GetNumberOfEvaluatedThresholds( ); + signal << "# nThr = " << nthr << std::endl; + signal << "# Opt = " << mori->GetOptimumThreshold( ) << std::endl; + for( unsigned long j = 0; j < nthr; ++j ) + { + typename _TMori::TPeak p; + double x, y; + mori->GetSignalValues( j, x, y, p ); + signal << x << " " << y << std::endl; + + } // rof + + std::ofstream signals_str( i->second.c_str( ) ); + signals_str << signal.str( ); + signals_str.close( ); + + } // fi + output->DisconnectPipeline( ); +} + +// ------------------------------------------------------------------------- +template< class _TInputPtr, class _TOutputPtr > +void Label( _TOutputPtr& output, const _TInputPtr& input ) +{ +} + +// ------------------------------------------------------------------------- +bool ParseArgs( int argc, char* argv[] ) +{ + std::set< std::string > mandatory; + mandatory.insert( "in" ); + mandatory.insert( "out_segmentation" ); + mandatory.insert( "seed_x" ); + mandatory.insert( "seed_y" ); + mandatory.insert( "seed_z" ); + + Args[ "mori_minimum_threshold" ] = "-850"; + Args[ "mori_signal_kernel_size" ] = "20"; + Args[ "mori_signal_threshold" ] = "100"; + Args[ "mori_signal_influence" ] = "0.5"; + Args[ "mori_lower_threshold" ] = "-1024"; + Args[ "mori_upper_threshold" ] = "0"; + Args[ "mori_delta_threshold" ] = "1"; + for( int i = 1; i < argc; i += 2 ) + Args[ argv[ i ] + 1 ] = argv[ i + 1 ]; + + bool complete = true; + for( std::string t: mandatory ) + complete &= ( Args.find( t ) != Args.end( ) ); + + if( !complete ) + { + std::cerr + << "Usage: " << argv[ 0 ] << std::endl + << "\t-in filename" << std::endl + << "\t-out_segmentation filename" << std::endl + << "\t-seed_x value -seed_y value -seed_z value" << std::endl + << "\t[-out_mori filename]" << std::endl + << "\t[-out_signal filename]" << std::endl + << "\t[-out_labels filename]" << std::endl + << "\t[-mori_minimum_threshold value]" << std::endl + << "\t[-mori_signal_kernel_size value]" << std::endl + << "\t[-mori_signal_threshold value]" << std::endl + << "\t[-mori_signal_influence value]" << std::endl + << "\t[-mori_lower_threshold value]" << std::endl + << "\t[-mori_upper_threshold value]" << std::endl + << "\t[-mori_delta_threshold value]" << std::endl; + return( false ); + + } // fi + return( true ); +} + +// ------------------------------------------------------------------------- int main( int argc, char* argv[] ) { + try + { + if( ParseArgs( argc, argv ) ) + { + // Parse seed + global_seed[ 0 ] = std::atof( Args[ "seed_x" ].c_str( ) ); + global_seed[ 1 ] = std::atof( Args[ "seed_y" ].c_str( ) ); + global_seed[ 2 ] = std::atof( Args[ "seed_z" ].c_str( ) ); + + // Read input image + TInputImage::Pointer input_image; + ReadImage( input_image, Args[ "in" ] ); + + // Mori segmentation + TLabelImage::Pointer mori; + Mori( mori, input_image ); + + // Create labels + TLabelImage::Pointer labels; + Label( labels, mori ); + + return( 0 ); + + } // fi + return( 1 ); + } + catch( std::exception& err ) + { + std::cerr + << "===============================" << std::endl + << "Error caught: " << std::endl + << err.what( ) + << "===============================" << std::endl + << std::endl; + return( 1 ); + + } // yrt /* TODO - -input input_raw_image - -seed x y z - [-mori mori_image_dfilename] - [-labels labels_image_filename] - [-output output_image_filename] + if [ -z "$label_upper_threshold" ]; then label_upper_threshold="-600"; fi + if [ -z "$label_inside" ]; then label_inside="1"; fi + if [ -z "$label_outside" ]; then label_outside="2"; fi + if [ -z "$random_walker_beta" ]; then random_walker_beta="20"; fi */ - - /* TODO - if [ -z "$mori_init_threshold" ]; then mori_init_threshold="-1024"; fi - if [ -z "$mori_end_threshold" ]; then mori_end_threshold="0"; fi - if [ -z "$mori_delta" ]; then mori_delta="1"; fi - if [ -z "$mori_minimum_threshold" ]; then mori_minimum_threshold="-850"; fi - if [ -z "$mori_inside_value" ]; then mori_inside_value="255"; fi - if [ -z "$mori_outside_value" ]; then mori_outside_value="0"; fi - if [ -z "$mori_signal_kernel_size" ]; then mori_signal_kernel_size="20"; fi - if [ -z "$mori_signal_threshold" ]; then mori_signal_threshold="500"; fi - if [ -z "$mori_signal_influence" ]; then mori_signal_influence="0.5"; fi - if [ -z "$label_upper_threshold" ]; then label_upper_threshold="-600"; fi - if [ -z "$label_inside" ]; then label_inside="1"; fi - if [ -z "$label_outside" ]; then label_outside="2"; fi - if [ -z "$random_walker_beta" ]; then random_walker_beta="20"; fi - */ - - return( 0 ); } + +// eof - $RCSfile$ diff --git a/lib/fpa/Filters/Image/Mori.h b/lib/fpa/Filters/Image/Mori.h index 66a5fa3..5103a30 100644 --- a/lib/fpa/Filters/Image/Mori.h +++ b/lib/fpa/Filters/Image/Mori.h @@ -59,13 +59,10 @@ namespace fpa ); protected: - Mori( ) - : Superclass( ) - { - } - virtual ~Mori( ) - { - } + Mori( ); + virtual ~Mori( ); + + virtual void _AfterGenerateData( ) override; private: // Purposely not implemented. @@ -79,5 +76,8 @@ namespace fpa } // ecapseman +#ifndef ITK_MANUAL_INSTANTIATION +# include +#endif // ITK_MANUAL_INSTANTIATION #endif // __fpa__Filters__Image__Mori__h__ // eof - $RCSfile$ diff --git a/lib/fpa/Filters/Image/Mori.hxx b/lib/fpa/Filters/Image/Mori.hxx new file mode 100644 index 0000000..8b44364 --- /dev/null +++ b/lib/fpa/Filters/Image/Mori.hxx @@ -0,0 +1,46 @@ +// ========================================================================= +// @author Leonardo Florez Valencia +// @email florez-l@javeriana.edu.co +// ========================================================================= +#ifndef __fpa__Filters__Image__Mori__hxx__ +#define __fpa__Filters__Image__Mori__hxx__ + +#include + +// ------------------------------------------------------------------------- +template< class _TInputImage, class _TOutputImage, class _TTraits > +fpa::Filters::Image::Mori< _TInputImage, _TOutputImage, _TTraits >:: +Mori( ) + : Superclass( ) +{ +} + +// ------------------------------------------------------------------------- +template< class _TInputImage, class _TOutputImage, class _TTraits > +fpa::Filters::Image::Mori< _TInputImage, _TOutputImage, _TTraits >:: +~Mori( ) +{ +} + +// ------------------------------------------------------------------------- +template< class _TInputImage, class _TOutputImage, class _TTraits > +void fpa::Filters::Image::Mori< _TInputImage, _TOutputImage, _TTraits >:: +_AfterGenerateData( ) +{ + this->Superclass::_AfterGenerateData( ); + + // Extract correct mark + typedef typename Superclass::TMarksImage _TMarks; + typedef itk::BinaryThresholdImageFilter< _TMarks, TOutputImage > _TFilter; + typename _TFilter::Pointer filter = _TFilter::New( ); + filter->SetInput( this->GetMarks( ) ); + filter->SetLowerThreshold( 1 ); + filter->SetUpperThreshold( this->m_PeakDetector.GetNumberOfSamples( ) - 2 ); + filter->SetInsideValue( this->GetInsideValue( ) ); + filter->SetOutsideValue( this->GetOutsideValue( ) ); + filter->Update( ); + this->GraftOutput( filter->GetOutput( ) ); +} + +#endif // __fpa__Filters__Image__Mori__hxx__ +// eof - $RCSfile$ diff --git a/lib/fpa/Filters/Mori.h b/lib/fpa/Filters/Mori.h index 0bda0ff..4cb877e 100644 --- a/lib/fpa/Filters/Mori.h +++ b/lib/fpa/Filters/Mori.h @@ -119,6 +119,5 @@ namespace fpa #ifndef ITK_MANUAL_INSTANTIATION # include #endif // ITK_MANUAL_INSTANTIATION - #endif // __fpa__Filters__Mori__h__ // eof - $RCSfile$ -- 2.47.1