]> Creatis software - FrontAlgorithms.git/commitdiff
...
authorLeonardo Flórez-Valencia <leonardo.florez@gmail.com>
Tue, 11 Jul 2017 04:27:05 +0000 (23:27 -0500)
committerLeonardo Flórez-Valencia <leonardo.florez@gmail.com>
Tue, 11 Jul 2017 04:27:05 +0000 (23:27 -0500)
appli/CTBronchi/CMakeLists.txt
appli/CTBronchi/MoriLabelling.cxx [new file with mode: 0644]
appli/CTBronchi/MoriLabelling.h [new file with mode: 0644]
appli/CTBronchi/MoriLabelling.hxx [new file with mode: 0644]
appli/CTBronchi/RandomWalker.cxx [new file with mode: 0644]
lib/fpa/Base/Mori.hxx
lib/fpa/Image/RandomWalker.hxx

index 446ff4c032256a350d5f4843adcbd41c04f5393f..1d7e316e60d3e95c16444125b80c430bd1535103 100644 (file)
@@ -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 (file)
index 0000000..0915cd5
--- /dev/null
@@ -0,0 +1,118 @@
+#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$
diff --git a/appli/CTBronchi/MoriLabelling.h b/appli/CTBronchi/MoriLabelling.h
new file mode 100644 (file)
index 0000000..105c7d0
--- /dev/null
@@ -0,0 +1,80 @@
+// =========================================================================
+// @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$
diff --git a/appli/CTBronchi/MoriLabelling.hxx b/appli/CTBronchi/MoriLabelling.hxx
new file mode 100644 (file)
index 0000000..5ca4fc4
--- /dev/null
@@ -0,0 +1,105 @@
+// =========================================================================
+// @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$
diff --git a/appli/CTBronchi/RandomWalker.cxx b/appli/CTBronchi/RandomWalker.cxx
new file mode 100644 (file)
index 0000000..f6e81fb
--- /dev/null
@@ -0,0 +1,120 @@
+#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$
index 3d1a94dfa63e996cbf36aa580a8ae15bdd964660..723e6fa285839562ccff88590825bcb14b47712b 100644 (file)
@@ -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
index 5fb77681d925dd0a3c7b6b92072094de2fbaf6ac..21abc08f617cf5aede6f97a1b71c803f1314a71f 100644 (file)
@@ -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