+#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$