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