]> Creatis software - FrontAlgorithms.git/blobdiff - libs/fpa/Image/RegionGrow.hxx
...
[FrontAlgorithms.git] / libs / fpa / Image / RegionGrow.hxx
index 326dc5421ec9f3108f216f762ca1e5080c51cccc..0cf74deca72c5af32a8834e34fa38e525357b4a2 100644 (file)
@@ -1,11 +1,42 @@
+// =========================================================================
+// @author Leonardo Florez Valencia
+// @email florez-l@javeriana.edu.co
+// =========================================================================
+
 #ifndef __fpa__Image__RegionGrow__hxx__
 #define __fpa__Image__RegionGrow__hxx__
 
+#include <queue>
+
+// -------------------------------------------------------------------------
+template< class _TInputImage, class _TOutputImage >
+void fpa::Image::RegionGrow< _TInputImage, _TOutputImage >::
+SetPredicate( TIntensityFunctor* functor )
+{
+  if( this->m_IntensityFunctor.GetPointer( ) != functor )
+  {
+    this->m_IntensityFunctor = functor;
+    this->Modified( );
+
+  } // fi
+}
+
+// -------------------------------------------------------------------------
+template< class _TInputImage, class _TOutputImage >
+void fpa::Image::RegionGrow< _TInputImage, _TOutputImage >::
+AddSeed( const TIndex& seed )
+{
+  if( this->m_Seeds.insert( seed ).second )
+    this->Modified( );
+}
+
 // -------------------------------------------------------------------------
 template< class _TInputImage, class _TOutputImage >
 fpa::Image::RegionGrow< _TInputImage, _TOutputImage >::
 RegionGrow( )
-  : Superclass( )
+  : Superclass( ),
+    m_InsideValue( TInputPixel( 0 ) ),
+    m_OutsideValue( TInputPixel( 0 ) )
 {
 }
 
@@ -19,14 +50,91 @@ fpa::Image::RegionGrow< _TInputImage, _TOutputImage >::
 // -------------------------------------------------------------------------
 template< class _TInputImage, class _TOutputImage >
 void fpa::Image::RegionGrow< _TInputImage, _TOutputImage >::
-_BeforeGenerateData( )
+GenerateInputRequestedRegion( )
+{
+  this->Superclass::GenerateInputRequestedRegion( );
+  if( this->GetInput( ) )
+  {
+    TInputImage* input =
+      const_cast< TInputImage* >( this->GetInput( ) );
+    input->SetRequestedRegionToLargestPossibleRegion( );
+
+  } // fi
+}
+
+// -------------------------------------------------------------------------
+template< class _TInputImage, class _TOutputImage >
+void fpa::Image::RegionGrow< _TInputImage, _TOutputImage >::
+EnlargeOutputRequestedRegion( itk::DataObject* output )
+{
+  this->Superclass::EnlargeOutputRequestedRegion( output );
+  output->SetRequestedRegionToLargestPossibleRegion( );
+}
+
+// -------------------------------------------------------------------------
+template< class _TInputImage, class _TOutputImage >
+void fpa::Image::RegionGrow< _TInputImage, _TOutputImage >::
+GenerateData( )
 {
-  this->Superclass::_BeforeGenerateData( );
-  this->m_InitResult = this->GetOutsideValue( );
-  TGrowFunction* grow =
-    dynamic_cast< TGrowFunction* >( this->GetGrowFunction( ) );
-  if( grow != NULL )
-    grow->SetImage( this->GetInput( ) );
+  const TInputImage* input = this->GetInput( );
+  TOutputImage* output = this->GetOutput( );
+  TRegion region = input->GetRequestedRegion( );
+
+  // Configure output
+  output->SetBufferedRegion( region );
+  output->Allocate( );
+  output->FillBuffer( this->m_OutsideValue );
+
+  // Init marks
+  typedef itk::Image< bool, TInputImage::ImageDimension > _TMarks;
+  typename _TMarks::Pointer marks = _TMarks::New( );
+  marks->CopyInformation( input );
+  marks->SetRequestedRegion( region );
+  marks->SetBufferedRegion( input->GetBufferedRegion( ) );
+  marks->Allocate( );
+  marks->FillBuffer( false );
+
+  // Init queue
+  std::queue< TIndex > q;
+  for( TIndex seed: this->m_Seeds )
+    q.push( seed );
+
+  // Main loop
+  while( q.size( ) > 0 )
+  {
+    // Get next candidate
+    TIndex node = q.front( );
+    q.pop( );
+    if( marks->GetPixel( node ) )
+      continue;
+    marks->SetPixel( node, true );
+
+    // Apply inclusion predicate
+    TInputPixel value = input->GetPixel( node );
+    bool inside = false;
+    if( this->m_IntensityFunctor.IsNotNull( ) )
+      inside = this->m_IntensityFunctor->Evaluate( value );
+    if( !inside )
+      continue;
+
+    // Ok, pixel lays inside region
+    output->SetPixel( node, this->m_InsideValue );
+
+    // Add neighborhood
+    for( unsigned int d = 0; d < TInputImage::ImageDimension; ++d )
+    {
+      TIndex neigh = node;
+      for( int i = -1; i <= 1; i += 2 )
+      {
+        neigh[ d ] = node[ d ] + i;
+        if( region.IsInside( neigh ) )
+          q.push( neigh );
+
+      } // rof
+
+    } // rof
+
+  } // elihw
 }
 
 #endif // __fpa__Image__RegionGrow__hxx__