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)
--- /dev/null
+#include <chrono>
+#include <itkImage.h>
+#include <itkImageFileReader.h>
+#include <itkImageFileWriter.h>
+#include <CTBronchi/MoriLabelling.h>
+
+// -------------------------------------------------------------------------
+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$
--- /dev/null
+// =========================================================================
+// @author Leonardo Florez Valencia
+// @email florez-l@javeriana.edu.co
+// =========================================================================
+
+#ifndef __CTBronchi__MoriLabelling__h__
+#define __CTBronchi__MoriLabelling__h__
+
+#include <itkImageToImageFilter.h>
+
+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 <CTBronchi/MoriLabelling.hxx>
+#endif // ITK_MANUAL_INSTANTIATION
+
+#endif // __CTBronchi__MoriLabelling__h__
+
+// eof - $RCSfile$
--- /dev/null
+// =========================================================================
+// @author Leonardo Florez Valencia
+// @email florez-l@javeriana.edu.co
+// =========================================================================
+
+#ifndef __CTBronchi__MoriLabelling__hxx__
+#define __CTBronchi__MoriLabelling__hxx__
+
+#include <itkImageRegionConstIterator.h>
+#include <itkImageRegionIterator.h>
+
+// -------------------------------------------------------------------------
+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$
--- /dev/null
+#include <chrono>
+#include <itkImage.h>
+#include <itkImageFileReader.h>
+#include <itkImageFileWriter.h>
+
+#include <fpa/Image/RandomWalker.h>
+#include <fpa/Image/Functors/Dijkstra/Gaussian.h>
+
+// -------------------------------------------------------------------------
+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$
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
{
TVertex neigh = lIt.GetIndex( );
neigh[ d ] += s;
- is_seed |= ( lbl->GetPixel( neigh ) == 0 );
+ if( reg.IsInside( neigh ) )
+ is_seed |= ( lbl->GetPixel( neigh ) == 0 );
} // rof