#include "FloodFillImageFilter.h" #include #include #include // ------------------------------------------------------------------------- cpPlugins::BasicFilters::FloodFillImageFilter:: FloodFillImageFilter( ) : Superclass( ) { this->_AddInput( "Input" ); this->_MakeOutput< cpPlugins::Interface::Image >( "Output" ); double seed[ 3 ] = { double( 0 ) }; this->m_Parameters->ConfigureAsPoint( "Seed", 3, seed ); this->m_Parameters->ConfigureAsReal( "Window", 0 ); this->m_Parameters->ConfigureAsReal( "Level", 0 ); this->m_Parameters->ConfigureAsUint( "InsideValue", 0 ); this->m_Parameters->ConfigureAsUint( "OutsideValue", 255 ); } // ------------------------------------------------------------------------- cpPlugins::BasicFilters::FloodFillImageFilter:: ~FloodFillImageFilter( ) { } // ------------------------------------------------------------------------- std::string cpPlugins::BasicFilters::FloodFillImageFilter:: _GenerateData( ) { cpPlugins::Interface::Image* image = this->GetInput< cpPlugins::Interface::Image >( "Input" ); if( image == NULL ) return( "FloodFillImageFilter: No input image." ); itk::DataObject* itk_image = NULL; std::string r = ""; cpPlugins_Image_Demangle_AllScalarTypes( 2, image, itk_image, r, _GD0 ); else cpPlugins_Image_Demangle_AllScalarTypes( 3, image, itk_image, r, _GD0 ); else r = "FloodFillImageFilter: Input image type not supported."; return( r ); } // ------------------------------------------------------------------------- template< class I > std::string cpPlugins::BasicFilters::FloodFillImageFilter:: _GD0( itk::DataObject* image ) { return( this->_RealGD< I, itk::Image< unsigned char, I::ImageDimension > >( image ) ); } // ------------------------------------------------------------------------- template< class I, class R = float > class cpPlugins_BasicFilters_FloodFillImageFilter_Function : public itk::ImageFunction< I, bool, R > { public: typedef cpPlugins_BasicFilters_FloodFillImageFilter_Function Self; typedef itk::ImageFunction< I, bool, R > Superclass; typedef itk::SmartPointer< Self > Pointer; typedef itk::SmartPointer< const Self > ConstPointer; typedef typename Superclass::PointType TPoint; typedef typename Superclass::IndexType TIndex; typedef typename Superclass::ContinuousIndexType TCIndex; public: itkNewMacro( Self ); itkTypeMacro( cpPlugins_BasicFilters_FloodFillImageFilter_Function, itkImageFunction ); itkSetMacro( Window, double ); itkSetMacro( Level, double ); public: virtual bool Evaluate( const TPoint& point ) const { return( true ); } virtual bool EvaluateAtIndex( const TIndex& index ) const { if( !( this->IsInsideBuffer( index ) ) ) return( false ); const I* image = this->GetInputImage( ); double w2 = this->m_Window / double( 2 ); double min = this->m_Level - w2; double max = this->m_Level + w2; unsigned char val = double( 0 ); double x = double( image->GetPixel( index ) ); double m = double( 100 ) / this->m_Window; double b = ( this->m_Window - ( double( 2 ) * this->m_Level ) ); b *= double( 50 ) / this->m_Window; if( x > min && x < max ) val = ( unsigned char )( ( m * x ) + b ); if( this->m_Start ) { this->m_StartValue = val; this->m_Start = false; return( true ); } else return( std::abs( this->m_StartValue - val ) <= 2 ); } virtual bool EvaluateAtContinuousIndex( const TCIndex& index ) const { return( true ); } protected: cpPlugins_BasicFilters_FloodFillImageFilter_Function( ) : Superclass( ), m_Window( double( 0 ) ), m_Level( double( 0 ) ), m_Start( true ) { } virtual ~cpPlugins_BasicFilters_FloodFillImageFilter_Function( ) { } private: // Purposely not implemented cpPlugins_BasicFilters_FloodFillImageFilter_Function( const Self& other ); Self& operator=( const Self& other ); protected: double m_Window; double m_Level; mutable unsigned char m_StartValue; mutable bool m_Start; }; // ------------------------------------------------------------------------- template< class I, class O > inline std::string cpPlugins::BasicFilters::FloodFillImageFilter:: _RealGD( itk::DataObject* image ) { typedef typename O::PixelType _OP; typedef cpPlugins_BasicFilters_FloodFillImageFilter_Function< I > _F; typedef itk::FloodFilledImageFunctionConditionalConstIterator< I, _F > _It; typename I::PointType pseed; pseed = this->m_Parameters->GetPoint< typename I::PointType >( "Seed", I::ImageDimension ); double window = this->m_Parameters->GetReal( "Window" ); double level = this->m_Parameters->GetReal( "Level" ); _OP in_val = _OP( this->m_Parameters->GetUint( "InsideValue" ) ); _OP out_val = _OP( this->m_Parameters->GetUint( "OutsideValue" ) ); const I* in = dynamic_cast< const I* >( image ); typename I::IndexType seed; in->TransformPhysicalPointToIndex( pseed, seed ); typename O::Pointer out = O::New( ); out->SetLargestPossibleRegion( in->GetLargestPossibleRegion( ) ); out->SetRequestedRegion( in->GetRequestedRegion( ) ); out->SetBufferedRegion( in->GetBufferedRegion( ) ); out->SetOrigin( in->GetOrigin( ) ); out->SetDirection( in->GetDirection( ) ); out->SetSpacing( in->GetSpacing( ) ); out->Allocate( ); out->FillBuffer( out_val ); typename _F::Pointer f = _F::New( ); f->SetInputImage( in ); f->SetWindow( window ); f->SetLevel( level ); _It i( in, f ); i.AddSeed( seed ); for( i.GoToBegin( ); !i.IsAtEnd( ); ++i ) out->SetPixel( i.GetIndex( ), in_val ); // Connect output cpPlugins::Interface::Image* out_port = this->GetOutput< cpPlugins::Interface::Image >( "Output" ); if( out_port != NULL ) { out_port->SetITK< O >( out ); return( "" ); } else return( "FloodFillImageFilter: output not correctly created." ); } // eof - $RCSfile$