1 /*=========================================================================
2 Program: vv http://www.creatis.insa-lyon.fr/rio/vv
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
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.
13 It is distributed under dual licence
15 - BSD See included LICENSE.txt file
16 - CeCILL-B http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html
17 ===========================================================================**/
19 //--------------------------------------------------------------------
20 template<class ImageType>
21 clitk::MorphoMathFilter<ImageType>::MorphoMathFilter():
23 itk::ImageToImageFilter<ImageType, ImageType>()
25 this->SetNumberOfRequiredInputs(1);
26 SetBackgroundValue(0);
27 SetForegroundValue(1);
32 SetBoundaryToForegroundFlag(false);
34 //--------------------------------------------------------------------
37 //--------------------------------------------------------------------
38 template<class ImageType>
39 clitk::MorphoMathFilter<ImageType>::~MorphoMathFilter()
43 //--------------------------------------------------------------------
46 //--------------------------------------------------------------------
47 template<class ImageType>
48 void clitk::MorphoMathFilter<ImageType>::
49 SetRadiusInMM(PointType & p)
52 m_RadiusInMMIsSet = true;
53 m_RadiusIsSet = false;
55 //--------------------------------------------------------------------
58 //--------------------------------------------------------------------
59 template<class ImageType>
60 void clitk::MorphoMathFilter<ImageType>::
61 SetRadius(SizeType & p)
65 m_RadiusInMMIsSet = false;
67 //--------------------------------------------------------------------
70 //--------------------------------------------------------------------
71 template<class ImageType>
72 void clitk::MorphoMathFilter<ImageType>::
75 for(uint i=0; i<ImageType::ImageDimension; i++)
79 //--------------------------------------------------------------------
82 //--------------------------------------------------------------------
83 template<class ImageType>
84 void clitk::MorphoMathFilter<ImageType>::
85 SetOperationType(int type)
88 case 0: m_OperationType = Erode; return;
89 case 1: m_OperationType = Dilate; return;
90 case 2: m_OperationType = Open; return;
91 case 3: m_OperationType = Close; return;
92 case 4: m_OperationType = CondErode; return;
93 case 5: m_OperationType = CondDilate; return;
94 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)");
97 //--------------------------------------------------------------------
100 //--------------------------------------------------------------------
101 template <class ImageType>
103 clitk::MorphoMathFilter<ImageType>::
104 GenerateInputRequestedRegion()
107 itk::ImageToImageFilter<ImageType, ImageType>::GenerateInputRequestedRegion();
108 // Get input pointers and set requested region to common region
109 ImagePointer input1 = dynamic_cast<ImageType*>(itk::ProcessObject::GetInput(0));
110 input1->SetRequestedRegion(input1->GetLargestPossibleRegion());
112 //--------------------------------------------------------------------
115 //--------------------------------------------------------------------
116 template <class ImageType>
118 clitk::MorphoMathFilter<ImageType>::
119 GenerateOutputInformation()
121 //---------------------------------
123 //---------------------------------
124 ImagePointer m_input = dynamic_cast<ImageType*>(itk::ProcessObject::GetInput(0));
126 //---------------------------------
127 // Cast into internalimagetype
128 //---------------------------------
129 typedef itk::CastImageFilter<ImageType, InternalImageType> InputCastImageFilterType;
130 typename InputCastImageFilterType::Pointer caster = InputCastImageFilterType::New();
131 caster->SetInput(m_input);
133 input =caster->GetOutput();
135 //---------------------------------
136 // Compute the radius in pixel
137 //---------------------------------
138 if (m_RadiusInMMIsSet) {
139 for(uint i=0; i<ImageType::ImageDimension; i++) {
140 m_Radius[i] = (uint)lrint(m_RadiusInMM[i]/input->GetSpacing()[i]);
144 //---------------------------------
145 // Extend the image if needed
146 //---------------------------------
147 if (GetExtendSupportFlag()) {
148 typedef itk::ConstantPadImageFilter<InternalImageType, InternalImageType> PadFilterType;
149 typename PadFilterType::Pointer padFilter = PadFilterType::New();
150 padFilter->SetInput(input);
151 typename ImageType::SizeType lower;
152 typename ImageType::SizeType upper;
153 for(uint i=0; i<3; i++) {
154 lower[i] = upper[i] = 2*(m_Radius[i]+1);
156 padFilter->SetPadLowerBound(lower);
157 padFilter->SetPadUpperBound(upper);
159 if (GetVerboseFlag()) std::cout << "Extend the image to 2x " << lower << std::endl;
160 input = padFilter->GetOutput();
164 ImagePointer outputImage = this->GetOutput(0);
165 outputImage->SetRegions(input->GetLargestPossibleRegion());
167 //--------------------------------------------------------------------
170 //--------------------------------------------------------------------
171 template <class ImageType>
173 clitk::MorphoMathFilter<ImageType>::
176 //---------------------------------
178 //---------------------------------
179 typedef itk::BinaryBallStructuringElement<PixelType,ImageDimension> KernelType;
180 KernelType structuringElement;
181 if (GetVerboseFlag()) {
182 std::cout << "Radius in pixel : " << m_Radius << std::endl;
184 structuringElement.SetRadius(m_Radius);
185 structuringElement.CreateStructuringElement();
187 //---------------------------------
188 // Switch according to operation type
189 //---------------------------------
190 typedef itk::ImageToImageFilter<InternalImageType, InternalImageType> ImageFilterType;
191 typename ImageFilterType::Pointer filter;
192 switch(m_OperationType)
195 typedef itk::BinaryErodeImageFilter<InternalImageType, InternalImageType , KernelType> FilterType;
196 typename FilterType::Pointer m = FilterType::New();
197 m->SetBackgroundValue(this->GetBackgroundValue());
198 m->SetForegroundValue(this->GetForegroundValue());
199 m->SetBoundaryToForeground(GetBoundaryToForegroundFlag());
200 m->SetKernel(structuringElement);
203 if (GetVerboseFlag()) std::cout<<"Using the erode filter..."<<std::endl;
209 typedef itk::BinaryDilateImageFilter<InternalImageType, InternalImageType , KernelType> FilterType;
210 typename FilterType::Pointer m = FilterType::New();
211 m->SetBackgroundValue(this->GetBackgroundValue());
212 m->SetForegroundValue(this->GetForegroundValue());
213 m->SetBoundaryToForeground(GetBoundaryToForegroundFlag());
214 m->SetKernel(structuringElement);
217 if (GetVerboseFlag()) std::cout<<"Using the dilate filter..."<<std::endl;
223 typedef itk::BinaryMorphologicalClosingImageFilter<InternalImageType, InternalImageType , KernelType> FilterType;
224 typename FilterType::Pointer m = FilterType::New();
225 m->SetForegroundValue(this->GetForegroundValue());
226 m->SetSafeBorder(GetBoundaryToForegroundFlag());
227 m->SetKernel(structuringElement);
230 if (GetVerboseFlag()) std::cout<<"Using the closing filter..."<<std::endl;
236 typedef itk::BinaryMorphologicalOpeningImageFilter<InternalImageType, InternalImageType , KernelType> FilterType;
237 typename FilterType::Pointer m = FilterType::New();
238 m->SetBackgroundValue(this->GetBackgroundValue());
239 m->SetForegroundValue(this->GetForegroundValue());
240 m->SetKernel(structuringElement);
243 if (GetVerboseFlag()) std::cout<<"Using the opening filter..."<<std::endl;
249 typedef clitk::ConditionalBinaryErodeImageFilter<InternalImageType, InternalImageType , KernelType> FilterType;
250 typename FilterType::Pointer m = FilterType::New();
251 m->SetBackgroundValue(this->GetBackgroundValue());
252 m->SetForegroundValue(this->GetForegroundValue());
253 m->SetBoundaryToForeground(GetBoundaryToForegroundFlag());
254 m->SetKernel(structuringElement);
257 if (GetVerboseFlag()) std::cout<<"Using the conditional erode filter..."<<std::endl;
263 typedef clitk::ConditionalBinaryDilateImageFilter<InternalImageType, InternalImageType , KernelType> FilterType;
264 typename FilterType::Pointer m = FilterType::New();
265 m->SetBackgroundValue(this->GetBackgroundValue());
266 m->SetForegroundValue(this->GetForegroundValue());
267 m->SetBoundaryToForeground(GetBoundaryToForegroundFlag());
268 m->SetKernel(structuringElement);
271 if (GetVerboseFlag()) std::cout<<"Using the conditional dilate filter..."<<std::endl;
278 //---------------------------------
279 // Execute the filter
280 //---------------------------------
281 filter->SetInput(input);
284 //---------------------------------
286 //---------------------------------
287 typedef itk::CastImageFilter< InternalImageType, ImageType > OutputCastImageFilterType;
288 typename OutputCastImageFilterType::Pointer oCaster = OutputCastImageFilterType::New();
289 oCaster->SetInput(filter->GetOutput());
291 this->SetNthOutput(0, oCaster->GetOutput());
293 //--------------------------------------------------------------------