From: Leonardo Flórez-Valencia Date: Tue, 5 Dec 2017 17:06:20 +0000 (-0500) Subject: ... X-Git-Url: https://git.creatis.insa-lyon.fr/pubgit/?a=commitdiff_plain;h=8148ddf65cb59ae75109b6373c85117959167e63;p=FrontAlgorithms.git ... --- diff --git a/appli/CTBronchi/CMakeLists.txt b/appli/CTBronchi/CMakeLists.txt index b5f19be..be25477 100644 --- a/appli/CTBronchi/CMakeLists.txt +++ b/appli/CTBronchi/CMakeLists.txt @@ -4,36 +4,58 @@ option(fpa_BUILD_CTBronchi "Build bronchi analysis from CT images applications?" OFF) if(fpa_BUILD_CTBronchi) - set(_pfx fpa_CTBronchi_) - set( - _examples - Vesselness - MoriSegmentation - MoriLabelling - FastRandomWalker - SliceBySliceRandomWalker - AndSegmentations - Skeleton + BuildLibrary( + fpa_CTBronchi SHARED + INSTALL_ALL + SOURCE + Filter.h Filter.hxx + Image.h Image.hxx + Process.h Process.cxx + LINKS fpa cpPlugins::tclap ) - foreach(_e ${_examples}) - BuildApplication( - ${_pfx}${_e} - SOURCE ${_e}.cxx - INSTALL - RECURRENT - LINKS fpa cpPlugins::tclap - ) - endforeach(_e) - configure_file( - Process.sh - ${PROJECT_BINARY_DIR}/${_pfx}Process.sh - COPYONLY - ) - install( - FILES ${PROJECT_BINARY_DIR}/${_pfx}Process.sh - DESTINATION bin + BuildApplication( + fpa_CTBronchi_CommandLineProcess + SOURCE CommandLineProcess.cxx + INSTALL + RECURRENT + LINKS fpa_CTBronchi ) + endif(fpa_BUILD_CTBronchi) +#option(fpa_BUILD_CTBronchi "Build bronchi analysis from CT images applications?" OFF) +#if(fpa_BUILD_CTBronchi) +# set(_pfx fpa_CTBronchi_) +# set( +# _examples +# Vesselness +# MoriSegmentation +# MoriLabelling +# FastRandomWalker +# SliceBySliceRandomWalker +# AndSegmentations +# Skeleton +# ) +# foreach(_e ${_examples}) +# BuildApplication( +# ${_pfx}${_e} +# SOURCE ${_e}.cxx +# INSTALL +# RECURRENT +# LINKS fpa cpPlugins::tclap +# ) +# endforeach(_e) + +# configure_file( +# Process.sh +# ${PROJECT_BINARY_DIR}/${_pfx}Process.sh +# COPYONLY +# ) +# install( +# FILES ${PROJECT_BINARY_DIR}/${_pfx}Process.sh +# DESTINATION bin +# ) +#endif(fpa_BUILD_CTBronchi) + ## eof - $RCSfile$ diff --git a/appli/CTBronchi/CommandLineProcess.cxx b/appli/CTBronchi/CommandLineProcess.cxx new file mode 100644 index 0000000..8131d0e --- /dev/null +++ b/appli/CTBronchi/CommandLineProcess.cxx @@ -0,0 +1,25 @@ +// ========================================================================= +// @author Leonardo Florez Valencia (florez-l@javeriana.edu.co) +// ========================================================================= + +#include +#include "Process.h" + +int main( int argc, char* argv[] ) +{ + try + { + CTBronchi::Process process; + process.ParseArguments( argc, argv ); + process.Update( ); + } + catch( std::exception& err ) + { + std::cerr << "Error caught: " << err.what( ) << std::endl; + return( 1 ); + + } // yrt + return( 0 ); +} + +// eof - $RCSfile$ diff --git a/appli/CTBronchi/Filter.h b/appli/CTBronchi/Filter.h new file mode 100644 index 0000000..20de5ec --- /dev/null +++ b/appli/CTBronchi/Filter.h @@ -0,0 +1,39 @@ +// ========================================================================= +// @author Leonardo Florez Valencia (florez-l@javeriana.edu.co) +// ========================================================================= +#ifndef __CTBronchi__Filter__h__ +#define __CTBronchi__Filter__h__ + +namespace CTBronchi +{ + /** + */ + template< class _TFilter > + class Filter + { + public: + typedef _TFilter TFilter; + + public: + Filter( ); + virtual ~Filter( ); + + bool IsNotNull( ) const; + bool IsNull( ) const; + + TFilter* Get( ); + const TFilter* Get( ) const; + + double Update( ); + + protected: + typename TFilter::Pointer m_Filter; + }; + +} // ecapseman + +#include "Filter.hxx" + +#endif // __CTBronchi__Filter__h__ + +// eof - $RCSfile$ diff --git a/appli/CTBronchi/Filter.hxx b/appli/CTBronchi/Filter.hxx new file mode 100644 index 0000000..8f4f8e6 --- /dev/null +++ b/appli/CTBronchi/Filter.hxx @@ -0,0 +1,79 @@ +// ========================================================================= +// @author Leonardo Florez Valencia (florez-l@javeriana.edu.co) +// ========================================================================= +#ifndef __CTBronchi__Filter__hxx__ +#define __CTBronchi__Filter__hxx__ + +#include + +// ------------------------------------------------------------------------- +template< class _TFilter > +CTBronchi::Filter< _TFilter >:: +Filter( ) +{ + this->m_Filter = TFilter::New( ); +} + +// ------------------------------------------------------------------------- +template< class _TFilter > +CTBronchi::Filter< _TFilter >:: +~Filter( ) +{ +} + +// ------------------------------------------------------------------------- +template< class _TFilter > +bool CTBronchi::Filter< _TFilter >:: +IsNotNull( ) const +{ + return( this->m_Filter.IsNotNull( ) ); +} + +// ------------------------------------------------------------------------- +template< class _TFilter > +bool CTBronchi::Filter< _TFilter >:: +IsNull( ) const +{ + return( this->m_Filter.IsNotNull( ) ); +} + +// ------------------------------------------------------------------------- +template< class _TFilter > +typename CTBronchi::Filter< _TFilter >:: +TFilter* CTBronchi::Filter< _TFilter >:: +Get( ) +{ + return( this->m_Filter ); +} + +// ------------------------------------------------------------------------- +template< class _TFilter > +const typename CTBronchi::Filter< _TFilter >:: +TFilter* CTBronchi::Filter< _TFilter >:: +Get( ) const +{ + return( this->m_Filter ); +} + +// ------------------------------------------------------------------------- +template< class _TFilter > +double CTBronchi::Filter< _TFilter >:: +Update( ) +{ + if( this->IsNotNull( ) ) + { + std::chrono::time_point< std::chrono::high_resolution_clock > s, e; + std::chrono::duration< double > t; + s = std::chrono::high_resolution_clock::now( ); + this->m_Filter->Update( ); + e = std::chrono::high_resolution_clock::now( ); + t = e - s; + return( t.count( ) ); + } + else + return( -1 ); +} + +#endif // __CTBronchi__Filter__hxx__ + +// eof - $RCSfile$ diff --git a/appli/CTBronchi/Image.h b/appli/CTBronchi/Image.h index 8b243e6..4518293 100644 --- a/appli/CTBronchi/Image.h +++ b/appli/CTBronchi/Image.h @@ -14,7 +14,7 @@ namespace CTBronchi class Image { public: - static const unsigned int _VDim = VDim; + static const unsigned int VDim = _VDim; typedef _TPixel TPixel; typedef itk::Image< TPixel, VDim > TImage; @@ -28,10 +28,10 @@ namespace CTBronchi TImage* Get( ); const TImage* Get( ) const; void Set( TImage* image ); - void Set( const TImage::Pointer& image ); + void Set( const typename TImage::Pointer& image ); - void Load( const std::string& fname ); - void Save( const std::string& fname ); + double Load( const std::string& fname ); + double Save( const std::string& fname ); protected: typename TImage::Pointer m_Image; diff --git a/appli/CTBronchi/Image.hxx b/appli/CTBronchi/Image.hxx index 4b6fa9b..86ce8eb 100644 --- a/appli/CTBronchi/Image.hxx +++ b/appli/CTBronchi/Image.hxx @@ -4,6 +4,7 @@ #ifndef __CTBronchi__Image__hxx__ #define __CTBronchi__Image__hxx__ +#include "Filter.h" #include #include @@ -61,57 +62,64 @@ void CTBronchi::Image< _TPixel, _VDim >:: Set( TImage* image ) { this->m_Image = image; - this->m_Image->DisconnectPipeline( ); + if( this->m_Image.IsNotNull( ) ) + this->m_Image->DisconnectPipeline( ); } // ------------------------------------------------------------------------- template< class _TPixel, unsigned int _VDim > void CTBronchi::Image< _TPixel, _VDim >:: -Set( const TImage::Pointer& image ) +Set( const typename TImage::Pointer& image ) { this->m_Image = image.GetPointer( ); - this->m_Image->DisconnectPipeline( ); + if( this->m_Image.IsNotNull( ) ) + this->m_Image->DisconnectPipeline( ); } // ------------------------------------------------------------------------- template< class _TPixel, unsigned int _VDim > -void CTBronchi::Image< _TPixel, _VDim >:: +double CTBronchi::Image< _TPixel, _VDim >:: Load( const std::string& fname ) { - typedef itk::ImageFileReader< TImage > _TReader; - typename _TReader::Pointer r = _TReader::New( ); - r->SetFileName( fname ); + typedef CTBronchi::Filter< itk::ImageFileReader< TImage > > _TReader; + _TReader r; + r.Get( )->SetFileName( fname ); try { - r->Update( ); - this->Set( r->GetOutput( ) ); + double t = r.Update( ); + this->Set( r.Get( )->GetOutput( ) ); + return( t ); } catch( ... ) { this->Set( NULL ); + return( -1 ); } // yrt } // ------------------------------------------------------------------------- template< class _TPixel, unsigned int _VDim > -void CTBronchi::Image< _TPixel, _VDim >:: +double CTBronchi::Image< _TPixel, _VDim >:: Save( const std::string& fname ) { - typedef itk::ImageFileWriter< TImage > _TWriter; + typedef CTBronchi::Filter< itk::ImageFileWriter< TImage > > _TWriter; + double t = -1; if( this->IsNotNull( ) ) { - typename _TWriter::Pointer w = _TWriter::New( ); - w->SetFileName( fname ); - w->SetInput( this->m_Image ); + _TWriter w; + w.Get( )->SetFileName( fname ); + w.Get( )->UseCompressionOn( ); + w.Get( )->SetInput( this->m_Image ); try { - w->Update( ); + t = w.Update( ); } catch( ... ) { } } // fi + return( t ); } #endif // __CTBronchi__Image__hxx__ diff --git a/appli/CTBronchi/Process.cxx b/appli/CTBronchi/Process.cxx index e69de29..9f29ffc 100644 --- a/appli/CTBronchi/Process.cxx +++ b/appli/CTBronchi/Process.cxx @@ -0,0 +1,353 @@ +// ========================================================================= +// @author Leonardo Florez Valencia (florez-l@javeriana.edu.co) +// ========================================================================= + +#include +#include +#include + +#include +#include +#include +#include + +#include + +#include "MoriLabelling.h" +#include "Process.h" + +// ------------------------------------------------------------------------- +CTBronchi::Process:: +Process( ) + : m_UndefinedLabel( 0 ), + m_InsideLabel( 1 ), + m_OutsideLabel( 2 ) +{ + this->m_StrArg[ "input" ] = TArgument( "", true ); + this->m_StrArg[ "seed_file" ] = TArgument( "", false ); + this->m_StrArg[ "seed" ] = TArgument( "", false ); + this->m_StrArg[ "seed_type" ] = TArgument( "point", false ); + + this->m_DblArg[ "beta" ] = TArgument( "2.5", false ); + this->m_DblArg[ "epsilon" ] = TArgument( "1e-5", false ); + this->m_DblArg[ "vesselness_sigma" ] = TArgument( "0.5", false ); + this->m_DblArg[ "vesselness_alpha1" ] = TArgument( "0.5", false ); + this->m_DblArg[ "vesselness_alpha2" ] = TArgument( "2", false ); + this->m_DblArg[ "mori_min_thr" ] = TArgument( "-850", false ); + this->m_DblArg[ "mori_kernel" ] = TArgument( "20", false ); + this->m_DblArg[ "mori_signal_thr" ] = TArgument( "100", false ); + this->m_DblArg[ "mori_signal_influence" ] = TArgument( "0.5", false ); + this->m_DblArg[ "mori_lower" ] = TArgument( "-1024", false ); + this->m_DblArg[ "mori_upper" ] = TArgument( "0", false ); + this->m_DblArg[ "mori_delta" ] = TArgument( "1", false ); + this->m_DblArg[ "slicerw_thr" ] = TArgument( "5", false ); + this->m_DblArg[ "fastrw_thr" ] = TArgument( "65", false ); + this->m_DblArg[ "labels_upper_thr" ] = TArgument( "-400", false ); +} + +// ------------------------------------------------------------------------- +CTBronchi::Process:: +~Process( ) +{ +} + +// ------------------------------------------------------------------------- +void CTBronchi::Process:: +ParseArguments( int argc, char* argv[] ) +{ + typedef TCLAP::ValueArg< std::string > _TStrArg; + typedef TCLAP::ValueArg< TScalar > _TDblArg; + std::map< std::string, _TStrArg* > strArg; + std::map< std::string, _TDblArg* > dblArg; + unsigned char flag = 'a'; + + TArguments::iterator sIt = this->m_StrArg.begin( ); + for( ; sIt != this->m_StrArg.end( ); ++sIt ) + { + std::stringstream fStr; + fStr << flag; + flag++; + if( flag == 'h' ) + flag++; + + _TStrArg* a = new _TStrArg( + fStr.str( ), sIt->first, sIt->first, + std::get< 1 >( sIt->second ), + std::get< 0 >( sIt->second ), + "string" + ); + strArg[ sIt->first ] = a; + + } // rof + + TArguments::iterator dIt = this->m_DblArg.begin( ); + for( ; dIt != this->m_DblArg.end( ); ++dIt ) + { + std::stringstream fStr; + fStr << flag; + flag++; + if( flag == 'h' ) + flag++; + + std::istringstream vStr( std::get< 0 >( dIt->second ) ); + TScalar v; + vStr >> v; + + _TDblArg* a = new _TDblArg( + fStr.str( ), dIt->first, dIt->first, + std::get< 1 >( dIt->second ), + v, "value" + ); + dblArg[ dIt->first ] = a; + + } // rof + + std::map< std::string, _TStrArg* >::iterator saIt; + std::map< std::string, _TDblArg* >::iterator daIt; + try + { + TCLAP::CmdLine cmd( "CTBronchi pipeline", ' ', "1.0.0" ); + for( saIt = strArg.begin( ); saIt != strArg.end( ); ++saIt ) + cmd.add( *( saIt->second ) ); + for( daIt = dblArg.begin( ); daIt != dblArg.end( ); ++daIt ) + cmd.add( *( daIt->second ) ); + cmd.parse( argc, argv ); + } + catch( TCLAP::ArgException& err ) + { + std::stringstream msg; + msg << err.error( ) << " " << err.argId( ); + throw std::runtime_error( msg.str( ) ); + + } // yrt + + for( saIt = strArg.begin( ); saIt != strArg.end( ); ++saIt ) + { + std::get< 0 >( this->m_StrArg[ saIt->first ] ) = saIt->second->getValue( ); + delete saIt->second; + + } // rof + for( daIt = dblArg.begin( ); daIt != dblArg.end( ); ++daIt ) + { + std::stringstream vStr; + vStr << daIt->second->getValue( ); + std::get< 0 >( this->m_DblArg[ daIt->first ] ) = vStr.str( ); + delete daIt->second; + + } // rof + + // Compute base filename + std::string iname = std::get< 0 >( this->m_StrArg[ "input" ] ); + this->m_BaseFileName = iname.substr( 0, iname.find_last_of( "." ) ); +} + +// ------------------------------------------------------------------------- +void CTBronchi::Process:: +Update( ) +{ + this->_Input( ); + this->_Vesselness( ); + this->_Mori( ); + this->_MoriLabelling( ); +} + +// ------------------------------------------------------------------------- +void CTBronchi::Process:: +_Input( ) +{ + std::string iname = std::get< 0 >( this->m_StrArg[ "input" ] ); + std::string sname = std::get< 0 >( this->m_StrArg[ "seed_file" ] ); + std::string seed = std::get< 0 >( this->m_StrArg[ "seed" ] ); + std::string stype = std::get< 0 >( this->m_StrArg[ "seed_type" ] ); + if( sname == "" && seed == "" ) + throw std::runtime_error( "No seed given." ); + if( sname != "" ) + { + std::ifstream str( sname.c_str( ) ); + str.seekg( 0, std::ios::end ); + seed.reserve( str.tellg( ) ); + str.seekg( 0, std::ios::beg ); + seed.assign( + std::istreambuf_iterator< char >( str ), + std::istreambuf_iterator< char >( ) + ); + str.close( ); + + } // fi + + // Get seed + std::istringstream sSeed( seed ); + TPoint pnt; + TIndex idx; + if( stype == "point" ) + sSeed >> pnt[ 0 ] >> pnt[ 1 ] >> pnt[ 2 ]; + else + sSeed >> idx[ 0 ] >> idx[ 1 ] >> idx[ 2 ]; + + // Read image + double t = this->m_Input.Load( iname ); + if( t < 0 ) + std::runtime_error( std::string( "Could not read \"" ) + iname + "\"" ); + std::cout << "\"" << iname << "\" read in " << t << " s." << std::endl; + + // Synch seed + if( stype == "point" ) + this->m_Input.Get( )->TransformPhysicalPointToIndex( pnt, idx ); + else + this->m_Input.Get( )->TransformIndexToPhysicalPoint( idx, pnt ); + this->m_Seed = TSeed( idx, pnt ); +} + +// ------------------------------------------------------------------------- +void CTBronchi::Process:: +_Vesselness( ) +{ + std::string vname = this->m_BaseFileName + "_vesselness.mha"; + double t = this->m_Vesselness.Load( vname ); + if( t < 0 ) + { + t = 0; + + // Arguments + std::stringstream v; + v << std::get< 0 >( this->m_DblArg[ "vesselness_sigma" ] ) << " " + << std::get< 0 >( this->m_DblArg[ "vesselness_alpha1" ] ) << " " + << std::get< 0 >( this->m_DblArg[ "vesselness_alpha2" ] ); + std::istringstream w( v.str( ) ); + TScalar s, a1, a2; + w >> s >> a1 >> a2; + + // Min-max + typedef itk::MinimumMaximumImageCalculator< TPixelImage::TImage > _TMinMax; + _TMinMax::Pointer minMax = _TMinMax::New( ); + minMax->SetImage( this->m_Input.Get( ) ); + minMax->Compute( ); + + // Invert intensities + typedef CTBronchi::Filter< itk::InvertIntensityImageFilter< TPixelImage::TImage > > _TInverter; + _TInverter inverter; + inverter.Get( )->SetInput( this->m_Input.Get( ) ); + inverter.Get( )->SetMaximum( minMax->GetMaximum( ) ); + double t1 = inverter.Update( ); + t += t1; + std::cout << "Inversion executed in " << t1 << " s" << std::endl; + + // Compute hessian image + typedef CTBronchi::Filter< itk::HessianRecursiveGaussianImageFilter< TPixelImage::TImage > > _THessian; + _THessian hessian; + hessian.Get( )->SetInput( inverter.Get( )->GetOutput( ) ); + hessian.Get( )->SetSigma( s ); + t1 = hessian.Update( ); + t += t1; + std::cout << "Hessian executed in " << t1 << " s" << std::endl; + + // Vesselness + typedef CTBronchi::Filter< itk::Hessian3DToVesselnessMeasureImageFilter< TScalar > > _TVesselness; + _TVesselness vesselness; + vesselness.Get( )->SetInput( hessian.Get( )->GetOutput( ) ); + vesselness.Get( )->SetAlpha1( a1 ); + vesselness.Get( )->SetAlpha2( a2 ); + t1 = vesselness.Update( ); + t += t1; + std::cout << "Hessian measure computed in " << t1 << " s." << std::endl; + + this->m_Vesselness.Set( vesselness.Get( )->GetOutput( ) ); + t1 = this->m_Vesselness.Save( vname ); + t += t1; + std::cout << "\"" << vname << "\" saved in " << t1 << " s." << std::endl; + + } // fi + std::cout << "Vesselness computed in " << t << " s." << std::endl; +} + +// ------------------------------------------------------------------------- +void CTBronchi::Process:: +_Mori( ) +{ + std::string mname = this->m_BaseFileName + "_mori.mha"; + double t = this->m_Mori.Load( mname ); + if( t < 0 ) + { + t = 0; + + // Arguments + std::stringstream v; + v << std::get< 0 >( this->m_DblArg[ "mori_min_thr" ] ) << " " + << std::get< 0 >( this->m_DblArg[ "mori_kernel" ] ) << " " + << std::get< 0 >( this->m_DblArg[ "mori_signal_thr" ] ) << " " + << std::get< 0 >( this->m_DblArg[ "mori_signal_influence" ] ) << " " + << std::get< 0 >( this->m_DblArg[ "mori_lower" ] ) << " " + << std::get< 0 >( this->m_DblArg[ "mori_upper" ] ) << " " + << std::get< 0 >( this->m_DblArg[ "mori_delta" ] ); + std::istringstream w( v.str( ) ); + TScalar mThr, sKernel, sThr, sInfluence, lower, upper, delta; + w >> mThr >> sKernel >> sThr >> sInfluence >> lower >> upper >> delta; + + // Mori segmentation + typedef CTBronchi::Filter< fpa::Filters::Image::Mori< TPixelImage::TImage, TLabelImage::TImage > > _TMori; + _TMori mori; + mori.Get( )->SetInput( this->m_Input.Get( ) ); + mori.Get( )->SetSeed( this->m_Seed.second ); + mori.Get( )->SetInsideValue( this->m_InsideLabel ); + mori.Get( )->SetOutsideValue( this->m_UndefinedLabel ); + mori.Get( )->SetMinimumThreshold( mThr ); + mori.Get( )->SetSignalKernelSize( sKernel ); + mori.Get( )->SetSignalThreshold( sThr ); + mori.Get( )->SetSignalInfluence( sInfluence ); + mori.Get( )->SetThresholds( lower, upper, delta ); + double t1 = mori.Update( ); + t += t1; + std::cout << "Segmentation computed in " << t1 << " s." << std::endl; + + this->m_Mori.Set( mori.Get( )->GetOutput( ) ); + t1 = this->m_Mori.Save( mname ); + t += t1; + std::cout << "\"" << mname << "\" saved in " << t1 << " s." << std::endl; + + } // fi + std::cout << "Mori segmentation computed in " << t << " s." << std::endl; +} + +// ------------------------------------------------------------------------- +void CTBronchi::Process:: +_MoriLabelling( ) +{ + std::string mname = this->m_BaseFileName + "_labels.mha"; + double t = this->m_Labels.Load( mname ); + if( t < 0 ) + { + t = 0; + + // Arguments + std::stringstream v; + v << std::get< 0 >( this->m_DblArg[ "fastrw_thr" ] ) << " " + << std::get< 0 >( this->m_DblArg[ "labels_upper_thr" ] ); + std::istringstream w( v.str( ) ); + TScalar vThr, uThr; + w >> vThr >> uThr; + + // Mori labelling + typedef CTBronchi::Filter< CTBronchi::MoriLabelling< TPixelImage::TImage, TLabelImage::TImage, TScalarImage::TImage > > _TLabelling; + _TLabelling labelling; + labelling.Get( )->SetInput( this->m_Input.Get( ) ); + labelling.Get( )->SetInputLabels( this->m_Mori.Get( ) ); + labelling.Get( )->SetInputVesselness( this->m_Vesselness.Get( ) ); + labelling.Get( )->SetVesselnessThreshold( vThr ); + labelling.Get( )->SetUpperThreshold( uThr ); + labelling.Get( )->SetInsideValue( this->m_InsideLabel ); + labelling.Get( )->SetOutsideValue( this->m_OutsideLabel ); + labelling.Get( )->SetFillValue( this->m_OutsideLabel ); + double t1 = labelling.Update( ); + t += t1; + std::cout << "Labelling computed in " << t1 << " s." << std::endl; + + this->m_Labels.Set( labelling.Get( )->GetOutput( ) ); + t1 = this->m_Labels.Save( mname ); + t += t1; + std::cout << "\"" << mname << "\" saved in " << t1 << " s." << std::endl; + + } // fi + std::cout << "Mori labelling computed in " << t << " s." << std::endl; +} + +// eof - $RCSfile$ diff --git a/appli/CTBronchi/Process.h b/appli/CTBronchi/Process.h index 9daaf66..bae6f43 100644 --- a/appli/CTBronchi/Process.h +++ b/appli/CTBronchi/Process.h @@ -4,25 +4,65 @@ #ifndef __CTBronchi__Process__h__ #define __CTBronchi__Process__h__ -#include +#include +#include +#include +#include "Image.h" namespace CTBronchi { - class Process + class FPA_CTBRONCHI_EXPORT Process { + public: // Some types and values static const unsigned int Dim = 3; typedef short TPixel; typedef unsigned char TLabel; typedef float TScalar; - double MeasureTime( itk::ProcessObject* f ); - - template< class _TImagePtr > - void ReadImage( _TImagePtr& image, const std::string& fname ); - - template< class _TImage > - void WriteImage( const _TImage* image, const std::string& fname ); + // Arguments + typedef std::tuple< std::string, bool > TArgument; + typedef std::map< std::string, TArgument > TArguments; + + // Images + typedef CTBronchi::Image< TPixel, Dim > TPixelImage; + typedef CTBronchi::Image< TLabel, Dim > TLabelImage; + typedef CTBronchi::Image< TScalar, Dim > TScalarImage; + + // Seed + typedef TPixelImage::TImage::PointType TPoint; + typedef TPixelImage::TImage::IndexType TIndex; + typedef std::pair< TIndex, TPoint > TSeed; + + public: + Process( ); + virtual ~Process( ); + + void ParseArguments( int argc, char* argv[] ); + void Update( ); + + protected: + void _Input( ); + void _Vesselness( ); + void _Mori( ); + void _MoriLabelling( ); + + protected: + TArguments m_StrArg; + TArguments m_DblArg; + + std::string m_BaseFileName; + TSeed m_Seed; + TLabel m_UndefinedLabel; + TLabel m_InsideLabel; + TLabel m_OutsideLabel; + + TPixelImage m_Input; + TScalarImage m_Vesselness; + TLabelImage m_Mori; + TLabelImage m_Labels; + TLabelImage m_FastRW; + TLabelImage m_SliceRW; }; } // ecapseman