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