]> Creatis software - cpPlugins.git/blob - lib/cpPlugins/Plugins/BasicFilters/DoubleFloodImageFilter.cxx
Some bugs...
[cpPlugins.git] / lib / cpPlugins / Plugins / BasicFilters / DoubleFloodImageFilter.cxx
1 #include "DoubleFloodImageFilter.h"
2 #include <cpPlugins/Interface/Image.h>
3 #include <cpPlugins/Interface/BaseApplication.h>
4 #include <cpPlugins/Interface/Plugins.h>
5 #include <cpExtensions/Interaction/ImageInteractorStyle.h>
6 #include <cpExtensions/Visualization/ImageSliceActors.h>
7
8 #include <vtkRenderWindowInteractor.h>
9
10 #include <itkFloodFilledImageFunctionConditionalConstIterator.h>
11 #include <itkImageFunction.h>
12
13 #ifdef cpPlugins_Interface_QT4
14 #include <QDialogButtonBox>
15
16 // -------------------------------------------------------------------------
17 cpPlugins::BasicFilters::DoubleFloodImageFilter_Dialog::
18 DoubleFloodImageFilter_Dialog(
19   QWidget* parent, DoubleFloodImageFilter* filter, Qt::WindowFlags f
20   )
21   : QDialog( parent, f | Qt::WindowStaysOnTopHint ),
22     m_Filter( filter )
23 {
24   this->m_Title = new QLabel( this );
25   this->m_Title->setText( "Execute simple vessel segmentation filter" );
26
27   this->m_MainLayout = new QGridLayout( this );
28   this->m_ToolsLayout = new QVBoxLayout( );
29   this->m_ToolsLayout->addWidget( this->m_Title );
30   this->m_MainLayout->addLayout( this->m_ToolsLayout, 0, 0, 1, 1 );
31
32   // Add buttons
33   QDialogButtonBox* bb = new QDialogButtonBox(
34     QDialogButtonBox::Cancel | QDialogButtonBox::Ok
35     );
36   QObject::connect( bb, SIGNAL( accepted( ) ), this, SLOT( accept( ) ) );
37   QObject::connect( bb, SIGNAL( rejected( ) ), this, SLOT( reject( ) ) );
38   this->m_ToolsLayout->addWidget( bb );
39 }
40
41 // -------------------------------------------------------------------------
42 cpPlugins::BasicFilters::DoubleFloodImageFilter_Dialog::
43 ~DoubleFloodImageFilter_Dialog( )
44 {
45   delete this->m_Title;
46   delete this->m_ToolsLayout;
47   delete this->m_MainLayout;
48 }
49
50 // -------------------------------------------------------------------------
51 void cpPlugins::BasicFilters::DoubleFloodImageFilter_Dialog::
52 accept( )
53 {
54   // Get interactive widget
55   if( this->m_Filter == NULL )
56     return;
57
58   typedef cpExtensions::Interaction::ImageInteractorStyle _TImageStyle;
59   typedef cpExtensions::Visualization::ImageSliceActors   _TImageActors;
60
61   // Get seeds
62   unsigned int nTotalSeeds = 0;
63   auto iIt = this->m_Filter->m_Interactors.begin( );
64   for( ; iIt != this->m_Filter->m_Interactors.end( ); ++iIt )
65   {
66     _TImageStyle* istyle =
67       dynamic_cast< _TImageStyle* >(
68         ( *iIt )->GetInteractorStyle( )
69         );
70     if( istyle == NULL )
71       continue;
72
73     // Get window level
74     _TImageActors* actors =
75       dynamic_cast< _TImageActors* >( istyle->GetAssociatedObject( ) );
76     if( actors != NULL )
77     {
78       this->m_Filter->GetParameters( )->SetReal( "Window", actors->GetWindow( ) );
79       this->m_Filter->GetParameters( )->SetReal( "Level", actors->GetLevel( ) );
80
81     } // fi
82
83     unsigned int nSeeds = istyle->GetNumberOfSeeds( );
84     for( unsigned int s = 0; s < nSeeds; ++s )
85     {
86       if( nTotalSeeds < 2 )
87       {
88         double seed[ 3 ];
89         istyle->GetSeed( s, seed );
90         if( nTotalSeeds == 0 )
91           this->m_Filter->GetParameters( )->SetPoint( "Seed0", 3, seed );
92         else
93           this->m_Filter->GetParameters( )->SetPoint( "Seed1", 3, seed );
94
95       } // fi
96       nTotalSeeds++;
97
98     } // rof
99
100   } // rof
101
102   // Update filter
103   auto plugins = this->m_Filter->GetPlugins( );
104   if( plugins != NULL )
105   {
106     auto app = plugins->GetApplication( );
107     if( app != NULL )
108       app->UpdateActualFilter( );
109
110   } // fi
111 }
112
113 // -------------------------------------------------------------------------
114 void cpPlugins::BasicFilters::DoubleFloodImageFilter_Dialog::
115 reject( )
116 {
117   auto plugins = this->m_Filter->GetPlugins( );
118   if( plugins != NULL )
119     plugins->DeactivateFilter( );
120   this->Superclass::reject( );
121 }
122
123 #endif // cpPlugins_Interface_QT4
124
125 // -------------------------------------------------------------------------
126 cpPlugins::BasicFilters::DoubleFloodImageFilter::
127 DialogResult cpPlugins::BasicFilters::DoubleFloodImageFilter::
128 ExecConfigurationDialog( QWidget* parent )
129 {
130 #ifdef cpPlugins_Interface_QT4
131
132   typedef cpExtensions::Interaction::ImageInteractorStyle _TImageStyle;
133
134   // Activate seed widgets
135   bool at_least_one = false;
136   auto iIt = this->m_Interactors.begin( );
137   for( ; iIt != this->m_Interactors.end( ); ++iIt )
138   {
139     _TImageStyle* istyle =
140       dynamic_cast< _TImageStyle* >(
141         ( *iIt )->GetInteractorStyle( )
142         );
143     if( istyle != NULL )
144     {
145       istyle->SeedWidgetOn( );
146       at_least_one = true;
147
148     } // fi
149     
150   } // rof
151   if( !at_least_one )
152     return( Self::DialogResult_Cancel );
153
154   // Create dialog
155   this->m_Dialog = new DoubleFloodImageFilter_Dialog( NULL, this );
156   this->m_Dialog->show( );
157
158   return( Self::DialogResult_Modal );
159 #else // cpPlugins_Interface_QT4
160   return( Self::DialogResult_Cancel );
161 #endif // cpPlugins_Interface_QT4
162 }
163
164 // -------------------------------------------------------------------------
165 cpPlugins::BasicFilters::DoubleFloodImageFilter::
166 DoubleFloodImageFilter( )
167   : Superclass( )
168 {
169   this->_AddInput( "Input" );
170   this->_MakeOutput< cpPlugins::Interface::Image >( "Output" );
171
172   double seed[ 3 ] = { double( 0 ) };
173   this->m_Parameters->ConfigureAsPoint( "Seed0", 3, seed );
174   this->m_Parameters->ConfigureAsPoint( "Seed1", 3, seed );
175   this->m_Parameters->ConfigureAsReal( "Window", 0 );
176   this->m_Parameters->ConfigureAsReal( "Level", 0 );
177   this->m_Parameters->ConfigureAsUint( "InsideValue", 255 );
178   this->m_Parameters->ConfigureAsUint( "OutsideValue", 0 );
179 }
180
181 // -------------------------------------------------------------------------
182 cpPlugins::BasicFilters::DoubleFloodImageFilter::
183 ~DoubleFloodImageFilter( )
184 {
185 }
186
187 // -------------------------------------------------------------------------
188 std::string cpPlugins::BasicFilters::DoubleFloodImageFilter::
189 _GenerateData( )
190 {
191   cpPlugins::Interface::Image* image =
192     this->GetInput< cpPlugins::Interface::Image >( "Input" );
193   if( image == NULL )
194     return( "DoubleFloodImageFilter: No input image." );
195
196   itk::DataObject* itk_image = NULL;
197   std::string r = "";
198   cpPlugins_Image_Demangle_AllScalarTypes( 2, image, itk_image, r, _GD0 );
199   else cpPlugins_Image_Demangle_AllScalarTypes( 3, image, itk_image, r, _GD0 );
200   else r = "DoubleFloodImageFilter: Input image type not supported.";
201   return( r );
202 }
203
204 // -------------------------------------------------------------------------
205 template< class I >
206 std::string cpPlugins::BasicFilters::DoubleFloodImageFilter::
207 _GD0( itk::DataObject* image )
208 {
209   return(
210     this->_RealGD< I, itk::Image< unsigned char, I::ImageDimension > >(
211       image
212       )
213     );
214 }
215
216 // -------------------------------------------------------------------------
217 template< class I, class R = float >
218 class cpPlugins_BasicFilters_DoubleFloodImageFilter_Function
219   : public itk::ImageFunction< I, bool, R >
220 {
221 public:
222   typedef cpPlugins_BasicFilters_DoubleFloodImageFilter_Function Self;
223   typedef itk::ImageFunction< I, bool, R >                     Superclass;
224   typedef itk::SmartPointer< Self >                            Pointer;
225   typedef itk::SmartPointer< const Self >                      ConstPointer;
226
227   typedef typename Superclass::PointType           TPoint;
228   typedef typename Superclass::IndexType           TIndex;
229   typedef typename Superclass::ContinuousIndexType TCIndex;
230
231 public:
232   itkNewMacro( Self );
233   itkTypeMacro(
234     cpPlugins_BasicFilters_DoubleFloodImageFilter_Function,
235     itkImageFunction
236     );
237
238   itkSetMacro( Window, double );
239   itkSetMacro( Level, double );
240
241 public:
242   virtual bool Evaluate( const TPoint& point ) const
243     {
244       return( true );
245     }
246   virtual bool EvaluateAtIndex( const TIndex& index ) const
247     {
248       if( !( this->IsInsideBuffer( index ) ) )
249         return( false );
250
251       const I* image = this->GetInputImage( );
252       double w2 = this->m_Window / double( 2 );
253       double min = this->m_Level - w2;
254       double max = this->m_Level + w2;
255       unsigned char val = double( 0 );
256       double x = double( image->GetPixel( index ) );
257       double m = double( 100 ) / this->m_Window;
258       double b = ( this->m_Window - ( double( 2 ) * this->m_Level ) );
259       b *= double( 50 ) / this->m_Window;
260       if( x > min && x < max )
261         val = ( unsigned char )( ( m * x ) + b );
262
263       if( this->m_Start )
264       {
265         this->m_StartValue = val;
266         this->m_Start = false;
267         return( true );
268       }
269       else
270         return( std::abs( this->m_StartValue - val ) <= 2 );
271     }
272   virtual bool EvaluateAtContinuousIndex( const TCIndex& index ) const
273     {
274       return( true );
275     }
276
277 protected:
278   cpPlugins_BasicFilters_DoubleFloodImageFilter_Function( )
279     : Superclass( ),
280       m_Window( double( 0 ) ),
281       m_Level( double( 0 ) ),
282       m_Start( true )
283     {
284     }
285   virtual ~cpPlugins_BasicFilters_DoubleFloodImageFilter_Function( )
286     {
287     }
288
289 private:
290   // Purposely not implemented
291   cpPlugins_BasicFilters_DoubleFloodImageFilter_Function( const Self& other );
292   Self& operator=( const Self& other );
293
294 protected:
295   double m_Window;
296   double m_Level;
297   mutable unsigned char m_StartValue;
298   mutable bool m_Start;
299 };
300
301 // -------------------------------------------------------------------------
302 template< class I, class O >
303 inline std::string cpPlugins::BasicFilters::DoubleFloodImageFilter::
304 _RealGD( itk::DataObject* image )
305 {
306   typedef typename O::PixelType _OP;
307   typedef cpPlugins_BasicFilters_DoubleFloodImageFilter_Function< I > _F;
308   typedef itk::FloodFilledImageFunctionConditionalConstIterator< I, _F > _It;
309
310   typename I::PointType pseed0, pseed1;
311   pseed0 = this->m_Parameters->GetPoint< typename I::PointType >(
312     "Seed0", I::ImageDimension
313     );
314   pseed1 = this->m_Parameters->GetPoint< typename I::PointType >(
315     "Seed1", I::ImageDimension
316     );
317   double window = this->m_Parameters->GetReal( "Window" );
318   double level = this->m_Parameters->GetReal( "Level" );
319   _OP in_val = _OP( this->m_Parameters->GetUint( "InsideValue" ) );
320   _OP out_val = _OP( this->m_Parameters->GetUint( "OutsideValue" ) );
321
322   const I* in = dynamic_cast< const I* >( image );
323   typename I::IndexType seed0, seed1;
324   in->TransformPhysicalPointToIndex( pseed0, seed0 );
325   in->TransformPhysicalPointToIndex( pseed1, seed1 );
326
327   typename O::Pointer out = O::New( );
328   out->SetLargestPossibleRegion( in->GetLargestPossibleRegion( ) );
329   out->SetRequestedRegion( in->GetRequestedRegion( ) );
330   out->SetBufferedRegion( in->GetBufferedRegion( ) );
331   out->SetOrigin( in->GetOrigin( ) );
332   out->SetDirection( in->GetDirection( ) );
333   out->SetSpacing( in->GetSpacing( ) );
334   out->Allocate( );
335   out->FillBuffer( out_val );
336
337   typename _F::Pointer f = _F::New( );
338   f->SetInputImage( in );
339   f->SetWindow( window );
340   f->SetLevel( level );
341   _It i( in, f );
342   i.AddSeed( seed0 );
343   i.AddSeed( seed1 );
344
345   for( i.GoToBegin( ); !i.IsAtEnd( ); ++i )
346     out->SetPixel( i.GetIndex( ), in_val );
347
348   // Connect output
349   cpPlugins::Interface::Image* out_port =
350     this->GetOutput< cpPlugins::Interface::Image >( "Output" );
351   if( out_port != NULL )
352   {
353     out_port->SetITK< O >( out );
354     return( "" );
355   }
356   else
357     return( "DoubleFloodImageFilter: output not correctly created." );
358 }
359
360 // eof - $RCSfile$