From: Leonardo Flórez-Valencia Date: Tue, 11 Jul 2017 04:27:05 +0000 (-0500) Subject: ... X-Git-Url: https://git.creatis.insa-lyon.fr/pubgit/?p=FrontAlgorithms.git;a=commitdiff_plain;h=6f716a6d2ce76a7bc9abb37406ce3802aa1e4451 ... --- diff --git a/appli/CTBronchi/CMakeLists.txt b/appli/CTBronchi/CMakeLists.txt index 446ff4c..1d7e316 100644 --- a/appli/CTBronchi/CMakeLists.txt +++ b/appli/CTBronchi/CMakeLists.txt @@ -3,11 +3,15 @@ if(fpa_BUILD_CTBronchi) include_directories( ${PROJECT_SOURCE_DIR}/lib ${PROJECT_BINARY_DIR}/lib + ${PROJECT_SOURCE_DIR}/appli + ${PROJECT_BINARY_DIR}/appli ) set(_pfx fpa_CTBronchi_) set( _examples MoriSegmentation + MoriLabelling + RandomWalker ) foreach(_e ${_examples}) add_executable(${_pfx}${_e} ${_e}.cxx) diff --git a/appli/CTBronchi/MoriLabelling.cxx b/appli/CTBronchi/MoriLabelling.cxx new file mode 100644 index 0000000..0915cd5 --- /dev/null +++ b/appli/CTBronchi/MoriLabelling.cxx @@ -0,0 +1,118 @@ +#include +#include +#include +#include +#include + +// ------------------------------------------------------------------------- +const unsigned int Dim = 3; +typedef short TPixel; +typedef unsigned short TLabel; + +typedef itk::Image< TPixel, Dim > TInputImage; +typedef itk::Image< TLabel, Dim > TLabelImage; + +typedef CTBronchi::MoriLabelling< TInputImage, TLabelImage > TFilter; + +// ------------------------------------------------------------------------- +int main( int argc, char* argv[] ) +{ + // Get arguments + if( argc < 8 ) + { + std::cerr + << "Usage: " << argv[ 0 ] << std::endl + << " input_image label_image output_image" << std::endl + << " upper_threshold(-400)" << std::endl + << " inside_value(255)" << std::endl + << " inside_label(1) outside_label(2)" + << std::endl; + return( 1 ); + + } // fi + std::string input_image_filename = argv[ 1 ]; + std::string label_image_filename = argv[ 2 ]; + std::string output_image_filename = argv[ 3 ]; + TLabel upper_threshold = std::atoi( argv[ 4 ] ); + TLabel inside_value = std::atoi( argv[ 5 ] ); + TLabel inside_label = std::atoi( argv[ 6 ] ); + TLabel outside_label = std::atoi( argv[ 7 ] ); + + // Read images + itk::ImageFileReader< TInputImage >::Pointer input_image_reader = + itk::ImageFileReader< TInputImage >::New( ); + input_image_reader->SetFileName( input_image_filename ); + + itk::ImageFileReader< TLabelImage >::Pointer label_image_reader = + itk::ImageFileReader< TLabelImage >::New( ); + label_image_reader->SetFileName( label_image_filename ); + + // Prepare filter + TFilter::Pointer filter = TFilter::New( ); + filter->SetInputLabelImage( label_image_reader->GetOutput( ) ); + filter->SetInputRawImage( input_image_reader->GetOutput( ) ); + filter->SetUpperThreshold( upper_threshold ); + filter->SetInsideValue( inside_value ); + filter->SetInsideLabel( inside_label ); + filter->SetOutsideLabel( outside_label ); + + // Show some information + std::cout << "----------------------------------------------" << std::endl; + std::cout << "Image: " << input_image_filename << std::endl; + + // Execute pipeline + std::chrono::time_point< std::chrono::high_resolution_clock > ts, te; + std::chrono::duration< double > tr; + try + { + ts = std::chrono::high_resolution_clock::now( ); + input_image_reader->Update( ); + te = std::chrono::high_resolution_clock::now( ); + tr = te - ts; + std::cout << "Raw read time: " << tr.count( ) << " s" << std::endl; + + ts = std::chrono::high_resolution_clock::now( ); + label_image_reader->Update( ); + te = std::chrono::high_resolution_clock::now( ); + tr = te - ts; + std::cout << "Label read time: " << tr.count( ) << " s" << std::endl; + + ts = std::chrono::high_resolution_clock::now( ); + filter->Update( ); + te = std::chrono::high_resolution_clock::now( ); + tr = te - ts; + std::cout + << "Labelling time: " << tr.count( ) << " s" << std::endl; + } + catch( std::exception& err ) + { + std::cerr << "Error caught: " << err.what( ) << std::endl; + return( 1 ); + + } // yrt + + // Save output image + itk::ImageFileWriter< TLabelImage >::Pointer output_image_writer = + itk::ImageFileWriter< TLabelImage >::New( ); + output_image_writer->SetInput( filter->GetOutput( ) ); + output_image_writer->SetFileName( output_image_filename ); + try + { + ts = std::chrono::high_resolution_clock::now( ); + output_image_writer->Update( ); + te = std::chrono::high_resolution_clock::now( ); + tr = te - ts; + std::cout << "Write time: " << tr.count( ) << " s" << std::endl; + } + catch( std::exception& err ) + { + std::cerr << "Error caught: " << err.what( ) << std::endl; + return( 1 ); + + } // yrt + std::cout << "----------------------------------------------" << std::endl; + + return( 0 ); +} + +// eof - $RCSfile$ diff --git a/appli/CTBronchi/MoriLabelling.h b/appli/CTBronchi/MoriLabelling.h new file mode 100644 index 0000000..105c7d0 --- /dev/null +++ b/appli/CTBronchi/MoriLabelling.h @@ -0,0 +1,80 @@ +// ========================================================================= +// @author Leonardo Florez Valencia +// @email florez-l@javeriana.edu.co +// ========================================================================= + +#ifndef __CTBronchi__MoriLabelling__h__ +#define __CTBronchi__MoriLabelling__h__ + +#include + +namespace CTBronchi +{ + /** + */ + template< class _TInputImage, class _TLabelImage > + class MoriLabelling + : public itk::ImageToImageFilter< _TLabelImage, _TLabelImage > + { + public: + typedef MoriLabelling Self; + typedef itk::ImageToImageFilter< _TLabelImage, _TLabelImage > Superclass; + typedef itk::SmartPointer< Self > Pointer; + typedef itk::SmartPointer< const Self > ConstPointer; + + typedef _TInputImage TInputImage; + typedef _TLabelImage TLabelImage; + typedef typename TInputImage::PixelType TPixel; + typedef typename TLabelImage::PixelType TLabel; + typedef typename TLabelImage::RegionType TRegion; + + public: + itkNewMacro( Self ); + itkTypeMacro( MoriLabelling, itk::ImageToImageFilter ); + + itkGetConstMacro( UpperThreshold, TPixel ); + itkSetMacro( UpperThreshold, TPixel ); + + itkGetConstMacro( InsideValue, TLabel ); + itkSetMacro( InsideValue, TLabel ); + + itkGetConstMacro( InsideLabel, TLabel ); + itkSetMacro( InsideLabel, TLabel ); + + itkGetConstMacro( OutsideLabel, TLabel ); + itkSetMacro( OutsideLabel, TLabel ); + + public: + const TLabelImage* GetInputLabelImage( ) const; + void SetInputLabelImage( TLabelImage* image ); + + const TInputImage* GetInputRawImage( ) const; + void SetInputRawImage( TInputImage* image ); + + protected: + MoriLabelling( ); + virtual ~MoriLabelling( ); + + virtual void ThreadedGenerateData( const TRegion& region, itk::ThreadIdType threadId ) override; + + private: + // Purposely not implemented. + MoriLabelling( const Self& other ); + Self& operator=( const Self& other ); + + protected: + TPixel m_UpperThreshold; + TLabel m_InsideValue; + TLabel m_InsideLabel; + TLabel m_OutsideLabel; + }; + +} // ecapseman + +#ifndef ITK_MANUAL_INSTANTIATION +# include +#endif // ITK_MANUAL_INSTANTIATION + +#endif // __CTBronchi__MoriLabelling__h__ + +// eof - $RCSfile$ diff --git a/appli/CTBronchi/MoriLabelling.hxx b/appli/CTBronchi/MoriLabelling.hxx new file mode 100644 index 0000000..5ca4fc4 --- /dev/null +++ b/appli/CTBronchi/MoriLabelling.hxx @@ -0,0 +1,105 @@ +// ========================================================================= +// @author Leonardo Florez Valencia +// @email florez-l@javeriana.edu.co +// ========================================================================= + +#ifndef __CTBronchi__MoriLabelling__hxx__ +#define __CTBronchi__MoriLabelling__hxx__ + +#include +#include + +// ------------------------------------------------------------------------- +template< class _TInputImage, class _TLabelImage > +const _TLabelImage* +CTBronchi::MoriLabelling< _TInputImage, _TLabelImage >:: +GetInputLabelImage( ) const +{ + return( this->GetInput( ) ); +} + +// ------------------------------------------------------------------------- +template< class _TInputImage, class _TLabelImage > +void CTBronchi::MoriLabelling< _TInputImage, _TLabelImage >:: +SetInputLabelImage( TLabelImage* image ) +{ + this->SetInput( image ); +} + +// ------------------------------------------------------------------------- +template< class _TInputImage, class _TLabelImage > +const _TInputImage* +CTBronchi::MoriLabelling< _TInputImage, _TLabelImage >:: +GetInputRawImage( ) const +{ + return( + dynamic_cast< const TInputImage* >( + this->itk::ProcessObject::GetInput( 1 ) + ) + ); +} + +// ------------------------------------------------------------------------- +template< class _TInputImage, class _TLabelImage > +void CTBronchi::MoriLabelling< _TInputImage, _TLabelImage >:: +SetInputRawImage( TInputImage* image ) +{ + this->itk::ProcessObject::SetNthInput( 1, image ); +} + +// ------------------------------------------------------------------------- +template< class _TInputImage, class _TLabelImage > +CTBronchi::MoriLabelling< _TInputImage, _TLabelImage >:: +MoriLabelling( ) + : Superclass( ), + m_UpperThreshold( TLabel( 0 ) ), + m_InsideValue( TLabel( 0 ) ), + m_InsideLabel( TLabel( 0 ) ), + m_OutsideLabel( TLabel( 0 ) ) +{ + this->SetNumberOfRequiredInputs( 2 ); +} + +// ------------------------------------------------------------------------- +template< class _TInputImage, class _TLabelImage > +CTBronchi::MoriLabelling< _TInputImage, _TLabelImage >:: +~MoriLabelling( ) +{ +} + +// ------------------------------------------------------------------------- +template< class _TInputImage, class _TLabelImage > +void CTBronchi::MoriLabelling< _TInputImage, _TLabelImage >:: +ThreadedGenerateData( const TRegion& region, itk::ThreadIdType threadId ) +{ + itk::ImageRegionConstIterator< TLabelImage > + lIt( this->GetInputLabelImage( ), region ); + itk::ImageRegionConstIterator< TInputImage > + iIt( this->GetInputRawImage( ), region ); + itk::ImageRegionIterator< TLabelImage > + oIt( this->GetOutput( ), region ); + + lIt.GoToBegin( ); + iIt.GoToBegin( ); + oIt.GoToBegin( ); + while( !( lIt.IsAtEnd( ) || iIt.IsAtEnd( ) || oIt.IsAtEnd( ) ) ) + { + if( lIt.Get( ) != this->m_InsideValue ) + { + if( this->m_UpperThreshold < iIt.Get( ) ) + oIt.Set( this->m_OutsideLabel ); + else + oIt.Set( TLabel( 0 ) ); + } + else + oIt.Set( this->m_InsideLabel ); + ++lIt; + ++iIt; + ++oIt; + + } // elihw +} + +#endif // __CTBronchi__MoriLabelling__hxx__ + +// eof - $RCSfile$ diff --git a/appli/CTBronchi/RandomWalker.cxx b/appli/CTBronchi/RandomWalker.cxx new file mode 100644 index 0000000..f6e81fb --- /dev/null +++ b/appli/CTBronchi/RandomWalker.cxx @@ -0,0 +1,120 @@ +#include +#include +#include +#include + +#include +#include + +// ------------------------------------------------------------------------- +const unsigned int Dim = 3; +typedef short TPixel; +typedef unsigned short TLabel; +typedef double TScalar; + +typedef itk::Image< TPixel, Dim > TInputImage; +typedef itk::Image< TLabel, Dim > TLabelImage; + +typedef fpa::Image::RandomWalker< TInputImage, TLabelImage, TScalar > TFilter; +typedef fpa::Image::Functors::Dijkstra::Gaussian< TInputImage, TScalar > TWeight; + +// ------------------------------------------------------------------------- +int main( int argc, char* argv[] ) +{ + // Get arguments + if( argc < 6 ) + { + std::cerr + << "Usage: " << argv[ 0 ] << std::endl + << " input_image label_image output_image" << std::endl + << " alpha(0) beta(100)" + << std::endl; + return( 1 ); + + } // fi + std::string input_image_filename = argv[ 1 ]; + std::string label_image_filename = argv[ 2 ]; + std::string output_image_filename = argv[ 3 ]; + double alpha = std::atof( argv[ 4 ] ); + double beta = std::atof( argv[ 5 ] ); + + // Read images + itk::ImageFileReader< TInputImage >::Pointer input_image_reader = + itk::ImageFileReader< TInputImage >::New( ); + input_image_reader->SetFileName( input_image_filename ); + + itk::ImageFileReader< TLabelImage >::Pointer label_image_reader = + itk::ImageFileReader< TLabelImage >::New( ); + label_image_reader->SetFileName( label_image_filename ); + + // Prepare weight + TWeight::Pointer weight = TWeight::New( ); + weight->SetAlpha( alpha ); + weight->SetBeta( beta ); + + // Prepare filter + TFilter::Pointer filter = TFilter::New( ); + filter->SetInput( input_image_reader->GetOutput( ) ); + filter->SetLabels( label_image_reader->GetOutput( ) ); + filter->SetWeightFunction( weight ); + + // Show some information + std::cout << "----------------------------------------------" << std::endl; + std::cout << "Image: " << input_image_filename << std::endl; + + // Execute pipeline + std::chrono::time_point< std::chrono::high_resolution_clock > ts, te; + std::chrono::duration< double > tr; + try + { + ts = std::chrono::high_resolution_clock::now( ); + input_image_reader->Update( ); + te = std::chrono::high_resolution_clock::now( ); + tr = te - ts; + std::cout << "Raw read time: " << tr.count( ) << " s" << std::endl; + + ts = std::chrono::high_resolution_clock::now( ); + label_image_reader->Update( ); + te = std::chrono::high_resolution_clock::now( ); + tr = te - ts; + std::cout << "Label read time: " << tr.count( ) << " s" << std::endl; + + ts = std::chrono::high_resolution_clock::now( ); + filter->Update( ); + te = std::chrono::high_resolution_clock::now( ); + tr = te - ts; + std::cout + << "Labelling time: " << tr.count( ) << " s" << std::endl; + } + catch( std::exception& err ) + { + std::cerr << "Error caught: " << err.what( ) << std::endl; + return( 1 ); + + } // yrt + + // Save output image + itk::ImageFileWriter< TLabelImage >::Pointer output_image_writer = + itk::ImageFileWriter< TLabelImage >::New( ); + output_image_writer->SetInput( filter->GetMarks( ) ); + output_image_writer->SetFileName( output_image_filename ); + try + { + ts = std::chrono::high_resolution_clock::now( ); + output_image_writer->Update( ); + te = std::chrono::high_resolution_clock::now( ); + tr = te - ts; + std::cout << "Write time: " << tr.count( ) << " s" << std::endl; + } + catch( std::exception& err ) + { + std::cerr << "Error caught: " << err.what( ) << std::endl; + return( 1 ); + + } // yrt + std::cout << "----------------------------------------------" << std::endl; + + return( 0 ); +} + +// eof - $RCSfile$ diff --git a/lib/fpa/Base/Mori.hxx b/lib/fpa/Base/Mori.hxx index 3d1a94d..723e6fa 100644 --- a/lib/fpa/Base/Mori.hxx +++ b/lib/fpa/Base/Mori.hxx @@ -218,8 +218,8 @@ _FinishOneLoop( ) TPeak p = this->m_PeakDetector.AddValue( *this->m_CurrThr, this->m_CurrCount ); - std::cout << *( this->m_CurrThr ) << " " << this->m_CurrCount << std::endl; this->m_CurrThr++; + this->m_CurrQueue = ( this->m_CurrQueue + 1 ) % 2; if( this->m_CurrThr != this->m_Thresholds.end( ) ) { // Update predicate and counting value diff --git a/lib/fpa/Image/RandomWalker.hxx b/lib/fpa/Image/RandomWalker.hxx index 5fb7768..21abc08 100644 --- a/lib/fpa/Image/RandomWalker.hxx +++ b/lib/fpa/Image/RandomWalker.hxx @@ -93,7 +93,8 @@ _UnifySeeds( ) { TVertex neigh = lIt.GetIndex( ); neigh[ d ] += s; - is_seed |= ( lbl->GetPixel( neigh ) == 0 ); + if( reg.IsInside( neigh ) ) + is_seed |= ( lbl->GetPixel( neigh ) == 0 ); } // rof