]> Creatis software - clitk.git/blob - segmentation/clitkMorphoMathFilter.txx
2eb3a0261c280da9193d39e270d1746f6a478944
[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   VerboseFlagOff();
34 }
35 //--------------------------------------------------------------------
36
37
38 //--------------------------------------------------------------------
39 template<class ImageType>
40 clitk::MorphoMathFilter<ImageType>::~MorphoMathFilter()
41 {
42   // Nothing
43 }
44 //--------------------------------------------------------------------
45
46
47 //--------------------------------------------------------------------
48 template<class ImageType>
49 void clitk::MorphoMathFilter<ImageType>::
50 SetRadiusInMM(PointType & p)
51 {
52   m_RadiusInMM = p;
53   m_RadiusInMMIsSet = true;
54   m_RadiusIsSet = false;
55 }
56 //--------------------------------------------------------------------
57
58
59 //--------------------------------------------------------------------
60 template<class ImageType>
61 void clitk::MorphoMathFilter<ImageType>::
62 SetRadius(SizeType & p)
63 {
64   m_Radius = p;
65   m_RadiusIsSet = true;
66   m_RadiusInMMIsSet = false;
67 }
68 //--------------------------------------------------------------------
69
70
71 //--------------------------------------------------------------------
72 template<class ImageType>
73 void clitk::MorphoMathFilter<ImageType>::
74 SetRadius(int r)
75 {
76   for(uint i=0; i<ImageType::ImageDimension; i++)
77     m_Radius[i] = r;
78   SetRadius(m_Radius);
79 }
80 //--------------------------------------------------------------------
81
82
83 //--------------------------------------------------------------------
84 template<class ImageType>
85 void clitk::MorphoMathFilter<ImageType>::
86 SetOperationType(int type)
87 {
88   if(type<0 || type>5)
89     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)");
90   m_OperationType = OperationTypeEnumeration(type);
91 }
92 //--------------------------------------------------------------------
93
94
95 //--------------------------------------------------------------------
96 template <class ImageType>
97 void 
98 clitk::MorphoMathFilter<ImageType>::
99 GenerateInputRequestedRegion() 
100 {
101   // Call default
102   itk::ImageToImageFilter<ImageType, ImageType>::GenerateInputRequestedRegion();
103   // Get input pointers and set requested region to common region
104   ImagePointer input1 = dynamic_cast<ImageType*>(itk::ProcessObject::GetInput(0));
105   input1->SetRequestedRegion(input1->GetLargestPossibleRegion());
106 }
107 //--------------------------------------------------------------------
108
109
110 //--------------------------------------------------------------------
111 template <class ImageType>
112 void 
113 clitk::MorphoMathFilter<ImageType>::
114 GenerateOutputInformation() 
115 {
116   //---------------------------------
117   // Define the images
118   //---------------------------------
119   ImagePointer m_input = dynamic_cast<ImageType*>(itk::ProcessObject::GetInput(0));
120
121   //---------------------------------
122   // Cast into internalimagetype
123   //---------------------------------
124   typedef itk::CastImageFilter<ImageType, InternalImageType> InputCastImageFilterType;
125   typename InputCastImageFilterType::Pointer caster = InputCastImageFilterType::New();
126   caster->SetInput(m_input);
127   caster->Update();
128   input =caster->GetOutput();
129   
130   //---------------------------------
131   // Compute the radius in pixel
132   //---------------------------------
133   if (m_RadiusInMMIsSet) {
134     for(uint i=0; i<ImageType::ImageDimension; i++) {
135       m_Radius[i] = (uint)lrint(m_RadiusInMM[i]/input->GetSpacing()[i]);
136     }
137   }
138
139   //---------------------------------
140   // Extend the image if needed
141   //---------------------------------
142   if (GetExtendSupportFlag()) {
143     typedef itk::ConstantPadImageFilter<InternalImageType, InternalImageType> PadFilterType;
144     typename PadFilterType::Pointer padFilter = PadFilterType::New();
145     padFilter->SetInput(input);
146     typename ImageType::SizeType lower;
147     typename ImageType::SizeType upper;
148     for(uint i=0; i<3; i++) {
149       lower[i] = upper[i] = 2*(m_Radius[i]+1);
150     }
151     padFilter->SetPadLowerBound(lower);
152     padFilter->SetPadUpperBound(upper);
153     padFilter->Update();
154     if (GetVerboseFlag()) std::cout << "Extend the image to 2x " << lower << std::endl;
155     input = padFilter->GetOutput();
156   }
157   
158   // Set output size
159   ImagePointer outputImage = this->GetOutput(0);
160   outputImage->SetRegions(input->GetLargestPossibleRegion());
161 }
162 //--------------------------------------------------------------------
163
164
165 //--------------------------------------------------------------------
166 template <class ImageType>
167 void 
168 clitk::MorphoMathFilter<ImageType>::
169 GenerateData() 
170 {
171   //---------------------------------
172   // Build kernel
173   //---------------------------------
174   typedef itk::BinaryBallStructuringElement<PixelType,ImageDimension> KernelType;
175   KernelType structuringElement;
176   if (GetVerboseFlag()) {
177     std::cout << "Radius in pixel : " << m_Radius << std::endl;
178   }
179   structuringElement.SetRadius(m_Radius);
180   structuringElement.CreateStructuringElement();
181
182   //---------------------------------
183   // Switch according to operation type
184   //---------------------------------
185   typedef itk::ImageToImageFilter<InternalImageType, InternalImageType> ImageFilterType;
186   typename ImageFilterType::Pointer filter; 
187   switch(m_OperationType)
188     {
189     case Erode: {
190       typedef itk::BinaryErodeImageFilter<InternalImageType, InternalImageType , KernelType> FilterType;
191       typename FilterType::Pointer m = FilterType::New();
192       m->SetBackgroundValue(this->GetBackgroundValue());
193       m->SetForegroundValue(this->GetForegroundValue());
194       m->SetBoundaryToForeground(GetBoundaryToForegroundFlag());
195       m->SetKernel(structuringElement);
196       
197       filter=m;
198       if (GetVerboseFlag()) std::cout<<"Using the erode filter..."<<std::endl;
199       break;
200     }
201
202     case Dilate:
203       {
204         typedef itk::BinaryDilateImageFilter<InternalImageType, InternalImageType , KernelType> FilterType;
205         typename FilterType::Pointer m = FilterType::New();
206         m->SetBackgroundValue(this->GetBackgroundValue());
207         m->SetForegroundValue(this->GetForegroundValue());
208         m->SetBoundaryToForeground(GetBoundaryToForegroundFlag());
209         m->SetKernel(structuringElement);
210
211         filter=m;
212         if (GetVerboseFlag()) std::cout<<"Using the dilate filter..."<<std::endl;
213         break;
214       }
215
216     case Close:
217       {
218         typedef itk::BinaryMorphologicalClosingImageFilter<InternalImageType, InternalImageType , KernelType> FilterType;
219         typename FilterType::Pointer m = FilterType::New();
220         m->SetForegroundValue(this->GetForegroundValue());
221         m->SetSafeBorder(GetBoundaryToForegroundFlag());
222         m->SetKernel(structuringElement);
223
224         filter=m;
225         if (GetVerboseFlag()) std::cout<<"Using the closing filter..."<<std::endl;
226         break;
227       }
228
229     case Open:
230       {
231         typedef itk::BinaryMorphologicalOpeningImageFilter<InternalImageType, InternalImageType , KernelType> FilterType;
232         typename FilterType::Pointer m = FilterType::New();
233         m->SetBackgroundValue(this->GetBackgroundValue());
234         m->SetForegroundValue(this->GetForegroundValue());
235         m->SetKernel(structuringElement);
236
237         filter=m;
238         if (GetVerboseFlag()) std::cout<<"Using the opening filter..."<<std::endl;
239         break;
240       }
241
242     case CondErode:
243       {
244         typedef clitk::ConditionalBinaryErodeImageFilter<InternalImageType, InternalImageType , KernelType> FilterType;
245         typename FilterType::Pointer m = FilterType::New();
246         m->SetBackgroundValue(this->GetBackgroundValue());
247         m->SetForegroundValue(this->GetForegroundValue());
248         m->SetBoundaryToForeground(GetBoundaryToForegroundFlag());
249         m->SetKernel(structuringElement);
250           
251         filter=m;
252         if (GetVerboseFlag()) std::cout<<"Using the conditional erode filter..."<<std::endl;
253         break;
254       }
255
256     case CondDilate:
257       {
258         typedef clitk::ConditionalBinaryDilateImageFilter<InternalImageType, InternalImageType , KernelType> FilterType;
259         typename FilterType::Pointer m = FilterType::New();
260         m->SetBackgroundValue(this->GetBackgroundValue());
261         m->SetForegroundValue(this->GetForegroundValue());
262         m->SetBoundaryToForeground(GetBoundaryToForegroundFlag());
263         m->SetKernel(structuringElement);
264           
265         filter=m;
266         if (GetVerboseFlag()) std::cout<<"Using the conditional dilate filter..."<<std::endl;
267         break;
268       }
269
270     }
271   
272
273   //---------------------------------
274   // Execute the filter
275   //---------------------------------
276   filter->SetInput(input);
277   filter->Update();
278
279   //---------------------------------
280   // Write the output
281   //---------------------------------
282   typedef itk::CastImageFilter< InternalImageType, ImageType > OutputCastImageFilterType;
283   typename OutputCastImageFilterType::Pointer oCaster = OutputCastImageFilterType::New();
284   oCaster->SetInput(filter->GetOutput());
285   oCaster->Update();
286
287   this->SetNthOutput(0, oCaster->GetOutput());
288   //this->GraftOutput(oCaster->GetOutput()); // NO
289 }
290 //--------------------------------------------------------------------
291
292