]> Creatis software - cpPlugins.git/blob - lib/cpPlugins/Plugins/BasicFilters/FloodFillImageFilter.cxx
Kind of bored: graph editor debugged
[cpPlugins.git] / lib / cpPlugins / Plugins / BasicFilters / FloodFillImageFilter.cxx
1 #include "FloodFillImageFilter.h"
2 #include <cpPlugins/Interface/Image.h>
3
4 #include <itkFloodFilledImageFunctionConditionalConstIterator.h>
5 #include <itkImageFunction.h>
6
7 // -------------------------------------------------------------------------
8 cpPlugins::BasicFilters::FloodFillImageFilter::
9 FloodFillImageFilter( )
10   : Superclass( )
11 {
12   this->_AddInput( "Input" );
13   this->_MakeOutput< cpPlugins::Interface::Image >( "Output" );
14
15   this->m_Parameters->ConfigureAsPoint( "Seed" );
16   this->m_Parameters->ConfigureAsReal( "Window" );
17   this->m_Parameters->ConfigureAsReal( "Level" );
18   this->m_Parameters->ConfigureAsUint( "InsideValue" );
19   this->m_Parameters->ConfigureAsUint( "OutsideValue" );
20
21   this->m_Parameters->SetReal( "Window", 0 );
22   this->m_Parameters->SetReal( "Level", 0 );
23   this->m_Parameters->SetUint( "InsideValue", 0 );
24   this->m_Parameters->SetUint( "OutsideValue", 255 );
25 }
26
27 // -------------------------------------------------------------------------
28 cpPlugins::BasicFilters::FloodFillImageFilter::
29 ~FloodFillImageFilter( )
30 {
31 }
32
33 // -------------------------------------------------------------------------
34 std::string cpPlugins::BasicFilters::FloodFillImageFilter::
35 _GenerateData( )
36 {
37   cpPlugins::Interface::Image* image =
38     this->GetInput< cpPlugins::Interface::Image >( "Input" );
39   if( image == NULL )
40     return( "FloodFillImageFilter: No input image." );
41
42   itk::DataObject* itk_image = NULL;
43   std::string r = "";
44   cpPlugins_Image_Demangle_AllScalarTypes( 2, image, itk_image, r, _GD0 );
45   else cpPlugins_Image_Demangle_AllScalarTypes( 3, image, itk_image, r, _GD0 );
46   else r = "FloodFillImageFilter: Input image type not supported.";
47   return( r );
48 }
49
50 // -------------------------------------------------------------------------
51 template< class I >
52 std::string cpPlugins::BasicFilters::FloodFillImageFilter::
53 _GD0( itk::DataObject* image )
54 {
55   return(
56     this->_RealGD< I, itk::Image< unsigned char, I::ImageDimension > >(
57       image
58       )
59     );
60 }
61
62 // -------------------------------------------------------------------------
63 template< class I, class R = float >
64 class cpPlugins_BasicFilters_FloodFillImageFilter_Function
65   : public itk::ImageFunction< I, bool, R >
66 {
67 public:
68   typedef cpPlugins_BasicFilters_FloodFillImageFilter_Function Self;
69   typedef itk::ImageFunction< I, bool, R >                     Superclass;
70   typedef itk::SmartPointer< Self >                            Pointer;
71   typedef itk::SmartPointer< const Self >                      ConstPointer;
72
73   typedef typename Superclass::PointType           TPoint;
74   typedef typename Superclass::IndexType           TIndex;
75   typedef typename Superclass::ContinuousIndexType TCIndex;
76
77 public:
78   itkNewMacro( Self );
79   itkTypeMacro(
80     cpPlugins_BasicFilters_FloodFillImageFilter_Function,
81     itkImageFunction
82     );
83
84   itkSetMacro( Window, double );
85   itkSetMacro( Level, double );
86
87 public:
88   virtual bool Evaluate( const TPoint& point ) const
89     {
90       return( true );
91     }
92   virtual bool EvaluateAtIndex( const TIndex& index ) const
93     {
94       if( !( this->IsInsideBuffer( index ) ) )
95         return( false );
96
97       const I* image = this->GetInputImage( );
98       double w2 = this->m_Window / double( 2 );
99       double min = this->m_Level - w2;
100       double max = this->m_Level + w2;
101       unsigned char val = double( 0 );
102       double x = double( image->GetPixel( index ) );
103       double m = double( 100 ) / this->m_Window;
104       double b = ( this->m_Window - ( double( 2 ) * this->m_Level ) );
105       b *= double( 50 ) / this->m_Window;
106       if( x > min && x < max )
107         val = ( unsigned char )( ( m * x ) + b );
108
109       if( this->m_Start )
110       {
111         this->m_StartValue = val;
112         this->m_Start = false;
113         return( true );
114       }
115       else
116         return( std::abs( this->m_StartValue - val ) <= 2 );
117     }
118   virtual bool EvaluateAtContinuousIndex( const TCIndex& index ) const
119     {
120       return( true );
121     }
122
123 protected:
124   cpPlugins_BasicFilters_FloodFillImageFilter_Function( )
125     : Superclass( ),
126       m_Window( double( 0 ) ),
127       m_Level( double( 0 ) ),
128       m_Start( true )
129     {
130     }
131   virtual ~cpPlugins_BasicFilters_FloodFillImageFilter_Function( )
132     {
133     }
134
135 private:
136   // Purposely not implemented
137   cpPlugins_BasicFilters_FloodFillImageFilter_Function( const Self& other );
138   Self& operator=( const Self& other );
139
140 protected:
141   double m_Window;
142   double m_Level;
143   mutable unsigned char m_StartValue;
144   mutable bool m_Start;
145 };
146
147 // -------------------------------------------------------------------------
148 template< class I, class O >
149 inline std::string cpPlugins::BasicFilters::FloodFillImageFilter::
150 _RealGD( itk::DataObject* image )
151 {
152   typedef typename O::PixelType _OP;
153   typedef cpPlugins_BasicFilters_FloodFillImageFilter_Function< I > _F;
154   typedef itk::FloodFilledImageFunctionConditionalConstIterator< I, _F > _It;
155
156   typename I::PointType pseed;
157   pseed = this->m_Parameters->GetPoint< typename I::PointType >(
158     "Seed", I::ImageDimension
159     );
160   double window = this->m_Parameters->GetReal( "Window" );
161   double level = this->m_Parameters->GetReal( "Level" );
162   _OP in_val = _OP( this->m_Parameters->GetUint( "InsideValue" ) );
163   _OP out_val = _OP( this->m_Parameters->GetUint( "OutsideValue" ) );
164
165   const I* in = dynamic_cast< const I* >( image );
166   typename I::IndexType seed;
167   in->TransformPhysicalPointToIndex( pseed, seed );
168
169   typename O::Pointer out = O::New( );
170   out->SetLargestPossibleRegion( in->GetLargestPossibleRegion( ) );
171   out->SetRequestedRegion( in->GetRequestedRegion( ) );
172   out->SetBufferedRegion( in->GetBufferedRegion( ) );
173   out->SetOrigin( in->GetOrigin( ) );
174   out->SetDirection( in->GetDirection( ) );
175   out->SetSpacing( in->GetSpacing( ) );
176   out->Allocate( );
177   out->FillBuffer( out_val );
178
179   typename _F::Pointer f = _F::New( );
180   f->SetInputImage( in );
181   f->SetWindow( window );
182   f->SetLevel( level );
183   _It i( in, f );
184   i.AddSeed( seed );
185
186   for( i.GoToBegin( ); !i.IsAtEnd( ); ++i )
187     out->SetPixel( i.GetIndex( ), in_val );
188
189   // Connect output
190   cpPlugins::Interface::Image* out_port =
191     this->GetOutput< cpPlugins::Interface::Image >( "Output" );
192   if( out_port != NULL )
193   {
194     out_port->SetITK< O >( out );
195     return( "" );
196   }
197   else
198     return( "FloodFillImageFilter: output not correctly created." );
199 }
200
201 // eof - $RCSfile$