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);
35 //--------------------------------------------------------------------
38 //--------------------------------------------------------------------
39 template<class ImageType>
40 clitk::MorphoMathFilter<ImageType>::~MorphoMathFilter()
44 //--------------------------------------------------------------------
47 //--------------------------------------------------------------------
48 template<class ImageType>
49 void clitk::MorphoMathFilter<ImageType>::
50 SetRadiusInMM(PointType & p)
53 m_RadiusInMMIsSet = true;
54 m_RadiusIsSet = false;
56 //--------------------------------------------------------------------
59 //--------------------------------------------------------------------
60 template<class ImageType>
61 void clitk::MorphoMathFilter<ImageType>::
62 SetRadius(SizeType & p)
66 m_RadiusInMMIsSet = false;
68 //--------------------------------------------------------------------
71 //--------------------------------------------------------------------
72 template<class ImageType>
73 void clitk::MorphoMathFilter<ImageType>::
76 for(uint i=0; i<ImageType::ImageDimension; i++)
80 //--------------------------------------------------------------------
83 //--------------------------------------------------------------------
84 template<class ImageType>
85 void clitk::MorphoMathFilter<ImageType>::
86 SetOperationType(int type)
89 case 0: m_OperationType = Erode; return;
90 case 1: m_OperationType = Dilate; return;
91 case 2: m_OperationType = Open; return;
92 case 3: m_OperationType = Close; return;
93 case 4: m_OperationType = CondErode; return;
94 case 5: m_OperationType = CondDilate; return;
95 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)");
98 //--------------------------------------------------------------------
101 //--------------------------------------------------------------------
102 template <class ImageType>
104 clitk::MorphoMathFilter<ImageType>::
105 GenerateInputRequestedRegion()
108 itk::ImageToImageFilter<ImageType, ImageType>::GenerateInputRequestedRegion();
109 // Get input pointers and set requested region to common region
110 ImagePointer input1 = dynamic_cast<ImageType*>(itk::ProcessObject::GetInput(0));
111 input1->SetRequestedRegion(input1->GetLargestPossibleRegion());
113 //--------------------------------------------------------------------
116 //--------------------------------------------------------------------
117 template <class ImageType>
119 clitk::MorphoMathFilter<ImageType>::
120 GenerateOutputInformation()
122 //---------------------------------
124 //---------------------------------
125 ImagePointer m_input = dynamic_cast<ImageType*>(itk::ProcessObject::GetInput(0));
127 //---------------------------------
128 // Cast into internalimagetype
129 //---------------------------------
130 typedef itk::CastImageFilter<ImageType, InternalImageType> InputCastImageFilterType;
131 typename InputCastImageFilterType::Pointer caster = InputCastImageFilterType::New();
132 caster->SetInput(m_input);
134 input =caster->GetOutput();
136 //---------------------------------
137 // Compute the radius in pixel
138 //---------------------------------
139 if (m_RadiusInMMIsSet) {
140 for(uint i=0; i<ImageType::ImageDimension; i++) {
141 m_Radius[i] = (uint)lrint(m_RadiusInMM[i]/input->GetSpacing()[i]);
145 //---------------------------------
146 // Extend the image if needed
147 //---------------------------------
148 if (GetExtendSupportFlag()) {
149 typedef itk::ConstantPadImageFilter<InternalImageType, InternalImageType> PadFilterType;
150 typename PadFilterType::Pointer padFilter = PadFilterType::New();
151 padFilter->SetInput(input);
152 typename ImageType::SizeType lower;
153 typename ImageType::SizeType upper;
154 for(uint i=0; i<3; i++) {
155 lower[i] = upper[i] = 2*(m_Radius[i]+1);
157 padFilter->SetPadLowerBound(lower);
158 padFilter->SetPadUpperBound(upper);
160 if (GetVerboseFlag()) std::cout << "Extend the image to 2x " << lower << std::endl;
161 input = padFilter->GetOutput();
165 ImagePointer outputImage = this->GetOutput(0);
166 outputImage->SetRegions(input->GetLargestPossibleRegion());
168 //--------------------------------------------------------------------
171 //--------------------------------------------------------------------
172 template <class ImageType>
174 clitk::MorphoMathFilter<ImageType>::
177 //---------------------------------
179 //---------------------------------
180 typedef itk::BinaryBallStructuringElement<PixelType,ImageDimension> KernelType;
181 KernelType structuringElement;
182 if (GetVerboseFlag()) {
183 std::cout << "Radius in pixel : " << m_Radius << std::endl;
185 structuringElement.SetRadius(m_Radius);
186 structuringElement.CreateStructuringElement();
188 //---------------------------------
189 // Switch according to operation type
190 //---------------------------------
191 typedef itk::ImageToImageFilter<InternalImageType, InternalImageType> ImageFilterType;
192 typename ImageFilterType::Pointer filter;
193 switch(m_OperationType)
196 typedef itk::BinaryErodeImageFilter<InternalImageType, InternalImageType , KernelType> FilterType;
197 typename FilterType::Pointer m = FilterType::New();
198 m->SetBackgroundValue(this->GetBackgroundValue());
199 m->SetForegroundValue(this->GetForegroundValue());
200 m->SetBoundaryToForeground(GetBoundaryToForegroundFlag());
201 m->SetKernel(structuringElement);
204 if (GetVerboseFlag()) std::cout<<"Using the erode filter..."<<std::endl;
210 typedef itk::BinaryDilateImageFilter<InternalImageType, InternalImageType , KernelType> FilterType;
211 typename FilterType::Pointer m = FilterType::New();
212 m->SetBackgroundValue(this->GetBackgroundValue());
213 m->SetForegroundValue(this->GetForegroundValue());
214 m->SetBoundaryToForeground(GetBoundaryToForegroundFlag());
215 m->SetKernel(structuringElement);
218 if (GetVerboseFlag()) std::cout<<"Using the dilate filter..."<<std::endl;
224 typedef itk::BinaryMorphologicalClosingImageFilter<InternalImageType, InternalImageType , KernelType> FilterType;
225 typename FilterType::Pointer m = FilterType::New();
226 m->SetForegroundValue(this->GetForegroundValue());
227 m->SetSafeBorder(GetBoundaryToForegroundFlag());
228 m->SetKernel(structuringElement);
231 if (GetVerboseFlag()) std::cout<<"Using the closing filter..."<<std::endl;
237 typedef itk::BinaryMorphologicalOpeningImageFilter<InternalImageType, InternalImageType , KernelType> FilterType;
238 typename FilterType::Pointer m = FilterType::New();
239 m->SetBackgroundValue(this->GetBackgroundValue());
240 m->SetForegroundValue(this->GetForegroundValue());
241 m->SetKernel(structuringElement);
244 if (GetVerboseFlag()) std::cout<<"Using the opening filter..."<<std::endl;
250 typedef clitk::ConditionalBinaryErodeImageFilter<InternalImageType, InternalImageType , KernelType> FilterType;
251 typename FilterType::Pointer m = FilterType::New();
252 m->SetBackgroundValue(this->GetBackgroundValue());
253 m->SetForegroundValue(this->GetForegroundValue());
254 m->SetBoundaryToForeground(GetBoundaryToForegroundFlag());
255 m->SetKernel(structuringElement);
258 if (GetVerboseFlag()) std::cout<<"Using the conditional erode filter..."<<std::endl;
264 typedef clitk::ConditionalBinaryDilateImageFilter<InternalImageType, InternalImageType , KernelType> FilterType;
265 typename FilterType::Pointer m = FilterType::New();
266 m->SetBackgroundValue(this->GetBackgroundValue());
267 m->SetForegroundValue(this->GetForegroundValue());
268 m->SetBoundaryToForeground(GetBoundaryToForegroundFlag());
269 m->SetKernel(structuringElement);
272 if (GetVerboseFlag()) std::cout<<"Using the conditional dilate filter..."<<std::endl;
279 //---------------------------------
280 // Execute the filter
281 //---------------------------------
282 filter->SetInput(input);
285 //---------------------------------
287 //---------------------------------
288 typedef itk::CastImageFilter< InternalImageType, ImageType > OutputCastImageFilterType;
289 typename OutputCastImageFilterType::Pointer oCaster = OutputCastImageFilterType::New();
290 oCaster->SetInput(filter->GetOutput());
293 this->SetNthOutput(0, oCaster->GetOutput());
294 //this->GraftOutput(oCaster->GetOutput()); // NO
296 //--------------------------------------------------------------------