]> Creatis software - FrontAlgorithms.git/commitdiff
...
authorLeonardo Flórez-Valencia <leonardo.florez@gmail.com>
Thu, 6 Jul 2017 04:03:15 +0000 (23:03 -0500)
committerLeonardo Flórez-Valencia <leonardo.florez@gmail.com>
Thu, 6 Jul 2017 04:03:15 +0000 (23:03 -0500)
data/input_mori_binary.png
lib/fpa/Base/Algorithm.h
lib/fpa/Base/Algorithm.hxx
lib/fpa/Base/Functors/RegionGrow/BinaryThreshold.h
lib/fpa/Base/Mori.h
lib/fpa/Base/Mori.hxx
lib/fpa/Base/RegionGrow.h
lib/fpa/Base/RegionGrow.hxx
lib/fpa/Image/Algorithm.hxx
lib/fpa/Image/Mori.h
tests/image/MoriSegmentation.cxx

index d6052476e0b2a2675e6f9b21be2f497f09e7e6d3..53ac575c9371575d65f706d9cd632e9080400bb5 100644 (file)
Binary files a/data/input_mori_binary.png and b/data/input_mori_binary.png differ
index 8750c5f7fb2360e2ac3afc44df84ec01d6414bb0..43f7a08c647fc9de4a77f37d21330d7e388aaf0e 100644 (file)
@@ -90,6 +90,7 @@ namespace fpa
       virtual void GenerateData( ) override;
       virtual void _BeforeGenerateData( );
       virtual void _AfterGenerateData( );
+      virtual void _FinishOneLoop( );
 
       virtual void _QueueInit( );
 
@@ -98,7 +99,7 @@ namespace fpa
       virtual TInputValue _GetInputValue( const TVertex& v ) const = 0;
       virtual TOutputValue _GetOutputValue( const TVertex& v ) const = 0;
 
-      virtual TOutputValue _ComputeOutputValue( const TNode& n ) = 0;
+      virtual bool _ComputeOutputValue( TNode& n ) = 0;
       virtual void _UpdateOutputValue( const TNode& n ) = 0;
       virtual void _QueueClear( ) = 0;
       virtual void _QueuePush( const TNode& node ) = 0;
index 44d2520da23e996f40197f7cf8484077100ee820..3a8b2d04aca27f44155f6112afc7575be1308bef 100644 (file)
@@ -167,9 +167,12 @@ GenerateData( )
             nnode.Vertex = *nIt;
             nnode.Parent = node.Vertex;
             nnode.FrontId = node.FrontId;
-            nnode.Value = this->_ComputeOutputValue( nnode );
-            this->_QueuePush( nnode );
-            this->InvokeEvent( TEvent( nnode.Vertex, nnode.FrontId, true ) );
+            if( this->_ComputeOutputValue( nnode ) )
+            {
+              this->_QueuePush( nnode );
+              this->InvokeEvent( TEvent( nnode.Vertex, nnode.FrontId, true ) );
+
+            } // fi
 
           } // fi
           ++nIt;
@@ -179,6 +182,7 @@ GenerateData( )
       } // fi
 
     } // fi
+    this->_FinishOneLoop( );
 
   } // elihw
 
@@ -201,6 +205,13 @@ _AfterGenerateData( )
 {
 }
 
+// -------------------------------------------------------------------------
+template< class _TFilter, class _TMarksInterface, class _TSeedsInterface >
+void fpa::Base::Algorithm< _TFilter, _TMarksInterface, _TSeedsInterface >::
+_FinishOneLoop( )
+{
+}
+
 // -------------------------------------------------------------------------
 template< class _TFilter, class _TMarksInterface, class _TSeedsInterface >
 void fpa::Base::Algorithm< _TFilter, _TMarksInterface, _TSeedsInterface >::
index ce533f69f14d979035a2cfe09b9f64378a556892..0ac4618e5bc237910ec919b20d7669e54fbb65e6 100644 (file)
@@ -36,21 +36,29 @@ namespace fpa
             itk::FunctionBase
             );
 
+          itkBooleanMacro( Strict );
+
           itkGetConstMacro( Lower, _TValue );
           itkGetConstMacro( Upper, _TValue );
+          itkGetConstMacro( Strict, bool );
 
           itkSetMacro( Lower, _TValue );
           itkSetMacro( Upper, _TValue );
+          itkSetMacro( Strict, bool );
 
         public:
           virtual bool Evaluate( const _TValue& input ) const override
             {
-              return( this->m_Lower < input && input < this->m_Upper );
+              if( this->m_Strict )
+                return( this->m_Lower < input && input < this->m_Upper );
+              else
+                return( this->m_Lower <= input && input <= this->m_Upper );
             }
 
         protected:
           BinaryThreshold( )
-            : Superclass( )
+            : Superclass( ),
+              m_Strict( true )
             {
               this->m_Upper = std::numeric_limits< _TValue >::max( );
               if( std::numeric_limits< _TValue >::is_integer )
@@ -71,6 +79,7 @@ namespace fpa
         protected:
           _TValue m_Lower;
           _TValue m_Upper;
+          bool m_Strict;
         };
 
       } // ecapseman
index d9277845fd365a80541769d891c7bbceda872aa0..6863278c7afe939f9c84c8af8538327bf86709f0 100644 (file)
@@ -8,6 +8,7 @@
 
 #include <deque>
 #include <set>
+#include <map>
 #include <itkConceptChecking.h>
 #include <itkFunctionBase.h>
 #include <fpa/Base/Functors/RegionGrow/BinaryThreshold.h>
@@ -37,6 +38,8 @@ namespace fpa
 
       typedef std::deque< TNode >     TQueue;
       typedef std::set< TInputValue > TThresholds;
+      typedef std::pair< TInputValue, unsigned long > TSignalData;
+      typedef std::map< TFrontId, TSignalData >       TSignal;
       typedef fpa::Base::Functors::RegionGrow::BinaryThreshold< TInputValue > TPredicate;
 
     public:
@@ -59,7 +62,7 @@ namespace fpa
       void SetThresholds(
         const TInputValue& init,
         const TInputValue& end,
-        unsigned long number_of_thresholds
+        const TInputValue& delta
         );
 
     protected:
@@ -68,7 +71,8 @@ namespace fpa
 
       virtual void _BeforeGenerateData( ) override;
       virtual void _AfterGenerateData( ) override;
-      virtual TOutputValue _ComputeOutputValue( const TNode& n ) override;
+      virtual void _FinishOneLoop( ) override;
+      virtual bool _ComputeOutputValue( TNode& n ) override;
       virtual void _QueueClear( ) override;
       virtual TNode _QueuePop( ) override;
       virtual void _QueuePush( const TNode& node ) override;
@@ -83,8 +87,11 @@ namespace fpa
     protected:
       typename TPredicate::Pointer m_Predicate;
       TThresholds m_Thresholds;
+      typename TThresholds::const_iterator m_CurrentThreshold;
       TQueue m_Queues[ 2 ];
       unsigned int m_CurrentQueue;
+      unsigned long m_Count;
+      TSignal m_Signal;
 
       TOutputValue m_InsideValue;
     };
index cff5fe8957e7128fb2e1c821d8b8396cfa8b845e..f0141448ef11996a484e35fe68201d0c6b8dcbb2 100644 (file)
@@ -57,15 +57,11 @@ void fpa::Base::Mori< _TAlgorithm >::
 SetThresholds(
   const TInputValue& init,
   const TInputValue& end,
-  unsigned long number_of_thresholds
+  const TInputValue& delta
   )
 {
-  double i = double( init );
-  double e = double( end );
-  double n = double( number_of_thresholds );
-  double d = ( e - i ) / n;
-  for( unsigned long c = 0; c <= number_of_thresholds; ++c )
-    this->AddThreshold( TInputValue( i + ( d * double( c ) ) ) );
+  for( TInputValue thr = init; thr <= end; thr += delta )
+    this->AddThreshold( thr );
 }
 
 // -------------------------------------------------------------------------
@@ -77,6 +73,7 @@ Mori( )
 {
   this->SetInitValue( TOutputValue( 0 ) );
   this->m_Predicate = TPredicate::New( );
+  this->m_Predicate->StrictOff( );
 }
 
 // -------------------------------------------------------------------------
@@ -95,6 +92,12 @@ _BeforeGenerateData( )
 
   this->_QueueClear( );
   this->m_CurrentQueue = 0;
+  this->m_CurrentThreshold = this->m_Thresholds.begin( );
+  this->m_Predicate->SetLower( *( this->m_CurrentThreshold ) );
+  this->m_CurrentThreshold++;
+  this->m_Predicate->SetUpper( *( this->m_CurrentThreshold ) );
+  this->m_Count = 0;
+  this->m_Signal.clear( );
 }
 
 // -------------------------------------------------------------------------
@@ -102,24 +105,57 @@ template< class _TAlgorithm >
 void fpa::Base::Mori< _TAlgorithm >::
 _AfterGenerateData( )
 {
+  // https://stackoverflow.com/questions/22583391/peak-signal-detection-in-realtime-timeseries-data
   this->Superclass::_AfterGenerateData( );
+
+  typename TSignal::const_iterator sIt = this->m_Signal.begin( );
+  for( ; sIt != this->m_Signal.end( ); ++sIt )
+  {
+    std::cout << int( sIt->first ) << " " << int( sIt->second.first ) << " " << sIt->second.second << std::endl;
+
+  } // rof
+  std::cerr << ( this->m_CurrentThreshold != this->m_Thresholds.end( ) ) << std::endl;
 }
 
 // -------------------------------------------------------------------------
 template< class _TAlgorithm >
-typename fpa::Base::Mori< _TAlgorithm >::
-TOutputValue fpa::Base::Mori< _TAlgorithm >::
-_ComputeOutputValue( const TNode& n )
+void fpa::Base::Mori< _TAlgorithm >::
+_FinishOneLoop( )
+{
+  if( this->m_Queues[ this->m_CurrentQueue ].size( ) == 0 )
+  {
+    this->m_Signal[ this->m_Signal.size( ) + 1 ] =
+      TSignalData( *this->m_CurrentThreshold, this->m_Count );
+    std::cerr << *( this->m_CurrentThreshold ) << std::endl;
+    this->m_CurrentThreshold++;
+    this->m_CurrentQueue = ( this->m_CurrentQueue + 1 ) % 2;
+    if( this->m_CurrentThreshold != this->m_Thresholds.end( ) )
+    {
+      this->m_Predicate->SetUpper( *( this->m_CurrentThreshold ) );
+      this->m_Count = 0;
+    }
+    else
+      this->_QueueClear( );
+
+  } // fi
+}
+
+// -------------------------------------------------------------------------
+template< class _TAlgorithm >
+bool fpa::Base::Mori< _TAlgorithm >::
+_ComputeOutputValue( TNode& n )
 {
   TInputValue value = this->_GetInputValue( n.Vertex );
   bool inside = this->m_Predicate->Evaluate( value );
+  n.Value = this->m_InsideValue;
   if( !inside )
   {
-    // TODO: Update new queue
-    return( this->m_InitValue );
+    n.FrontId++;
+    this->m_Queues[ ( this->m_CurrentQueue + 1 ) % 2 ].push_back( n );
   }
   else
-    return( this->m_InsideValue );
+    this->m_Count++;
+  return( inside );
 }
   
 // -------------------------------------------------------------------------
@@ -147,7 +183,6 @@ template< class _TAlgorithm >
 void fpa::Base::Mori< _TAlgorithm >::
 _QueuePush( const TNode& node )
 {
-  // TODO: Update mark
   this->m_Queues[ this->m_CurrentQueue ].push_back( node );
 }
 
@@ -169,14 +204,6 @@ _PrepareSeeds( TNodes& nodes )
     nIt->Value = this->m_InsideValue;
 }
 
-/* TODO
-   typename TPredicate::Pointer m_Predicate;
-   TThresholds m_Thresholds;
-   TQueue m_Queues[ 2 ];
-   unsigned int m_CurrentQueue;
-   TOutputValue m_InsideValue;
-*/
-
 #endif // __fpa__Base__Mori__hxx__
 
 // eof - $RCSfile$
index 34bb0851c589285c6837aaa55f1f7cac3134d3c7..28657d6614f371b971f969078993b886ac536dca 100644 (file)
@@ -63,7 +63,7 @@ namespace fpa
       RegionGrow( );
       virtual ~RegionGrow( );
 
-      virtual TOutputValue _ComputeOutputValue( const TNode& n ) override;
+      virtual bool _ComputeOutputValue( TNode& n ) override;
       virtual void _QueueClear( ) override;
       virtual TNode _QueuePop( ) override;
       virtual void _QueuePush( const TNode& node ) override;
index 247cf940ef4cbc1adf79d7453d58479f17c2603a..503222c1fc7d9ec6f6c770d7ba74dfd764f6f66a 100644 (file)
@@ -90,9 +90,8 @@ fpa::Base::RegionGrow< _TAlgorithm >::
 
 // -------------------------------------------------------------------------
 template< class _TAlgorithm >
-typename fpa::Base::RegionGrow< _TAlgorithm >::
-TOutputValue fpa::Base::RegionGrow< _TAlgorithm >::
-_ComputeOutputValue( const TNode& n )
+bool fpa::Base::RegionGrow< _TAlgorithm >::
+_ComputeOutputValue( TNode& n )
 {
   TInputValue value = this->_GetInputValue( n.Vertex );
   bool inside = false;
@@ -100,7 +99,8 @@ _ComputeOutputValue( const TNode& n )
     inside = this->m_ValuePredicate->Evaluate( value );
   if( this->m_VertexPredicate.IsNotNull( ) )
     inside &= this->m_VertexPredicate->Evaluate( n.Vertex );
-  return( ( inside )? this->m_InsideValue: this->m_InitValue );
+  n.Value = ( inside )? this->m_InsideValue: this->m_InitValue;
+  return( inside );
 }
 
 // -------------------------------------------------------------------------
index 9ac7548b55c2fbe729b2544f85795de31d541bb2..a94f13130a128e20cc7619aede6c215c88af6f64 100644 (file)
@@ -88,7 +88,7 @@ _UnifySeeds( )
     }
     else
       sIt->IsUnified = false;
-      
+
   } // rof
 
   return( nodes );
index 21c1748b87be65d4cd4eb2db62b83a34dc43f919..a81016ce6b53c4f5d86a699117970678e79a2268 100644 (file)
@@ -17,20 +17,20 @@ namespace fpa
   {
     /**
      */
-    template< class _TInputImage, class _TOutputImage, class _TFrontId = unsigned char >
+    template< class _TInputImage, class _TOutputImage >
     class Mori
-      : public fpa::Base::Mori< fpa::Image::Algorithm< _TInputImage, _TOutputImage, fpa::Base::MarksInterface< typename _TInputImage::IndexType >, fpa::Base::SingleSeedInterface< typename _TInputImage::IndexType, typename _TInputImage::PointType, typename _TInputImage::PixelType, typename _TOutputImage::PixelType, _TFrontId, typename _TInputImage::IndexType::LexicographicCompare > > >
+      : public fpa::Base::Mori< fpa::Image::Algorithm< _TInputImage, _TOutputImage, fpa::Base::MarksInterface< typename _TInputImage::IndexType >, fpa::Base::SingleSeedInterface< typename _TInputImage::IndexType, typename _TInputImage::PointType, typename _TInputImage::PixelType, typename _TOutputImage::PixelType, typename _TOutputImage::PixelType, typename _TInputImage::IndexType::LexicographicCompare > > >
     {
     public:
       typedef _TInputImage  TInputImage;
       typedef _TOutputImage TOutputImage;
-      typedef _TFrontId     TFrontId;
 
       typedef typename TInputImage::IndexType        TVertex;
       typedef typename TInputImage::PointType        TPoint;
       typedef typename TVertex::LexicographicCompare TVertexCompare;
       typedef typename TInputImage::PixelType        TInputValue;
       typedef typename TOutputImage::PixelType       TOutputValue;
+      typedef typename TOutputImage::PixelType       TFrontId;
 
       typedef fpa::Base::MarksInterface< TVertex > TMarksInterface;
       typedef fpa::Base::SingleSeedInterface< TVertex, TPoint, TInputValue, TOutputValue, TFrontId, TVertexCompare > TSeedsInterface;
index e02b359edc6231e1b6cfccc91671add0c3940988..d1b26f52bb6f2600fa073042426cc1bb53f7a224 100644 (file)
@@ -3,22 +3,24 @@
 #include <fpa/Image/Mori.h>
 
 // -------------------------------------------------------------------------
-const unsigned int Dim = 2;
-typedef unsigned char TPixel;
+const unsigned int Dim = 3;
+typedef short          TPixel;
+typedef unsigned short TLabel;
 
-typedef itk::Image< TPixel, Dim >          TImage;
-typedef fpa::Image::Mori< TImage, TImage > TFilter;
+typedef itk::Image< TPixel, Dim > TInputImage;
+typedef itk::Image< TLabel, Dim > TLabelImage;
+typedef fpa::Image::Mori< TInputImage, TLabelImage > TFilter;
 
 // -------------------------------------------------------------------------
 int main( int argc, char* argv[] )
 {
   // Get arguments
-  if( argc < 9 )
+  if( argc < 8 + Dim )
   {
     std::cerr
       << "Usage: " << argv[ 0 ]
       << " input_image output_image output_levels"
-      << " init_threshold end_threshold number_of_threshold seed_x seed_y"
+      << " init_threshold end_threshold delta [index/point] seed"
       << std::endl;
     return( 1 );
 
@@ -26,15 +28,24 @@ int main( int argc, char* argv[] )
   std::string input_image_filename = argv[ 1 ];
   std::string output_image_filename = argv[ 2 ];
   std::string output_levels_filename = argv[ 3 ];
-  unsigned char init_threshold = std::atoi( argv[ 4 ] );
-  unsigned char end_threshold = std::atoi( argv[ 5 ] );
-  unsigned char number_of_thresholds = std::atoi( argv[ 6 ] );
-  TImage::IndexType seed;
-  seed[ 0 ] = std::atoi( argv[ 7 ] );
-  seed[ 1 ] = std::atoi( argv[ 8 ] );
+  TPixel init_threshold = std::atoi( argv[ 4 ] );
+  TPixel end_threshold = std::atoi( argv[ 5 ] );
+  TPixel delta = std::atoi( argv[ 6 ] );
+  std::string seed_type = argv[ 7 ];
+
+  TInputImage::IndexType iseed;
+  TInputImage::PointType pseed;
+  for( unsigned int i = 0; i < Dim; ++i )
+  {
+    if( seed_type == "index" )
+      iseed[ i ] = std::atoi( argv[ 8 + i ] );
+    else
+      pseed[ i ] = std::atof( argv[ 8 + i ] );
+
+  } // rof
 
   // Create image
-  TImage::Pointer input_image;
+  TInputImage::Pointer input_image;
   std::string err0 =
     fpa::tests::image::Read( input_image, input_image_filename );
   if( err0 != "" ) std::cerr << err0 << std::endl;
@@ -42,8 +53,11 @@ int main( int argc, char* argv[] )
   // Prepare filter
   TFilter::Pointer filter = TFilter::New( );
   filter->SetInput( input_image );
-  filter->SetSeed( seed );
-  filter->SetThresholds( init_threshold, end_threshold, number_of_thresholds );
+  if( seed_type == "index" )
+    filter->SetSeed( iseed );
+  else
+    filter->SetSeed( pseed );
+  filter->SetThresholds( init_threshold, end_threshold, delta );
   filter->SetInsideValue( 255 );
   filter->SetOutsideValue( 0 );