]> Creatis software - clitk.git/blob - segmentation/clitkMorphoMathFilter.txx
changes in license header
[clitk.git] / segmentation / clitkMorphoMathFilter.txx
1 /*=========================================================================
2   Program:   vv                     http://www.creatis.insa-lyon.fr/rio/vv
3
4   Authors belong to: 
5   - University of LYON              http://www.universite-lyon.fr/
6   - Léon Bérard cancer center       http://www.centreleonberard.fr
7   - CREATIS CNRS laboratory         http://www.creatis.insa-lyon.fr
8
9   This software is distributed WITHOUT ANY WARRANTY; without even
10   the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
11   PURPOSE.  See the copyright notices for more information.
12
13   It is distributed under dual licence
14
15   - BSD        See included LICENSE.txt file
16   - CeCILL-B   http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html
17   ===========================================================================**/
18
19 //--------------------------------------------------------------------
20 template<class ImageType>
21 clitk::MorphoMathFilter<ImageType>::MorphoMathFilter():
22   clitk::FilterBase(),
23   itk::ImageToImageFilter<ImageType, ImageType>()
24 {
25   this->SetNumberOfRequiredInputs(1);
26   SetBackgroundValue(0);
27   SetForegroundValue(1);
28   SetOperationType(0);
29   SizeType p;
30   p.Fill(1);
31   SetRadius(p);
32   SetBoundaryToForegroundFlag(false);
33 }
34 //--------------------------------------------------------------------
35
36
37 //--------------------------------------------------------------------
38 template<class ImageType>
39 clitk::MorphoMathFilter<ImageType>::~MorphoMathFilter()
40 {
41   // Nothing
42 }
43 //--------------------------------------------------------------------
44
45
46 //--------------------------------------------------------------------
47 template<class ImageType>
48 void clitk::MorphoMathFilter<ImageType>::
49 SetRadiusInMM(PointType & p)
50 {
51   m_RadiusInMM = p;
52   m_RadiusInMMIsSet = true;
53   m_RadiusIsSet = false;
54 }
55 //--------------------------------------------------------------------
56
57
58 //--------------------------------------------------------------------
59 template<class ImageType>
60 void clitk::MorphoMathFilter<ImageType>::
61 SetRadius(SizeType & p)
62 {
63   m_Radius = p;
64   m_RadiusIsSet = true;
65   m_RadiusInMMIsSet = false;
66 }
67 //--------------------------------------------------------------------
68
69
70 //--------------------------------------------------------------------
71 template<class ImageType>
72 void clitk::MorphoMathFilter<ImageType>::
73 SetOperationType(int type)
74 {
75   switch (type) {
76   case 0: m_OperationType = Erode; return;
77   case 1: m_OperationType = Dilate; return;
78   case 2: m_OperationType = Open; return;
79   case 3: m_OperationType = Close; return;
80   case 4: m_OperationType = CondErode; return;
81   case 5: m_OperationType = CondDilate; return;
82   default: clitkExceptionMacro("Operation type must be between 0-5 (0=Erode, 1=Dilate, 2=Close (erode(dilate(x))), 3=Open (dilate(erode(x))), 4=CondErode, 5=CondDilate)");
83   }    
84 }
85 //--------------------------------------------------------------------
86
87
88 //--------------------------------------------------------------------
89 template <class ImageType>
90 void 
91 clitk::MorphoMathFilter<ImageType>::
92 GenerateInputRequestedRegion() 
93 {
94   // Call default
95   itk::ImageToImageFilter<ImageType, ImageType>::GenerateInputRequestedRegion();
96   // Get input pointers and set requested region to common region
97   ImagePointer input1 = dynamic_cast<ImageType*>(itk::ProcessObject::GetInput(0));
98   input1->SetRequestedRegion(input1->GetLargestPossibleRegion());
99 }
100 //--------------------------------------------------------------------
101
102
103 //--------------------------------------------------------------------
104 template <class ImageType>
105 void 
106 clitk::MorphoMathFilter<ImageType>::
107 GenerateOutputInformation() 
108 {
109   //---------------------------------
110   // Define the images
111   //---------------------------------
112   ImagePointer m_input = dynamic_cast<ImageType*>(itk::ProcessObject::GetInput(0));
113
114   //---------------------------------
115   // Cast into internalimagetype
116   //---------------------------------
117   typedef itk::CastImageFilter<ImageType, InternalImageType> InputCastImageFilterType;
118   typename InputCastImageFilterType::Pointer caster = InputCastImageFilterType::New();
119   caster->SetInput(m_input);
120   caster->Update();
121   input =caster->GetOutput();
122   
123   //---------------------------------
124   // Compute the radius in pixel
125   //---------------------------------
126   if (m_RadiusInMMIsSet) {
127     for(uint i=0; i<ImageType::ImageDimension; i++) {
128       m_Radius[i] = (uint)lrint(m_RadiusInMM[i]/input->GetSpacing()[i]);
129     }
130   }
131
132   //---------------------------------
133   // Extend the image if needed
134   //---------------------------------
135   if (GetExtendSupportFlag()) {
136     typedef itk::ConstantPadImageFilter<InternalImageType, InternalImageType> PadFilterType;
137     typename PadFilterType::Pointer padFilter = PadFilterType::New();
138     padFilter->SetInput(input);
139     typename ImageType::SizeType lower;
140     typename ImageType::SizeType upper;
141     for(uint i=0; i<3; i++) {
142       lower[i] = upper[i] = 2*(m_Radius[i]+1);
143     }
144     padFilter->SetPadLowerBound(lower);
145     padFilter->SetPadUpperBound(upper);
146     padFilter->Update();
147     if (GetVerboseFlag()) std::cout << "Extend the image to 2x " << lower << std::endl;
148     input = padFilter->GetOutput();
149   }
150   
151   // Set output size
152   ImagePointer outputImage = this->GetOutput(0);
153   outputImage->SetRegions(input->GetLargestPossibleRegion());
154 }
155 //--------------------------------------------------------------------
156
157
158 //--------------------------------------------------------------------
159 template <class ImageType>
160 void 
161 clitk::MorphoMathFilter<ImageType>::
162 GenerateData() 
163 {
164   //---------------------------------
165   // Build kernel
166   //---------------------------------
167   typedef itk::BinaryBallStructuringElement<PixelType,ImageDimension> KernelType;
168   KernelType structuringElement;
169   if (GetVerboseFlag()) {
170     std::cout << "Radius in pixel : " << m_Radius << std::endl;
171   }
172   structuringElement.SetRadius(m_Radius);
173   structuringElement.CreateStructuringElement();
174
175   //---------------------------------
176   // Switch according to operation type
177   //---------------------------------
178   typedef itk::ImageToImageFilter<InternalImageType, InternalImageType> ImageFilterType;
179   typename ImageFilterType::Pointer filter; 
180   switch(m_OperationType)
181     {
182     case Erode: {
183       typedef itk::BinaryErodeImageFilter<InternalImageType, InternalImageType , KernelType> FilterType;
184       typename FilterType::Pointer m = FilterType::New();
185       m->SetBackgroundValue(this->GetBackgroundValue());
186       m->SetForegroundValue(this->GetForegroundValue());
187       m->SetBoundaryToForeground(GetBoundaryToForegroundFlag());
188       m->SetKernel(structuringElement);
189       
190       filter=m;
191       if (GetVerboseFlag()) std::cout<<"Using the erode filter..."<<std::endl;
192       break;
193     }
194
195     case Dilate:
196       {
197         typedef itk::BinaryDilateImageFilter<InternalImageType, InternalImageType , KernelType> FilterType;
198         typename FilterType::Pointer m = FilterType::New();
199         m->SetBackgroundValue(this->GetBackgroundValue());
200         m->SetForegroundValue(this->GetForegroundValue());
201         m->SetBoundaryToForeground(GetBoundaryToForegroundFlag());
202         m->SetKernel(structuringElement);
203
204         filter=m;
205         if (GetVerboseFlag()) std::cout<<"Using the dilate filter..."<<std::endl;
206         break;
207       }
208
209     case Close:
210       {
211         typedef itk::BinaryMorphologicalClosingImageFilter<InternalImageType, InternalImageType , KernelType> FilterType;
212         typename FilterType::Pointer m = FilterType::New();
213         m->SetForegroundValue(this->GetForegroundValue());
214         m->SetSafeBorder(GetBoundaryToForegroundFlag());
215         m->SetKernel(structuringElement);
216
217         filter=m;
218         if (GetVerboseFlag()) std::cout<<"Using the closing filter..."<<std::endl;
219         break;
220       }
221
222     case Open:
223       {
224         typedef itk::BinaryMorphologicalOpeningImageFilter<InternalImageType, InternalImageType , KernelType> FilterType;
225         typename FilterType::Pointer m = FilterType::New();
226         m->SetBackgroundValue(this->GetBackgroundValue());
227         m->SetForegroundValue(this->GetForegroundValue());
228         m->SetKernel(structuringElement);
229
230         filter=m;
231         if (GetVerboseFlag()) std::cout<<"Using the opening filter..."<<std::endl;
232         break;
233       }
234
235     case CondErode:
236       {
237         typedef clitk::ConditionalBinaryErodeImageFilter<InternalImageType, InternalImageType , KernelType> FilterType;
238         typename FilterType::Pointer m = FilterType::New();
239         m->SetBackgroundValue(this->GetBackgroundValue());
240         m->SetForegroundValue(this->GetForegroundValue());
241         m->SetBoundaryToForeground(GetBoundaryToForegroundFlag());
242         m->SetKernel(structuringElement);
243           
244         filter=m;
245         if (GetVerboseFlag()) std::cout<<"Using the conditional erode filter..."<<std::endl;
246         break;
247       }
248
249     case CondDilate:
250       {
251         typedef clitk::ConditionalBinaryDilateImageFilter<InternalImageType, InternalImageType , KernelType> FilterType;
252         typename FilterType::Pointer m = FilterType::New();
253         m->SetBackgroundValue(this->GetBackgroundValue());
254         m->SetForegroundValue(this->GetForegroundValue());
255         m->SetBoundaryToForeground(GetBoundaryToForegroundFlag());
256         m->SetKernel(structuringElement);
257           
258         filter=m;
259         if (GetVerboseFlag()) std::cout<<"Using the conditional dilate filter..."<<std::endl;
260         break;
261       }
262
263     }
264   
265
266   //---------------------------------
267   // Execute the filter
268   //---------------------------------
269   filter->SetInput(input);
270   filter->Update();
271
272   //---------------------------------
273   // Write the output
274   //---------------------------------
275   typedef itk::CastImageFilter< InternalImageType, ImageType > OutputCastImageFilterType;
276   typename OutputCastImageFilterType::Pointer oCaster = OutputCastImageFilterType::New();
277   oCaster->SetInput(filter->GetOutput());
278   oCaster->Update();
279   this->SetNthOutput(0, oCaster->GetOutput());
280 }
281 //--------------------------------------------------------------------
282
283