]> Creatis software - FrontAlgorithms.git/commitdiff
...
authorLeonardo Flórez-Valencia <florez-l@javeriana.edu.co>
Fri, 24 Feb 2017 22:23:45 +0000 (17:23 -0500)
committerLeonardo Flórez-Valencia <florez-l@javeriana.edu.co>
Fri, 24 Feb 2017 22:23:45 +0000 (17:23 -0500)
examples/MoriRegionGrow_00.cxx
lib/fpa/Base/Algorithm.h
lib/fpa/Base/Algorithm.hxx
lib/fpa/Image/MoriRegionGrow.h
lib/fpa/Image/MoriRegionGrow.hxx
lib/fpa/Image/MoriRegionGrowHelper.h [new file with mode: 0644]
lib/fpa/Image/MoriRegionGrowHelper.hxx [new file with mode: 0644]
plugins/CMakeLists.txt
plugins/ImageAlgorithms/ImageAlgorithms.i
plugins/ImageAlgorithms/MoriRegionGrow.cxx
plugins/ImageAlgorithms/MoriRegionGrow.h

index 1d7049c36745e9b66de3b0396e6001e89ced8f03..45e74179d421ef8ea800028b3f7137fe348d8a89 100644 (file)
@@ -8,6 +8,7 @@ typedef itk::Image< unsigned char, 2 >               TImage;
 typedef itk::ImageFileReader< TImage >               TReader;
 typedef itk::ImageFileWriter< TImage >               TWriter;
 typedef fpa::Image::MoriRegionGrow< TImage, TImage > TFilter;
+typedef itk::ImageFileWriter< TFilter::TAuxImage >   TAuxWriter;
 
 // -------------------------------------------------------------------------
 int main( int argc, char* argv[] )
@@ -16,13 +17,13 @@ int main( int argc, char* argv[] )
   {
     std::cerr
       << "Usage: " << argv[ 0 ]
-      << " input_filename output_filename sensitivity" << std::endl;
+      << " input_filename output_filename output_aux_filename" << std::endl;
     return( 1 );
 
   } // fi
   std::string in_fname = argv[ 1 ];
   std::string out_fname = argv[ 2 ];
-  double sensitivity = std::atof( argv[ 3 ] );
+  std::string out_aux_fname = argv[ 3 ];
   int seed_x = 111;
   int seed_y = 91;
 
@@ -40,14 +41,19 @@ int main( int argc, char* argv[] )
   filter->SetStep( 1 );
   filter->SetInsideValue( 255 );
   filter->SetOutsideValue( 0 );
-  filter->SetSensitivity( sensitivity );
-  filter->AddSeed( seed, filter->GetInsideValue( ) );
+  filter->SetSeed( seed );
 
   TWriter::Pointer writer = TWriter::New( );
   writer->SetInput( filter->GetOutput( ) );
   writer->SetFileName( out_fname );
   writer->Update( );
 
+  TAuxWriter::Pointer aux_writer = TAuxWriter::New( );
+  aux_writer->SetInput( filter->GetAuxiliaryImage( ) );
+  aux_writer->SetFileName( out_aux_fname );
+  aux_writer->Update( );
+  
+
   return( 0 );
 }
 
index da7bee89127774915bcf49311806763e35fe2ba0..1a2394c3e270ea3a931f3f5f3fec12ddaf1e6035 100644 (file)
@@ -69,6 +69,7 @@ namespace fpa
       itkSetObjectMacro( NeighborhoodFunction, TNeighborhoodFunction );
 
     public:
+      void ClearSeeds( );
       void AddSeed( const TVertex& seed, const TOutput& value );
 
     protected:
index 30f42b7008e29eb45cd98bcd17bfb78afc36da3e..df7133661849ac07a07e034a18e45bbaf94be743 100644 (file)
@@ -36,6 +36,15 @@ _TQueueNode( const _TVertex& v, const _TQueueNode& n )
   this->FrontId = n.FrontId;
 }
 
+// -------------------------------------------------------------------------
+template < class _TFilter, class _TVertex, class _TOutput >
+void fpa::Base::Algorithm< _TFilter, _TVertex, _TOutput >::
+ClearSeeds( )
+{
+  this->m_Seeds.clear( );
+  this->Modified( );
+}
+
 // -------------------------------------------------------------------------
 template < class _TFilter, class _TVertex, class _TOutput >
 void fpa::Base::Algorithm< _TFilter, _TVertex, _TOutput >::
index 7a509ec9ac9339fb27f1f44d52aef2cc247a4b52..41c122e32d9caf0c5d5cc89cdcb0e493ff23fb12 100644 (file)
@@ -1,8 +1,9 @@
 #ifndef __fpa__Image__MoriRegionGrow__h__
 #define __fpa__Image__MoriRegionGrow__h__
 
-#include <fpa/Image/RegionGrow.h>
-#include <fpa/Image/Functors/RegionGrow/BinaryThreshold.h>
+#include <itkImageToImageFilter.h>
+#include <itkBinaryThresholdImageFilter.h>
+#include <fpa/Image/MoriRegionGrowHelper.h>
 
 namespace fpa
 {
@@ -10,53 +11,64 @@ namespace fpa
   {
     /**
      */
-    template< class _TInputImage, class _TOutputImage >
+    template< class _TInputImage, class _TOutputImage, class _TAuxPixel = unsigned short >
     class MoriRegionGrow
-      : public fpa::Image::RegionGrow< _TInputImage, _TOutputImage >
+      : public itk::ImageToImageFilter< _TInputImage, _TOutputImage >
     {
     public:
-      typedef MoriRegionGrow                                        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
-      fpa::Image::Functors::RegionGrow::BinaryThreshold< _TInputImage >
-      TBinThresholdFunction;
-      typedef typename _TInputImage::PixelType TPixel;
+      typedef MoriRegionGrow                                         Self;
+      typedef itk::ImageToImageFilter< _TInputImage, _TOutputImage > Superclass;
+      typedef itk::SmartPointer< Self >                              Pointer;
+      typedef itk::SmartPointer< const Self >                        ConstPointer;
 
-    protected:
-      typedef typename Superclass::_TQueueNode _TQueueNode;
-      typedef typename Superclass::_TQueue     _TQueue;
+      typedef itk::Image< _TAuxPixel, _TInputImage::ImageDimension >      TAuxImage;
+      typedef fpa::Image::MoriRegionGrowHelper< _TInputImage, TAuxImage > THelper;
+      typedef itk::BinaryThresholdImageFilter< TAuxImage, _TOutputImage > TThreshold;
+
+      typedef typename _TInputImage::IndexType  TIndex;
+      typedef typename _TInputImage::PixelType  TInputPixel;
+      typedef typename _TOutputImage::PixelType TOutputPixel;
 
     public:
       itkNewMacro( Self );
-      itkTypeMacro( fpa::Image::MoriRegionGrow, fpa::Image::RegionGrow );
+      itkTypeMacro( fpa::Image::MoriRegionGrow, itk::ImageToImageFilter );
 
-      itkGetConstMacro( Lower, TPixel );
-      itkGetConstMacro( Upper, TPixel );
-      itkGetConstMacro( Step, TPixel );
-      itkGetConstMacro( Sensitivity, double );
+      itkGetConstMacro( Seed, TIndex );
+      itkSetMacro( Seed, TIndex );
 
-      itkSetMacro( Lower, TPixel );
-      itkSetMacro( Upper, TPixel );
-      itkSetMacro( Step, TPixel );
-      itkSetMacro( Sensitivity, double );
+    public:
+      TAuxImage* GetAuxiliaryImage( );
+      const TAuxImage* GetAuxiliaryImage( ) const;
+
+      TInputPixel GetLower( ) const;
+      TInputPixel GetUpper( ) const;
+      TInputPixel GetStep( ) const;
+      TOutputPixel GetInsideValue( ) const;
+      TOutputPixel GetOutsideValue( ) const;
+
+      void SetLower( const TInputPixel& v );
+      void SetUpper( const TInputPixel& v );
+      void SetStep( const TInputPixel& v );
+      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:
       MoriRegionGrow( );
       virtual ~MoriRegionGrow( );
 
-      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;
+      virtual void GenerateData( ) override;
 
     private:
       // Purposely not defined
@@ -64,20 +76,9 @@ namespace fpa
       Self& operator=( const Self& other );
 
     protected:
-      TPixel m_Lower;
-      TPixel m_Upper;
-      TPixel m_Step;
-      double m_Sensitivity;
-
-      _TQueue m_NextQueue;
-      unsigned long m_ActualCount;
-      unsigned long m_PrevCount;
-
-      // Standard deviation
-      double m_N;
-      double m_S1;
-      double m_S2;
-      double m_STD;
+      typename THelper::Pointer m_Helper;
+      typename TThreshold::Pointer m_Threshold;
+      TIndex m_Seed;
     };
 
   } // ecapseman
index 5c4efc1e921eb7879d37bdf575d083e983122f71..737bf1f79d15acb515c1d9fb6f94a2f959c80bb3 100644 (file)
 #define __fpa__Image__MoriRegionGrow__hxx__
 
 // -------------------------------------------------------------------------
-template< class _TInputImage, class _TOutputImage >
-fpa::Image::MoriRegionGrow< _TInputImage, _TOutputImage >::
-MoriRegionGrow( )
-  : Superclass( ),
-    m_Step( TPixel( 1 ) ),
-    m_Sensitivity( double( 1 ) )
+template< class _TInputImage, class _TOutputImage, class _TAuxPixel >
+typename
+fpa::Image::MoriRegionGrow< _TInputImage, _TOutputImage, _TAuxPixel >::
+TAuxImage*
+fpa::Image::MoriRegionGrow< _TInputImage, _TOutputImage, _TAuxPixel >::
+GetAuxiliaryImage( )
 {
-  this->m_Upper = std::numeric_limits< TPixel >::max( );
-  if( std::numeric_limits< TPixel >::is_integer )
-    this->m_Lower = std::numeric_limits< TPixel >::min( );
-  else
-    this->m_Lower = -this->m_Upper;
-  typename TBinThresholdFunction::Pointer functor =
-    TBinThresholdFunction::New( );
-  this->SetGrowFunction( functor );
+  return( this->m_Helper->GetOutput( ) );
 }
 
 // -------------------------------------------------------------------------
-template< class _TInputImage, class _TOutputImage >
-fpa::Image::MoriRegionGrow< _TInputImage, _TOutputImage >::
-~MoriRegionGrow( )
+template< class _TInputImage, class _TOutputImage, class _TAuxPixel >
+const typename
+fpa::Image::MoriRegionGrow< _TInputImage, _TOutputImage, _TAuxPixel >::
+TAuxImage*
+fpa::Image::MoriRegionGrow< _TInputImage, _TOutputImage, _TAuxPixel >::
+GetAuxiliaryImage( ) const
+{
+  return( this->m_Helper->GetOutput( ) );
+}
+
+// -------------------------------------------------------------------------
+template< class _TInputImage, class _TOutputImage, class _TAuxPixel >
+typename
+fpa::Image::MoriRegionGrow< _TInputImage, _TOutputImage, _TAuxPixel >::
+TInputPixel
+fpa::Image::MoriRegionGrow< _TInputImage, _TOutputImage, _TAuxPixel >::
+GetLower( ) const
+{
+  return( this->m_Helper->GetLower( ) );
+}
+
+// -------------------------------------------------------------------------
+template< class _TInputImage, class _TOutputImage, class _TAuxPixel >
+typename
+fpa::Image::MoriRegionGrow< _TInputImage, _TOutputImage, _TAuxPixel >::
+TInputPixel
+fpa::Image::MoriRegionGrow< _TInputImage, _TOutputImage, _TAuxPixel >::
+GetUpper( ) const
+{
+  return( this->m_Helper->GetUpper( ) );
+}
+
+// -------------------------------------------------------------------------
+template< class _TInputImage, class _TOutputImage, class _TAuxPixel >
+typename
+fpa::Image::MoriRegionGrow< _TInputImage, _TOutputImage, _TAuxPixel >::
+TInputPixel
+fpa::Image::MoriRegionGrow< _TInputImage, _TOutputImage, _TAuxPixel >::
+GetStep( ) const
 {
+  return( this->m_Helper->GetStep( ) );
 }
 
 // -------------------------------------------------------------------------
-template< class _TInputImage, class _TOutputImage >
-bool fpa::Image::MoriRegionGrow< _TInputImage, _TOutputImage >::
-_ContinueGenerateData( )
+template< class _TInputImage, class _TOutputImage, class _TAuxPixel >
+typename
+fpa::Image::MoriRegionGrow< _TInputImage, _TOutputImage, _TAuxPixel >::
+TOutputPixel
+fpa::Image::MoriRegionGrow< _TInputImage, _TOutputImage, _TAuxPixel >::
+GetInsideValue( ) const
 {
-  TBinThresholdFunction* functor =
-    dynamic_cast< TBinThresholdFunction* >( this->GetGrowFunction( ) );
-  TPixel u = functor->GetUpper( );
-
-  // Analyze flooding
-  bool stop = false;
-  if( this->m_N > double( 10 ) )
-  {
-    double Q = double( this->m_PrevCount );
-    Q += ( this->m_STD * this->m_Sensitivity );
-    if( double( this->m_ActualCount ) > Q )
-      stop = true;
-
-  } // fi
-  double v;
-  if( this->m_PrevCount > 0 )
-    v = double( this->m_ActualCount ) - double( this->m_PrevCount );
-  else
-    v = double( 0 );
-  this->m_PrevCount = this->m_ActualCount;
-  this->m_N += double( 1 );
-  this->m_S1 += v;
-  this->m_S2 += v * v;
-  if( this->m_N > double( 1 ) )
-    this->m_STD =
-      ( this->m_S2 - ( ( this->m_S1 * this->m_S1 ) / this->m_N ) ) /
-      ( this->m_N - double( 1 ) );
-  else
-    this->m_STD = double( 0 );
-  this->m_STD = std::sqrt( this->m_STD );
-
-  std::cout << u << " " << this->m_ActualCount << " " << this->m_STD << std::endl;
-
-  if( u < this->m_Upper )
-  {
-    u += this->m_Step;
-    if( u > this->m_Upper )
-      u = this->m_Upper;
-    functor->SetUpper( u );
-    this->m_Queue = this->m_NextQueue;
-    while( this->m_NextQueue.size( ) > 0 )
-      this->m_NextQueue.pop( );
-    return( !stop );
-  }
-  else
-    return( false );
+  return( this->m_Threshold->GetInsideValue( ) );
 }
 
 // -------------------------------------------------------------------------
-template< class _TInputImage, class _TOutputImage >
-void fpa::Image::MoriRegionGrow< _TInputImage, _TOutputImage >::
-_BeforeGenerateData( )
+template< class _TInputImage, class _TOutputImage, class _TAuxPixel >
+typename
+fpa::Image::MoriRegionGrow< _TInputImage, _TOutputImage, _TAuxPixel >::
+TOutputPixel
+fpa::Image::MoriRegionGrow< _TInputImage, _TOutputImage, _TAuxPixel >::
+GetOutsideValue( ) const
 {
-  this->Superclass::_BeforeGenerateData( );
-
-  while( this->m_NextQueue.size( ) > 0 )
-    this->m_NextQueue.pop( );
-  this->m_ActualCount = 0;
-  this->m_PrevCount = 0;
-  this->m_N   = double( 0 );
-  this->m_S1  = double( 0 );
-  this->m_S2  = double( 0 );
-  this->m_STD = double( 0 );
-  TBinThresholdFunction* functor =
-    dynamic_cast< TBinThresholdFunction* >( this->GetGrowFunction( ) );
-  functor->SetLower( this->m_Lower );
-  functor->SetUpper( this->m_Lower + this->m_Step );
+  return( this->m_Threshold->GetInsideValue( ) );
 }
 
 // -------------------------------------------------------------------------
-template< class _TInputImage, class _TOutputImage >
-void fpa::Image::MoriRegionGrow< _TInputImage, _TOutputImage >::
-_AfterGenerateData( )
+template< class _TInputImage, class _TOutputImage, class _TAuxPixel >
+void fpa::Image::MoriRegionGrow< _TInputImage, _TOutputImage, _TAuxPixel >::
+SetLower( const TInputPixel& v )
 {
-  this->Superclass::_AfterGenerateData( );
-  while( this->m_NextQueue.size( ) > 0 )
-    this->m_NextQueue.pop( );
+  this->m_Helper->SetLower( v );
+  this->Modified( );
 }
 
 // -------------------------------------------------------------------------
-template< class _TInputImage, class _TOutputImage >
-void fpa::Image::MoriRegionGrow< _TInputImage, _TOutputImage >::
-_BeforeLoop( )
+template< class _TInputImage, class _TOutputImage, class _TAuxPixel >
+void fpa::Image::MoriRegionGrow< _TInputImage, _TOutputImage, _TAuxPixel >::
+SetUpper( const TInputPixel& v )
 {
-  this->Superclass::_BeforeLoop( );
+  this->m_Helper->SetUpper( v );
+  this->Modified( );
 }
 
 // -------------------------------------------------------------------------
-template< class _TInputImage, class _TOutputImage >
-void fpa::Image::MoriRegionGrow< _TInputImage, _TOutputImage >::
-_AfterLoop( )
+template< class _TInputImage, class _TOutputImage, class _TAuxPixel >
+void fpa::Image::MoriRegionGrow< _TInputImage, _TOutputImage, _TAuxPixel >::
+SetStep( const TInputPixel& v )
 {
-  this->Superclass::_AfterLoop( );
+  this->m_Helper->SetStep( v );
+  this->Modified( );
 }
 
 // -------------------------------------------------------------------------
-template< class _TInputImage, class _TOutputImage >
-bool fpa::Image::MoriRegionGrow< _TInputImage, _TOutputImage >::
-_UpdateValue( _TQueueNode& v, const _TQueueNode& p )
+template< class _TInputImage, class _TOutputImage, class _TAuxPixel >
+void fpa::Image::MoriRegionGrow< _TInputImage, _TOutputImage, _TAuxPixel >::
+SetInsideValue( const TOutputPixel& v )
+{
+  this->m_Threshold->SetInsideValue( v );
+  this->Modified( );
+}
+
+// -------------------------------------------------------------------------
+template< class _TInputImage, class _TOutputImage, class _TAuxPixel >
+void fpa::Image::MoriRegionGrow< _TInputImage, _TOutputImage, _TAuxPixel >::
+SetOutsideValue( const TOutputPixel& v )
+{
+  this->m_Threshold->SetOutsideValue( v );
+  this->Modified( );
+}
+
+// -------------------------------------------------------------------------
+template< class _TInputImage, class _TOutputImage, class _TAuxPixel >
+fpa::Image::MoriRegionGrow< _TInputImage, _TOutputImage, _TAuxPixel >::
+MoriRegionGrow( )
+  : Superclass( )
+{
+  this->m_Helper = THelper::New( );
+  this->m_Threshold = TThreshold::New( );
+}
+
+// -------------------------------------------------------------------------
+template< class _TInputImage, class _TOutputImage, class _TAuxPixel >
+fpa::Image::MoriRegionGrow< _TInputImage, _TOutputImage, _TAuxPixel >::
+~MoriRegionGrow( )
 {
-  bool ret = this->Superclass::_UpdateValue( v, p );
-  if( !ret )
-  {
-    v.Result = this->m_InsideValue;
-    this->m_NextQueue.push( v );
-
-  } // fi
-  return( ret );
 }
 
 // -------------------------------------------------------------------------
-template< class _TInputImage, class _TOutputImage >
-void fpa::Image::MoriRegionGrow< _TInputImage, _TOutputImage >::
-_UpdateResult( const _TQueueNode& n )
+template< class _TInputImage, class _TOutputImage, class _TAuxPixel >
+void fpa::Image::MoriRegionGrow< _TInputImage, _TOutputImage, _TAuxPixel >::
+GenerateData( )
 {
-  this->Superclass::_UpdateResult( n );
-  this->m_ActualCount += 1;
+  this->m_Helper->ClearSeeds( );
+  this->m_Helper->AddSeed( this->m_Seed, 0 );
+  this->m_Helper->SetInput( this->GetInput( ) );
+  this->m_Helper->Update( );
+
+  this->m_Threshold->SetInput( this->m_Helper->GetOutput( ) );
+  this->m_Threshold->SetLowerThreshold( std::numeric_limits< _TAuxPixel >::min( ) );
+  this->m_Threshold->SetUpperThreshold( this->m_Helper->GetOptimumThreshold( ) );
+  this->m_Threshold->Update( );
+  this->GetOutput( )->Graft( this->m_Threshold->GetOutput( ) );
 }
 
 #endif // __fpa__Image__MoriRegionGrow__hxx__
diff --git a/lib/fpa/Image/MoriRegionGrowHelper.h b/lib/fpa/Image/MoriRegionGrowHelper.h
new file mode 100644 (file)
index 0000000..3810b87
--- /dev/null
@@ -0,0 +1,92 @@
+#ifndef __fpa__Image__MoriRegionGrowHelper__h__
+#define __fpa__Image__MoriRegionGrowHelper__h__
+
+#include <utility>
+#include <vector>
+#include <fpa/Image/RegionGrow.h>
+#include <fpa/Image/Functors/RegionGrow/BinaryThreshold.h>
+
+namespace fpa
+{
+  namespace Image
+  {
+    /**
+     */
+    template< class _TInputImage, class _TOutputImage >
+    class MoriRegionGrowHelper
+      : public fpa::Image::RegionGrow< _TInputImage, _TOutputImage >
+    {
+    public:
+      typedef MoriRegionGrowHelper                                        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
+      fpa::Image::Functors::RegionGrow::BinaryThreshold< _TInputImage >
+      TBinThresholdFunction;
+      typedef typename _TInputImage::PixelType TPixel;
+
+    protected:
+      typedef typename Superclass::_TQueueNode _TQueueNode;
+      typedef typename Superclass::_TQueue     _TQueue;
+
+      typedef std::pair< TPixel, unsigned long > TCurveData;
+      typedef std::vector< TCurveData >          TCurve;
+
+    public:
+      itkNewMacro( Self );
+      itkTypeMacro( fpa::Image::MoriRegionGrowHelper, fpa::Image::RegionGrow );
+
+      itkGetConstMacro( Lower, TPixel );
+      itkGetConstMacro( Upper, TPixel );
+      itkGetConstMacro( Step, TPixel );
+      itkGetConstMacro( OptimumThreshold, typename _TOutputImage::PixelType );
+
+      itkSetMacro( Lower, TPixel );
+      itkSetMacro( Upper, TPixel );
+      itkSetMacro( Step, TPixel );
+
+
+    protected:
+      MoriRegionGrowHelper( );
+      virtual ~MoriRegionGrowHelper( );
+
+      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;
+
+    private:
+      // Purposely not defined
+      MoriRegionGrowHelper( const Self& other );
+      Self& operator=( const Self& other );
+
+    protected:
+      TPixel m_Lower;
+      TPixel m_Upper;
+      TPixel m_Step;
+      typename _TOutputImage::PixelType m_OptimumThreshold;
+
+      _TQueue m_NextQueue;
+      unsigned long m_ActualCount;
+      TCurve m_Curve;
+    };
+
+  } // ecapseman
+
+} // ecapseman
+
+#ifndef ITK_MANUAL_INSTANTIATION
+#  include <fpa/Image/MoriRegionGrowHelper.hxx>
+#endif // ITK_MANUAL_INSTANTIATION
+
+#endif // __fpa__Image__MoriRegionGrowHelper__h__
+
+// eof - $RCSfile$
diff --git a/lib/fpa/Image/MoriRegionGrowHelper.hxx b/lib/fpa/Image/MoriRegionGrowHelper.hxx
new file mode 100644 (file)
index 0000000..9dc1df3
--- /dev/null
@@ -0,0 +1,144 @@
+#ifndef __fpa__Image__MoriRegionGrowHelper__hxx__
+#define __fpa__Image__MoriRegionGrowHelper__hxx__
+
+// -------------------------------------------------------------------------
+template< class _TInputImage, class _TOutputImage >
+fpa::Image::MoriRegionGrowHelper< _TInputImage, _TOutputImage >::
+MoriRegionGrowHelper( )
+  : Superclass( ),
+    m_Step( TPixel( 1 ) )
+{
+  this->m_Upper = std::numeric_limits< TPixel >::max( );
+  if( std::numeric_limits< TPixel >::is_integer )
+    this->m_Lower = std::numeric_limits< TPixel >::min( );
+  else
+    this->m_Lower = -this->m_Upper;
+  typename TBinThresholdFunction::Pointer functor =
+    TBinThresholdFunction::New( );
+  this->SetGrowFunction( functor );
+}
+
+// -------------------------------------------------------------------------
+template< class _TInputImage, class _TOutputImage >
+fpa::Image::MoriRegionGrowHelper< _TInputImage, _TOutputImage >::
+~MoriRegionGrowHelper( )
+{
+}
+
+// -------------------------------------------------------------------------
+template< class _TInputImage, class _TOutputImage >
+bool fpa::Image::MoriRegionGrowHelper< _TInputImage, _TOutputImage >::
+_ContinueGenerateData( )
+{
+  TBinThresholdFunction* functor =
+    dynamic_cast< TBinThresholdFunction* >( this->GetGrowFunction( ) );
+  TPixel u = functor->GetUpper( );
+
+  // Update flooding data
+  this->m_Curve.push_back( TCurveData( u, this->m_ActualCount ) );
+
+  // Update thresholds
+  if( u < this->m_Upper )
+  {
+    u += this->m_Step;
+    if( u > this->m_Upper )
+      u = this->m_Upper;
+    functor->SetUpper( u );
+    this->m_Queue = this->m_NextQueue;
+    while( this->m_NextQueue.size( ) > 0 )
+      this->m_NextQueue.pop( );
+    return( true );
+  }
+  else
+    return( false );
+}
+
+// -------------------------------------------------------------------------
+template< class _TInputImage, class _TOutputImage >
+void fpa::Image::MoriRegionGrowHelper< _TInputImage, _TOutputImage >::
+_BeforeGenerateData( )
+{
+  this->Superclass::_BeforeGenerateData( );
+
+  while( this->m_NextQueue.size( ) > 0 )
+    this->m_NextQueue.pop( );
+  this->m_OptimumThreshold = ( typename _TOutputImage::PixelType )( 0 );
+  this->m_ActualCount = 0;
+  this->m_Curve.clear( );
+  TBinThresholdFunction* functor =
+    dynamic_cast< TBinThresholdFunction* >( this->GetGrowFunction( ) );
+  functor->SetLower( this->m_Lower );
+  functor->SetUpper( this->m_Lower + this->m_Step );
+}
+
+// -------------------------------------------------------------------------
+template< class _TInputImage, class _TOutputImage >
+void fpa::Image::MoriRegionGrowHelper< _TInputImage, _TOutputImage >::
+_AfterGenerateData( )
+{
+  typedef typename _TOutputImage::PixelType _TOut;
+
+  this->Superclass::_AfterGenerateData( );
+  while( this->m_NextQueue.size( ) > 0 )
+    this->m_NextQueue.pop( );
+
+  // Find optimum threshold by dicotomy
+  unsigned long l = 0;
+  unsigned long r = this->m_Curve.size( ) - 1;
+  while( ( r - l ) > 1 )
+  {
+    unsigned long m = ( r + l ) >> 1;
+    double vm = double( this->m_Curve[ m ].second );
+    double dl = vm - double( this->m_Curve[ l ].second );
+    double dr = double( this->m_Curve[ r ].second ) - vm;
+    if( dl > dr )
+      r = m;
+    else
+      l = m;
+
+  } // elihw
+  this->m_OptimumThreshold = _TOut( ( r + l ) >> 1 );
+}
+
+// -------------------------------------------------------------------------
+template< class _TInputImage, class _TOutputImage >
+void fpa::Image::MoriRegionGrowHelper< _TInputImage, _TOutputImage >::
+_BeforeLoop( )
+{
+  this->Superclass::_BeforeLoop( );
+}
+
+// -------------------------------------------------------------------------
+template< class _TInputImage, class _TOutputImage >
+void fpa::Image::MoriRegionGrowHelper< _TInputImage, _TOutputImage >::
+_AfterLoop( )
+{
+  this->Superclass::_AfterLoop( );
+}
+
+// -------------------------------------------------------------------------
+template< class _TInputImage, class _TOutputImage >
+bool fpa::Image::MoriRegionGrowHelper< _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 );
+}
+
+// -------------------------------------------------------------------------
+template< class _TInputImage, class _TOutputImage >
+void fpa::Image::MoriRegionGrowHelper< _TInputImage, _TOutputImage >::
+_UpdateResult( const _TQueueNode& n )
+{
+  this->Superclass::_UpdateResult( n );
+  this->m_ActualCount += 1;
+}
+
+#endif // __fpa__Image__MoriRegionGrowHelper__hxx__
+
+// eof - $RCSfile$
index 8950a2730e1387c546a0795130c2aa8c61290baf..73054623147048f64a1597d4290246e6f40bf789 100644 (file)
@@ -33,6 +33,7 @@ IF(USE_cpPlugins)
   ENDFOREACH(_d)
   TARGET_LINK_LIBRARIES(
     fpaPluginsImageAlgorithms
+    cpPlugins_ITKUnaryFunctorFilters
     fpaPluginsRegionGrowFunctors
     fpaPluginsDijkstraFunctors
     )
index 41cd37cdf5cfca304f61db86595bd577ea4d669b..0dcdcecb966f6f003c80815babe0be6dc5dbdb4f 100644 (file)
@@ -6,8 +6,10 @@ instances fpa::Image::Functors::SimpleNeighborhood< itk::Image< #scalar_types#,
 cinclude fpa/Base/RegionGrow.hxx
 define all_int_types=#int_types#;#uint_types#
 tinclude fpa/Image/RegionGrow:h|hxx
+tinclude fpa/Image/MoriRegionGrowHelper:h|hxx
 tinclude fpa/Image/MoriRegionGrow:h|hxx
 instances fpa::Image::RegionGrow< itk::Image< #scalar_types#, #pdims# >, itk::Image< #all_int_types#, #pdims# > >
+instances fpa::Image::MoriRegionGrowHelper< itk::Image< #scalar_types#, #pdims# >, itk::Image< #all_int_types#, #pdims# > >
 instances fpa::Image::MoriRegionGrow< itk::Image< #scalar_types#, #pdims# >, itk::Image< #all_int_types#, #pdims# > >
 
 cinclude fpa/Base/Dijkstra.hxx
index 4d23ecfd51bec979e51729eebaf8547d9516eece..f8e323c1509b5b437d479af86af7559975f4ef9c 100644 (file)
@@ -9,13 +9,18 @@ MoriRegionGrow( )
   : Superclass( )
 {
   typedef cpPlugins::Pipeline::DataObject _TData;
+  typedef cpInstances::DataObjects::Image _TImage;
+
+  this->_ConfigureInput< _TImage >( "Input", true, false );
+  this->_ConfigureInput< _TData >( "Seed", true, false );
+  this->_ConfigureOutput< _TImage >( "Output" );
+  this->_ConfigureOutput< _TImage >( "AuxiliaryOutput" );
 
   this->m_Parameters.ConfigureAsInt( "InsideValue", 1 );
   this->m_Parameters.ConfigureAsInt( "OutsideValue", 0 );
   this->m_Parameters.ConfigureAsReal( "Step", 1 );
   this->m_Parameters.ConfigureAsReal( "Lower", 0 );
   this->m_Parameters.ConfigureAsReal( "Upper", 1 );
-  this->m_Parameters.ConfigureAsReal( "Sensitivity", 1 );
   this->m_Parameters.ConfigureAsIntTypesChoices( "ResultType" );
 }
 
@@ -62,15 +67,41 @@ _GD1( _TInputImage* image )
   typedef fpa::Image::MoriRegionGrow< _TInputImage, _TOutputImage > _TFilter;
 
   auto filter = this->_CreateITK< _TFilter >( );
-  this->_ConfigureFilter( filter, image );
+  filter->SetInput( image );
   filter->SetInsideValue( this->m_Parameters.GetInt( "InsideValue" ) );
   filter->SetOutsideValue( this->m_Parameters.GetInt( "OutsideValue" ) );
   filter->SetStep( this->m_Parameters.GetReal( "Step" ) );
   filter->SetLower( this->m_Parameters.GetReal( "Lower" ) );
   filter->SetUpper( this->m_Parameters.GetReal( "Upper" ) );
-  filter->SetSensitivity( this->m_Parameters.GetReal( "Sensitivity" ) );
+
+  // Assign seed
+  auto seeds = this->GetInputData< vtkPolyData >( "Seed" );
+  if( seeds != NULL )
+  {
+    typename _TInputImage::PointType pnt;
+    typename _TInputImage::IndexType idx;
+    unsigned int dim =
+      ( _TInputImage::ImageDimension < 3 )? _TInputImage::ImageDimension: 3;
+    if( seeds->GetNumberOfPoints( ) > 0 )
+    {
+      double buf[ 3 ];
+      seeds->GetPoint( 0, buf );
+      pnt.Fill( 0 );
+      for( unsigned int d = 0; d < dim; ++d )
+        pnt[ d ] = buf[ d ];
+
+      if( image->TransformPhysicalPointToIndex( pnt, idx ) )
+        filter->SetSeed( idx );
+    }
+    else
+      this->_Error( "No given seeds." );
+  }
+  else
+    this->_Error( "No given seeds." );
+
   filter->Update( );
   this->GetOutput( "Output" )->SetITK( filter->GetOutput( ) );
+  this->GetOutput( "AuxiliaryOutput" )->SetITK( filter->GetAuxiliaryImage( ) );
 }
 
 // eof - $RCSfile$
index 653bd3db7d253bb82f114fac48d81facbd9bf62b..f21c28bd256c0ad9d0d98bfdbb118d7a6caad02a 100644 (file)
@@ -8,9 +8,11 @@ namespace fpaPluginsImageAlgorithms
   /**
    */
   class fpaPluginsImageAlgorithms_EXPORT MoriRegionGrow
-    : public BaseFilter
+    : public cpPlugins::Pipeline::ProcessObject
   {
-    cpPluginsObject( MoriRegionGrow, BaseFilter, fpaImageAlgorithms );
+    cpPluginsObject(
+      MoriRegionGrow, cpPlugins::Pipeline::ProcessObject, fpaImageAlgorithms
+      );
 
   protected:
     template< class _TImage >