From cf298be2de026712c5ab3487978e3a6954a809cd Mon Sep 17 00:00:00 2001 From: =?utf8?q?Leonardo=20Fl=C3=B3rez-Valencia?= Date: Fri, 24 Feb 2017 17:23:45 -0500 Subject: [PATCH] ... --- examples/MoriRegionGrow_00.cxx | 14 +- lib/fpa/Base/Algorithm.h | 1 + lib/fpa/Base/Algorithm.hxx | 9 + lib/fpa/Image/MoriRegionGrow.h | 99 ++++----- lib/fpa/Image/MoriRegionGrow.hxx | 233 +++++++++++---------- lib/fpa/Image/MoriRegionGrowHelper.h | 92 ++++++++ lib/fpa/Image/MoriRegionGrowHelper.hxx | 144 +++++++++++++ plugins/CMakeLists.txt | 1 + plugins/ImageAlgorithms/ImageAlgorithms.i | 2 + plugins/ImageAlgorithms/MoriRegionGrow.cxx | 37 +++- plugins/ImageAlgorithms/MoriRegionGrow.h | 6 +- 11 files changed, 467 insertions(+), 171 deletions(-) create mode 100644 lib/fpa/Image/MoriRegionGrowHelper.h create mode 100644 lib/fpa/Image/MoriRegionGrowHelper.hxx diff --git a/examples/MoriRegionGrow_00.cxx b/examples/MoriRegionGrow_00.cxx index 1d7049c..45e7417 100644 --- a/examples/MoriRegionGrow_00.cxx +++ b/examples/MoriRegionGrow_00.cxx @@ -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 ); } diff --git a/lib/fpa/Base/Algorithm.h b/lib/fpa/Base/Algorithm.h index da7bee8..1a2394c 100644 --- a/lib/fpa/Base/Algorithm.h +++ b/lib/fpa/Base/Algorithm.h @@ -69,6 +69,7 @@ namespace fpa itkSetObjectMacro( NeighborhoodFunction, TNeighborhoodFunction ); public: + void ClearSeeds( ); void AddSeed( const TVertex& seed, const TOutput& value ); protected: diff --git a/lib/fpa/Base/Algorithm.hxx b/lib/fpa/Base/Algorithm.hxx index 30f42b7..df71336 100644 --- a/lib/fpa/Base/Algorithm.hxx +++ b/lib/fpa/Base/Algorithm.hxx @@ -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 >:: diff --git a/lib/fpa/Image/MoriRegionGrow.h b/lib/fpa/Image/MoriRegionGrow.h index 7a509ec..41c122e 100644 --- a/lib/fpa/Image/MoriRegionGrow.h +++ b/lib/fpa/Image/MoriRegionGrow.h @@ -1,8 +1,9 @@ #ifndef __fpa__Image__MoriRegionGrow__h__ #define __fpa__Image__MoriRegionGrow__h__ -#include -#include +#include +#include +#include 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 diff --git a/lib/fpa/Image/MoriRegionGrow.hxx b/lib/fpa/Image/MoriRegionGrow.hxx index 5c4efc1..737bf1f 100644 --- a/lib/fpa/Image/MoriRegionGrow.hxx +++ b/lib/fpa/Image/MoriRegionGrow.hxx @@ -2,152 +2,159 @@ #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 index 0000000..3810b87 --- /dev/null +++ b/lib/fpa/Image/MoriRegionGrowHelper.h @@ -0,0 +1,92 @@ +#ifndef __fpa__Image__MoriRegionGrowHelper__h__ +#define __fpa__Image__MoriRegionGrowHelper__h__ + +#include +#include +#include +#include + +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 +#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 index 0000000..9dc1df3 --- /dev/null +++ b/lib/fpa/Image/MoriRegionGrowHelper.hxx @@ -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$ diff --git a/plugins/CMakeLists.txt b/plugins/CMakeLists.txt index 8950a27..7305462 100644 --- a/plugins/CMakeLists.txt +++ b/plugins/CMakeLists.txt @@ -33,6 +33,7 @@ IF(USE_cpPlugins) ENDFOREACH(_d) TARGET_LINK_LIBRARIES( fpaPluginsImageAlgorithms + cpPlugins_ITKUnaryFunctorFilters fpaPluginsRegionGrowFunctors fpaPluginsDijkstraFunctors ) diff --git a/plugins/ImageAlgorithms/ImageAlgorithms.i b/plugins/ImageAlgorithms/ImageAlgorithms.i index 41cd37c..0dcdcec 100644 --- a/plugins/ImageAlgorithms/ImageAlgorithms.i +++ b/plugins/ImageAlgorithms/ImageAlgorithms.i @@ -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 diff --git a/plugins/ImageAlgorithms/MoriRegionGrow.cxx b/plugins/ImageAlgorithms/MoriRegionGrow.cxx index 4d23ecf..f8e323c 100644 --- a/plugins/ImageAlgorithms/MoriRegionGrow.cxx +++ b/plugins/ImageAlgorithms/MoriRegionGrow.cxx @@ -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$ diff --git a/plugins/ImageAlgorithms/MoriRegionGrow.h b/plugins/ImageAlgorithms/MoriRegionGrow.h index 653bd3d..f21c28b 100644 --- a/plugins/ImageAlgorithms/MoriRegionGrow.h +++ b/plugins/ImageAlgorithms/MoriRegionGrow.h @@ -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 > -- 2.45.0