]> Creatis software - FrontAlgorithms.git/commitdiff
...
authorLeonardo Flórez-Valencia <florez-l@javeriana.edu.co>
Thu, 16 Mar 2017 21:42:33 +0000 (16:42 -0500)
committerLeonardo Flórez-Valencia <florez-l@javeriana.edu.co>
Thu, 16 Mar 2017 21:42:33 +0000 (16:42 -0500)
16 files changed:
data/input_mori_binary.png [new file with mode: 0644]
examples/BronchiiInitialSegmentationWithBinaryThresholdRegionGrow.cxx [new file with mode: 0644]
examples/BronchiiInitialSegmentationWithMori.cxx
examples/CMakeLists.txt
examples/CreateMoriInputImage.cxx [new file with mode: 0644]
libs/fpa/Base/Algorithm.h
libs/fpa/Base/Algorithm.hxx
libs/fpa/Base/RegionGrow.h
libs/fpa/Base/RegionGrow.hxx
libs/fpa/Image/Algorithm.h
libs/fpa/Image/Algorithm.hxx
libs/fpa/Image/Functors/RegionGrow/BinaryThreshold.hxx
libs/fpa/Image/MoriFilter.h
libs/fpa/Image/MoriFilter.hxx
libs/fpa/Image/MoriFilterHelper.h
libs/fpa/Image/MoriFilterHelper.hxx

diff --git a/data/input_mori_binary.png b/data/input_mori_binary.png
new file mode 100644 (file)
index 0000000..d605247
Binary files /dev/null and b/data/input_mori_binary.png differ
diff --git a/examples/BronchiiInitialSegmentationWithBinaryThresholdRegionGrow.cxx b/examples/BronchiiInitialSegmentationWithBinaryThresholdRegionGrow.cxx
new file mode 100644 (file)
index 0000000..8381cff
--- /dev/null
@@ -0,0 +1,116 @@
+#include <climits>
+#include <cstdlib>
+#include <fstream>
+#include <iostream>
+#include <string>
+
+#include <itkImage.h>
+#include <itkImageFileReader.h>
+#include <itkImageFileWriter.h>
+
+#include <fpa/Image/RegionGrow.h>
+#include <fpa/Image/Functors/RegionGrow/BinaryThreshold.h>
+
+// -------------------------------------------------------------------------
+static const unsigned int Dim = 3;
+typedef short TPixel;
+typedef itk::Image< TPixel, Dim > TImage;
+
+// -------------------------------------------------------------------------
+std::string GetFullPath( const std::string& filename )
+{
+  /* On windows:
+     #include <windows.h>
+     TCHAR full_path[MAX_PATH];
+     GetFullPathName(_T("foo.dat"), MAX_PATH, full_path, NULL);
+  */
+
+  char* buffer = realpath( filename.c_str( ), NULL );
+  std::string path = buffer;
+  std::free( buffer );
+  return( path );
+}
+
+// -------------------------------------------------------------------------
+std::string GetFullPathToDirectory( const std::string& filename )
+{
+  std::string path = GetFullPath( filename );
+  std::size_t found = path.find_last_of( "/\\" );
+  return( path.substr( 0, found + 1 ) );
+}
+
+// -------------------------------------------------------------------------
+int main( int argc, char* argv[] )
+{
+  // Command configuration
+  if( argc < 5 )
+  {
+    std::cerr
+      << "Usage: " << argv[ 0 ] << " input_image output_image lower upper"
+      << std::endl;
+    return( 1 );
+
+  } // fi
+  std::string input_image_filename = GetFullPath( argv[ 1 ] );
+  std::string output_image_filename = argv[ 2 ];
+  std::string output_auxiliary_image_filename = output_image_filename + "_aux.mhd";
+  TPixel lower = std::atoi( argv[ 3 ] );
+  TPixel upper = std::atoi( argv[ 4 ] );
+
+  // Try to guess initial seed
+  std::string seed_filename = GetFullPathToDirectory( argv[ 1 ] ) + "seed.txt";
+  std::ifstream seed_str( seed_filename.c_str( ) );
+  if( !seed_str )
+  {
+    std::cerr
+      << "No \"seed.txt\" file in the same input image directory."
+      << std::endl;
+    return( 1 );
+
+  } // fi
+  TImage::IndexType seed;
+  seed_str >> seed[ 0 ] >> seed[ 1 ] >> seed[ 2 ];
+  seed_str.close( );
+
+  // Read image
+  typedef itk::ImageFileReader< TImage > TReader;
+  TReader::Pointer reader = TReader::New( );
+  reader->SetFileName( input_image_filename );
+
+  // Growing predicate
+  typedef fpa::Image::Functors::RegionGrow::BinaryThreshold< TImage, TImage::PixelType > TPredicate;
+  TPredicate::Pointer predicate = TPredicate::New( );
+  predicate->SetLower( lower );
+  predicate->SetUpper( upper );
+
+  // RegionGrow algorithm
+  typedef fpa::Image::RegionGrow< TImage, TImage > TFilter;
+  TFilter::Pointer filter = TFilter::New( );
+  filter->SetInput( reader->GetOutput( ) );
+  filter->AddSeed( seed, 1 );
+  filter->SetInsideValue( 1 );
+  filter->SetOutsideValue( 0 );
+  filter->SetGrowFunction( predicate );
+
+  // Write results
+  typedef itk::ImageFileWriter< TImage > TWriter;
+  TWriter::Pointer writer = TWriter::New( );
+  writer->SetInput( filter->GetOutput( ) );
+  writer->SetFileName( output_image_filename );
+
+  // Execute pipeline
+  try
+  {
+    writer->Update( );
+  }
+  catch( std::exception& err )
+  {
+    std::cerr << "Error caught: " << err.what( ) << std::endl;
+    return( 1 );
+
+  } // yrt
+
+  return( 0 );
+}
+
+// eof - $RCSfile$
index ed0c294132e264d2a11558f45616a870ac89bdd9..fa940d5a1ce5af997fcbf20bbbdfa430f6eb2254 100644 (file)
@@ -52,6 +52,7 @@ int main( int argc, char* argv[] )
   } // fi
   std::string input_image_filename = GetFullPath( argv[ 1 ] );
   std::string output_image_filename = argv[ 2 ];
+  std::string output_auxiliary_image_filename = output_image_filename + "_aux.mhd";
 
   // Try to guess initial seed
   std::string seed_filename = GetFullPathToDirectory( argv[ 1 ] ) + "seed.txt";
@@ -66,6 +67,7 @@ int main( int argc, char* argv[] )
   } // fi
   TImage::IndexType seed;
   seed_str >> seed[ 0 ] >> seed[ 1 ] >> seed[ 2 ];
+  seed_str.close( );
 
   // Read image
   typedef itk::ImageFileReader< TImage > TReader;
@@ -77,7 +79,7 @@ int main( int argc, char* argv[] )
   TFilter::Pointer filter = TFilter::New( );
   filter->SetInput( reader->GetOutput( ) );
   filter->SetSeed( seed );
-  filter->SetThresholdRange( -1024, 0 );
+  filter->SetThresholdRange( -200, 100, 1 );
   filter->SetInsideValue( 1 );
   filter->SetOutsideValue( 0 );
 
@@ -98,6 +100,57 @@ int main( int argc, char* argv[] )
     return( 1 );
 
   } // yrt
+
+  // Write auxiliary image
+  typedef itk::ImageFileWriter< TFilter::TAuxImage > TAuxWriter;
+  TAuxWriter::Pointer aux_writer = TAuxWriter::New( );
+  aux_writer->SetInput( filter->GetAuxiliaryImage( ) );
+  aux_writer->SetFileName( output_auxiliary_image_filename );
+
+  // Execute pipeline
+  try
+  {
+    aux_writer->Update( );
+  }
+  catch( std::exception& err )
+  {
+    std::cerr << "Error caught: " << err.what( ) << std::endl;
+    return( 1 );
+
+  } // yrt
+
+  // Write result signal
+  std::string output_signal_filename = output_image_filename + ".csv";
+  std::ofstream output_signal_str( output_signal_filename.c_str( ) );
+  TFilter::TCurve curve = filter->GetCurve( );
+  unsigned long max_count = 0;
+  for( TFilter::TCurve::value_type d : curve )
+  {
+    output_signal_str << d.first << " " << d.second << std::endl;
+    if( max_count < d.second )
+      max_count = d.second;
+
+  } // rof
+  output_signal_str.close( );
+
+  // Write gnuplot script
+  std::string output_gnuplot_filename = output_image_filename + ".gnuplot";
+  std::ofstream output_gnuplot_str( output_gnuplot_filename.c_str( ) );
+  unsigned int thr_pos = filter->GetOptimumThreshold( );
+  int thr = curve[ thr_pos ].first;
+  output_gnuplot_str
+    << "set term png" << std::endl
+    << "set output \"" << output_image_filename << ".png\"" << std::endl
+    << "set arrow 1 from " << thr
+    << ",0 to " << thr << "," << max_count
+    << std::endl
+    << "show arrow 1" << std::endl
+    << "plot \"" << output_signal_filename
+    << "\" using 1:2 with linespoints title \"Evolution ("
+    << thr << "," << thr_pos << ") " << "\""
+    << std::endl;
+  output_gnuplot_str.close( );
+
   return( 0 );
 }
 
index 8205f496047cb84237541553ba978a126ed5bc87..0b9e558044eea95077f84896fc56d6ffa3b3245e 100644 (file)
@@ -2,7 +2,9 @@ OPTION(BUILD_EXAMPLES "Build cpPlugins-free examples." OFF)
 IF(BUILD_EXAMPLES)
   SET(
     _examples
+    CreateMoriInputImage
     BronchiiInitialSegmentationWithMori
+    BronchiiInitialSegmentationWithBinaryThresholdRegionGrow
     )
   INCLUDE_DIRECTORIES(
     ${PROJECT_SOURCE_DIR}/libs
diff --git a/examples/CreateMoriInputImage.cxx b/examples/CreateMoriInputImage.cxx
new file mode 100644 (file)
index 0000000..144ed6e
--- /dev/null
@@ -0,0 +1,64 @@
+#include <queue>
+#include <itkImage.h>
+#include <itkImageFileReader.h>
+#include <itkSignedMaurerDistanceMapImageFilter.h>
+#include <itkImageFileWriter.h>
+
+// -------------------------------------------------------------------------
+static const unsigned int Dim = 2;
+typedef short TInputPixel;
+typedef float TOutputPixel;
+typedef itk::Image< TInputPixel, Dim > TInputImage;
+typedef itk::Image< TOutputPixel, Dim > TOutputImage;
+
+// -------------------------------------------------------------------------
+int main( int argc, char* argv[] )
+{
+  // Command configuration
+  if( argc < 3 )
+  {
+    std::cerr
+      << "Usage: " << argv[ 0 ] << " input_image output_image"
+      << std::endl;
+    return( 1 );
+
+  } // fi
+  std::string input_image_filename = argv[ 1 ];
+  std::string output_image_filename = argv[ 2 ];
+
+  // Read image
+  typedef itk::ImageFileReader< TInputImage > TReader;
+  TReader::Pointer reader = TReader::New( );
+  reader->SetFileName( input_image_filename );
+
+  // Distance map
+  typedef itk::SignedMaurerDistanceMapImageFilter< TInputImage, TOutputImage > TFilter;
+  TFilter::Pointer filter = TFilter::New( );
+  filter->SetInput( reader->GetOutput( ) );
+  filter->SetBackgroundValue( 0 );
+  filter->InsideIsPositiveOn( );
+  filter->SquaredDistanceOff( );
+  filter->UseImageSpacingOn( );
+
+  // Write image
+  typedef itk::ImageFileWriter< TOutputImage > TWriter;
+  TWriter::Pointer writer = TWriter::New( );
+  writer->SetInput( filter->GetOutput( ) );
+  writer->SetFileName( output_image_filename );
+
+  // Execute pipeline
+  try
+  {
+    writer->Update( );
+  }
+  catch( std::exception& err )
+  {
+    std::cerr << "Error caught: " << err.what( ) << std::endl;
+    return( 1 );
+
+  } // yrt
+
+  return( 0 );
+}
+
+// eof - $RCSfile$
index 6625467e29ae3c698b4a3d55d61ac9c6464a8649..232c4b3672288fbfe82d1bfa1c3b423ac0613049 100644 (file)
@@ -102,14 +102,14 @@ namespace fpa
       virtual bool _ValidLoop( ) const;
       virtual void _UpdateCollisions( const TVertex& a, const TVertex& b );
 
-      virtual _TOutput _GetInputValue( const _TQueueNode& v, const _TQueueNode& p );
+      virtual _TOutput _GetInputValue( const TVertex& v, const TVertex& p );
+      virtual bool _UpdateResult( _TQueueNode& n );
 
       virtual void _InitMarks( ) = 0;
       virtual void _InitResults( const TOutput& init_value ) = 0;
       virtual bool _IsMarked( const _TVertex& v ) const = 0;
       virtual void _Mark( const _TQueueNode& n ) = 0;
       virtual TFrontId _GetMark( const _TVertex& v ) const = 0;
-      virtual void _UpdateResult( const _TQueueNode& n ) = 0;
       virtual TOutput _GetResult( const _TVertex& v ) const = 0;
       virtual unsigned int _GetNumberOfDimensions( ) const = 0;
 
index c29ff03e174791bea40b5155fab7e55f2526db72..2b82a4f47d654a3f4857d6d780f6549cf07bbdf7 100644 (file)
@@ -137,8 +137,9 @@ _Loop( )
     if( this->_IsMarked( node.Vertex ) )
       continue;
     this->_Mark( node );
-    this->_UpdateResult( node );
     this->InvokeEvent( TMarkEvent( node.Vertex, node.FrontId ) );
+    if( !( this->_UpdateResult( node ) ) )
+      continue;
 
     // Add neighbors to queue
     TNeighborhood neighs = this->m_NeighborhoodFunction->Evaluate( node.Vertex );
@@ -254,16 +255,24 @@ _UpdateCollisions( const TVertex& a, const TVertex& b )
 // -------------------------------------------------------------------------
 template < class _TFilter, class _TVertex, class _TOutput >
 _TOutput fpa::Base::Algorithm< _TFilter, _TVertex, _TOutput >::
-_GetInputValue( const _TQueueNode& v, const _TQueueNode& p )
+_GetInputValue( const TVertex& v, const TVertex& p )
 {
   _TOutput res = this->m_InitResult;
   if( this->m_VertexFunction.IsNotNull( ) )
-    res = this->m_VertexFunction->Evaluate( v.Vertex, p.Vertex );
+    res = this->m_VertexFunction->Evaluate( v, p );
   if( this->m_ConversionFunction.IsNotNull( ) )
     res = this->m_ConversionFunction->Evaluate( res );
   return( res );
 }
 
+// -------------------------------------------------------------------------
+template < class _TFilter, class _TVertex, class _TOutput >
+bool fpa::Base::Algorithm< _TFilter, _TVertex, _TOutput >::
+_UpdateResult( _TQueueNode& n )
+{
+  return( true );
+}
+
 #endif // __fpa__Base__Algorithm__hxx__
 
 // eof - $RCSfile$
index 4790b851a9273768e1d0ae5f4cf1e79e03d025aa..ea9008af8ad3191a572534a06ec172f44319d85f 100644 (file)
@@ -48,13 +48,10 @@ namespace fpa
       virtual bool _UpdateValue(
         _TQueueNode& v, const _TQueueNode& p
         ) override;
-      virtual TOutput _GetInputValue( const _TQueueNode& v, const _TQueueNode& p ) override
-        {
-          TOutput res = this->m_InitResult;
-          if( this->m_GrowFunction.IsNotNull( ) )
-            res = this->m_GrowFunction->Evaluate( v.Vertex, p.Vertex );
-          return( res );
-        }
+      virtual TOutput _GetInputValue(
+        const TVertex& v, const TVertex& p
+        ) override;
+      virtual bool _UpdateResult( _TQueueNode& n ) override;
 
 
     private:
index c3cb9f3a355fccca44f8f8776702fea5d2ea7013..3def0a7656dd729d1256ff1f8157c9569da8d29e 100644 (file)
@@ -9,7 +9,6 @@ typename fpa::Base::RegionGrow< _TSuperclass >::
 TGrowFunction* fpa::Base::RegionGrow< _TSuperclass >::
 GetGrowFunction( )
 {
-  // TODO: return( dynamic_cast< TGrowFunction* >( this->GetVertexFunction( ) ) );
   return( this->m_GrowFunction );
 }
 
@@ -19,11 +18,6 @@ const typename fpa::Base::RegionGrow< _TSuperclass >::
 TGrowFunction* fpa::Base::RegionGrow< _TSuperclass >::
 GetGrowFunction( ) const
 {
-  /* TODO
-     return(
-     dynamic_cast< const TGrowFunction* >( this->GetVertexFunction( ) )
-     );
-  */
   return( this->m_GrowFunction );
 }
 
@@ -119,8 +113,29 @@ template< class _TSuperclass >
 bool fpa::Base::RegionGrow< _TSuperclass >::
 _UpdateValue( _TQueueNode& v, const _TQueueNode& p )
 {
-  v.Result = this->_GetInputValue( v, p );
-  return( v.Result == this->GetInsideValue( ) );
+  return( true );
+}
+
+// -------------------------------------------------------------------------
+template< class _TSuperclass >
+typename fpa::Base::RegionGrow< _TSuperclass >::
+TOutput fpa::Base::RegionGrow< _TSuperclass >::
+_GetInputValue( const TVertex& v, const TVertex& p )
+{
+  TOutput res = this->m_InitResult;
+  if( this->m_GrowFunction.IsNotNull( ) )
+    res = this->m_GrowFunction->Evaluate( v, p );
+  return( res );
+}
+
+// -------------------------------------------------------------------------
+template< class _TSuperclass >
+bool fpa::Base::RegionGrow< _TSuperclass >::
+_UpdateResult( _TQueueNode& n )
+{
+  n.Result = this->_GetInputValue( n.Vertex, n.Parent );
+  this->Superclass::_UpdateResult( n );
+  return( n.Result == this->GetInsideValue( ) );
 }
 
 #endif // __fpa__Base__RegionGrow__hxx__
index 0105cc3080d13166c0a23ca5b702b7622012c795..11c1cb28eb5b61c7350f1bf357de80c437aa0e8b 100644 (file)
@@ -48,7 +48,7 @@ namespace fpa
       virtual bool _IsMarked( const TVertex& v ) const override;
       virtual void _Mark( const _TQueueNode& n ) override;
       virtual TFrontId _GetMark( const TVertex& v ) const override;
-      virtual void _UpdateResult( const _TQueueNode& n ) override;
+      virtual bool _UpdateResult( _TQueueNode& n ) override;
       virtual TOutput _GetResult( const TVertex& v ) const override;
       virtual unsigned int _GetNumberOfDimensions( ) const override;
 
index 3c33e4e3ca90019e7ac77b58c1c8ae9b541948cc..00077d3e5858f1f7675f7e65c0a07f8c49d0be87 100644 (file)
@@ -118,10 +118,13 @@ _GetMark( const TVertex& v ) const
 
 // -------------------------------------------------------------------------
 template< class _TInputImage, class _TOutputImage >
-void fpa::Image::Algorithm< _TInputImage, _TOutputImage >::
-_UpdateResult( const _TQueueNode& n )
+bool fpa::Image::Algorithm< _TInputImage, _TOutputImage >::
+_UpdateResult( _TQueueNode& n )
 {
+  bool res = this->Superclass::_UpdateResult( n );
+  std::cout << n.Vertex << " " << n.Result << std::endl;
   this->GetOutput( )->SetPixel( n.Vertex, n.Result );
+  return( res );
 }
 
 // -------------------------------------------------------------------------
index 7f2b9dca99bc40f2e4b78cfdbe6a95d0ab3137ec..b41db088b022025d1754ecb28cafcf8c6930c2f0 100644 (file)
@@ -14,6 +14,9 @@ Evaluate( const TIndex& a, const TIndex& b ) const
   if( im != NULL )
   {
     TPixel v = im->GetPixel( b );
+
+    std::cout << a << " " << v << " " << this->m_Lower << " " << this->m_Upper << std::endl;
+
     return(
       ( this->m_Lower < v && v < this->m_Upper )?
       this->m_InsideValue:
index 0707ff5c2bfb2934fc145deb9d793c744f5ed86f..a78aab7f47925fe499890792a881d77e8168fa10 100644 (file)
@@ -16,18 +16,19 @@ namespace fpa
       : public itk::ImageToImageFilter< _TInputImage, _TOutputImage >
     {
     public:
-      typedef MoriFilter                                         Self;
+      typedef MoriFilter                                             Self;
       typedef itk::ImageToImageFilter< _TInputImage, _TOutputImage > Superclass;
       typedef itk::SmartPointer< Self >                              Pointer;
       typedef itk::SmartPointer< const Self >                        ConstPointer;
 
       typedef itk::Image< _TAuxPixel, _TInputImage::ImageDimension >      TAuxImage;
-      typedef fpa::Image::MoriFilterHelper< _TInputImage, TAuxImage > THelper;
+      typedef fpa::Image::MoriFilterHelper< _TInputImage, TAuxImage >     THelper;
       typedef itk::BinaryThresholdImageFilter< TAuxImage, _TOutputImage > TThreshold;
 
       typedef typename _TInputImage::IndexType  TIndex;
       typedef typename _TInputImage::PixelType  TInputPixel;
       typedef typename _TOutputImage::PixelType TOutputPixel;
+      typedef typename THelper::TCurve          TCurve;
 
     public:
       itkNewMacro( Self );
@@ -45,6 +46,8 @@ namespace fpa
       TInputPixel GetStep( ) const;
       TOutputPixel GetInsideValue( ) const;
       TOutputPixel GetOutsideValue( ) const;
+      TOutputPixel GetOptimumThreshold( ) const;
+      TCurve GetCurve( ) const;
 
       void SetLower( const TInputPixel& v );
       void SetUpper( const TInputPixel& v );
@@ -56,18 +59,6 @@ namespace fpa
       void SetInsideValue( const TOutputPixel& v );
       void SetOutsideValue( const TOutputPixel& v );
 
-
-      /* TODO
-         itkGetConstMacro( Lower, TPixel );
-         itkGetConstMacro( Upper, TPixel );
-         itkGetConstMacro( Step, TPixel );
-         itkGetConstMacro( Sensitivity, double );
-         itkSetMacro( Lower, TPixel );
-         itkSetMacro( Upper, TPixel );
-         itkSetMacro( Step, TPixel );
-         itkSetMacro( Sensitivity, double );
-      */
-
     protected:
       MoriFilter( );
       virtual ~MoriFilter( );
index 9f822c9ea9d22bd6234ddd1a823266b2727c6680..6c749c65b0289cd7ba90d76fa10a1d1055783e24 100644 (file)
@@ -78,6 +78,27 @@ GetOutsideValue( ) const
   return( this->m_Threshold->GetInsideValue( ) );
 }
 
+// -------------------------------------------------------------------------
+template< class _TInputImage, class _TOutputImage, class _TAuxPixel >
+typename
+fpa::Image::MoriFilter< _TInputImage, _TOutputImage, _TAuxPixel >::
+TOutputPixel
+fpa::Image::MoriFilter< _TInputImage, _TOutputImage, _TAuxPixel >::
+GetOptimumThreshold( ) const
+{
+  return( this->m_Helper->GetOptimumThreshold( ) );
+}
+
+// -------------------------------------------------------------------------
+template< class _TInputImage, class _TOutputImage, class _TAuxPixel >
+typename
+fpa::Image::MoriFilter< _TInputImage, _TOutputImage, _TAuxPixel >::
+TCurve fpa::Image::MoriFilter< _TInputImage, _TOutputImage, _TAuxPixel >::
+GetCurve( ) const
+{
+  return( this->m_Helper->GetCurve( ) );
+}
+
 // -------------------------------------------------------------------------
 template< class _TInputImage, class _TOutputImage, class _TAuxPixel >
 void fpa::Image::MoriFilter< _TInputImage, _TOutputImage, _TAuxPixel >::
@@ -157,8 +178,7 @@ template< class _TInputImage, class _TOutputImage, class _TAuxPixel >
 void fpa::Image::MoriFilter< _TInputImage, _TOutputImage, _TAuxPixel >::
 GenerateData( )
 {
-  this->m_Helper->ClearSeeds( );
-  this->m_Helper->AddSeed( this->m_Seed, this->GetOutsideValue( ) );
+  this->m_Helper->SetSeed( this->m_Seed );
   this->m_Helper->SetInput( this->GetInput( ) );
   this->m_Helper->Update( );
 
index 6d55ec7cb6d10b5b4f78a5b4a021f77879574fb2..d9a4a3dc5c25d637e59e5494f87365ea6eae1daf 100644 (file)
@@ -1,10 +1,13 @@
 #ifndef __fpa__Image__MoriFilterHelper__h__
 #define __fpa__Image__MoriFilterHelper__h__
 
+/* TODO
+   #include <fpa/Image/RegionGrow.h>
+   #include <fpa/Image/Functors/RegionGrow/BinaryThreshold.h>
+*/
 #include <utility>
 #include <vector>
-#include <fpa/Image/RegionGrow.h>
-#include <fpa/Image/Functors/RegionGrow/BinaryThreshold.h>
+#include <itkImageToImageFilter.h>
 
 namespace fpa
 {
@@ -14,52 +17,68 @@ namespace fpa
      */
     template< class _TInputImage, class _TOutputImage >
     class MoriFilterHelper
-      : public fpa::Image::RegionGrow< _TInputImage, _TOutputImage >
+      : public itk::ImageToImageFilter< _TInputImage, _TOutputImage >
     {
     public:
-      typedef MoriFilterHelper                                        Self;
-      typedef fpa::Image::RegionGrow< _TInputImage, _TOutputImage > Superclass;
-      typedef itk::SmartPointer< Self >                             Pointer;
-      typedef itk::SmartPointer< const Self >                       ConstPointer;
-
-      typedef typename Superclass::TOutput       TOutput;
-      typedef typename Superclass::TVertex       TVertex;
-      typedef typename Superclass::TGrowFunction TGrowFunction;
-      typedef typename _TInputImage::PixelType   TPixel;
-      typedef fpa::Image::Functors::RegionGrow::BinaryThreshold< _TInputImage, TOutput > TBinThresholdFunction;
-
-    protected:
-      typedef typename Superclass::_TQueueNode _TQueueNode;
-      typedef typename Superclass::_TQueue     _TQueue;
-
-      typedef std::pair< TPixel, unsigned long > TCurveData;
-      typedef std::vector< TCurveData >          TCurve;
+      typedef MoriFilterHelper                                       Self;
+      typedef itk::ImageToImageFilter< _TInputImage, _TOutputImage > Superclass;
+      typedef itk::SmartPointer< Self >                              Pointer;
+      typedef itk::SmartPointer< const Self >                        ConstPointer;
+
+      typedef _TInputImage  TInputImage;
+      typedef _TOutputImage TOutputImage;
+      typedef typename TInputImage::IndexType  TIndex;
+      typedef typename TInputImage::PixelType  TInputPixel;
+      typedef typename TOutputImage::PixelType TOutputPixel;
+
+      typedef std::pair< TInputPixel, unsigned long > TCurveData;
+      typedef std::vector< TCurveData >               TCurve;
+
+      /* TODO
+         typedef typename Superclass::TOutput       TOutput;
+         typedef typename Superclass::TVertex       TVertex;
+         typedef typename Superclass::TGrowFunction TGrowFunction;
+         typedef typename _TInputImage::PixelType   TPixel;
+         typedef fpa::Image::Functors::RegionGrow::BinaryThreshold< _TInputImage, TOutput > TBinThresholdFunction;
+         protected:
+         typedef typename Superclass::_TQueueNode _TQueueNode;
+         typedef typename Superclass::_TQueue     _TQueue;
+      */
 
     public:
       itkNewMacro( Self );
-      itkTypeMacro( fpa::Image::MoriFilterHelper, fpa::Image::RegionGrow );
+      itkTypeMacro( fpa::Image::MoriFilterHelper, itk::ImageToImageFilter );
 
-      itkGetConstMacro( Lower, TPixel );
-      itkGetConstMacro( Upper, TPixel );
-      itkGetConstMacro( Step, TPixel );
+      itkGetConstMacro( Seed, TIndex );
+      itkGetConstMacro( Lower, TInputPixel );
+      itkGetConstMacro( Upper, TInputPixel );
+      itkGetConstMacro( Step, TInputPixel );
       itkGetConstMacro( OptimumThreshold, typename _TOutputImage::PixelType );
+      itkGetConstMacro( Curve, TCurve );
 
-      itkSetMacro( Lower, TPixel );
-      itkSetMacro( Upper, TPixel );
-      itkSetMacro( Step, TPixel );
-
+      itkSetMacro( Seed, TIndex );
+      itkSetMacro( Lower, TInputPixel );
+      itkSetMacro( Upper, TInputPixel );
+      itkSetMacro( Step, TInputPixel );
 
     protected:
-      MoriFilterHelper( );
-      virtual ~MoriFilterHelper( );
-
-      virtual bool _ContinueGenerateData( ) override;
-      virtual void _BeforeGenerateData( ) override;
-      virtual void _AfterGenerateData( ) override;
-      virtual void _BeforeLoop( ) override;
-      virtual void _AfterLoop( ) override;
-      virtual bool _UpdateValue( _TQueueNode& v, const _TQueueNode& p ) override;
-      virtual void _UpdateResult( const _TQueueNode& n ) override;
+      MoriFilterHelper( )
+        : Superclass( )
+        {
+        }
+      virtual ~MoriFilterHelper( )
+        {
+        }
+
+      /* TODO
+         virtual bool _ContinueGenerateData( ) override;
+         virtual void _BeforeGenerateData( ) override;
+         virtual void _AfterGenerateData( ) override;
+         virtual void _BeforeLoop( ) override;
+         virtual void _AfterLoop( ) override;
+         virtual bool _UpdateValue( _TQueueNode& v, const _TQueueNode& p ) override;
+         virtual bool _UpdateResult( _TQueueNode& n ) override;
+      */
 
     private:
       // Purposely not defined
@@ -67,12 +86,12 @@ namespace fpa
       Self& operator=( const Self& other );
 
     protected:
-      TPixel m_Lower;
-      TPixel m_Upper;
-      TPixel m_Step;
+      TIndex m_Seed;
+      TInputPixel m_Lower;
+      TInputPixel m_Upper;
+      TInputPixel m_Step;
       typename _TOutputImage::PixelType m_OptimumThreshold;
 
-      _TQueue m_NextQueue;
       unsigned long m_ActualCount;
       TCurve m_Curve;
     };
@@ -81,9 +100,11 @@ namespace fpa
 
 } // ecapseman
 
-#ifndef ITK_MANUAL_INSTANTIATION
-#  include <fpa/Image/MoriFilterHelper.hxx>
-#endif // ITK_MANUAL_INSTANTIATION
+/* TODO
+   #ifndef ITK_MANUAL_INSTANTIATION
+   #  include <fpa/Image/MoriFilterHelper.hxx>
+   #endif // ITK_MANUAL_INSTANTIATION
+*/
 
 #endif // __fpa__Image__MoriFilterHelper__h__
 
index 4ddb234232a1019a0396231e703fedfe94fcfeea..fb6826ad5e16de2ccaa08c1e5bf08236a72d8470 100644 (file)
@@ -32,11 +32,10 @@ _ContinueGenerateData( )
 {
   TBinThresholdFunction* functor =
     dynamic_cast< TBinThresholdFunction* >( this->GetGrowFunction( ) );
-  TPixel u = functor->GetUpper( );
 
   // Update flooding data
+  TPixel u = functor->GetUpper( );
   this->m_Curve.push_back( TCurveData( u, this->m_ActualCount ) );
-  std::cout << u << " " << this->m_ActualCount << std::endl;
 
   // Update thresholds
   if( u < this->m_Upper )
@@ -45,9 +44,30 @@ _ContinueGenerateData( )
     if( u > this->m_Upper )
       u = this->m_Upper;
     functor->SetUpper( u );
-    this->m_Queue = this->m_NextQueue;
+
+    while( this->m_Queue.size( ) > 0 )
+      this->m_Queue.pop( );
+    // TODO: std::cout << "-----> " << this->m_NextQueue.size( ) << " " << u << std::endl;
     while( this->m_NextQueue.size( ) > 0 )
+    {
+      this->m_Queue.push( this->m_NextQueue.front( ) );
+      // TODO: std::cout << "\t" << this->m_NextQueue.front( ).Vertex << std::endl;
       this->m_NextQueue.pop( );
+
+    } // elihw
+
+    /* TODO: ensure pixels belong to new threshold?
+       while( this->m_Queue.size( ) > 0 )
+       this->m_Queue.pop( );
+       while( this->m_NextQueue.size( ) > 0 )
+       {
+       _TQueueNode n = this->m_NextQueue.front( );
+       this->m_NextQueue.pop( );
+
+       if( ??? )
+       this->m_Queue.push( n );
+       }
+    */
     return( true );
   }
   else
@@ -122,22 +142,38 @@ template< class _TInputImage, class _TOutputImage >
 bool fpa::Image::MoriFilterHelper< _TInputImage, _TOutputImage >::
 _UpdateValue( _TQueueNode& v, const _TQueueNode& p )
 {
-  typedef typename _TOutputImage::PixelType _TOut;
-
-  bool ret = this->Superclass::_UpdateValue( v, p );
-  v.Result = _TOut( this->m_Curve.size( ) + 1 );
-  if( !ret )
-    this->m_NextQueue.push( v );
-  return( ret );
+  return( this->Superclass::_UpdateValue( v, p ) );
+  /* TODO
+     typedef typename _TOutputImage::PixelType _TOut;
+
+     bool ret = this->Superclass::_UpdateValue( v, p );
+     v.Result = _TOut( this->m_Curve.size( ) + 1 );
+     if( !ret )
+     this->m_NextQueue.push( v );
+     return( ret );
+  */
 }
 
 // -------------------------------------------------------------------------
 template< class _TInputImage, class _TOutputImage >
-void fpa::Image::MoriFilterHelper< _TInputImage, _TOutputImage >::
-_UpdateResult( const _TQueueNode& n )
+bool fpa::Image::MoriFilterHelper< _TInputImage, _TOutputImage >::
+_UpdateResult( _TQueueNode& n )
 {
-  this->Superclass::_UpdateResult( n );
-  this->m_ActualCount += 1;
+  typedef typename _TOutputImage::PixelType _TOut;
+
+  n.Result = _TOut( this->m_Curve.size( ) + 1 );
+  if( this->Superclass::_UpdateResult( n ) )
+  {
+    this->m_ActualCount += 1;
+    std::cout << this->m_ActualCount << std::endl;
+    return( true );
+  }
+  else
+  {
+    this->m_NextQueue.push( n );
+    return( false );
+
+  } // fi
 }
 
 #endif // __fpa__Image__MoriFilterHelper__hxx__