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 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);
92 //--------------------------------------------------------------------
95 //--------------------------------------------------------------------
96 template <class ImageType>
98 clitk::MorphoMathFilter<ImageType>::
99 GenerateInputRequestedRegion()
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());
107 //--------------------------------------------------------------------
110 //--------------------------------------------------------------------
111 template <class ImageType>
113 clitk::MorphoMathFilter<ImageType>::
114 GenerateOutputInformation()
116 //---------------------------------
118 //---------------------------------
119 ImagePointer m_input = dynamic_cast<ImageType*>(itk::ProcessObject::GetInput(0));
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);
128 input =caster->GetOutput();
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]);
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);
151 padFilter->SetPadLowerBound(lower);
152 padFilter->SetPadUpperBound(upper);
154 if (GetVerboseFlag()) std::cout << "Extend the image to 2x " << lower << std::endl;
155 input = padFilter->GetOutput();
159 ImagePointer outputImage = this->GetOutput(0);
160 outputImage->SetRegions(input->GetLargestPossibleRegion());
162 //--------------------------------------------------------------------
165 //--------------------------------------------------------------------
166 template <class ImageType>
168 clitk::MorphoMathFilter<ImageType>::
171 //---------------------------------
173 //---------------------------------
174 typedef itk::BinaryBallStructuringElement<PixelType,ImageDimension> KernelType;
175 KernelType structuringElement;
176 if (GetVerboseFlag()) {
177 std::cout << "Radius in pixel : " << m_Radius << std::endl;
179 structuringElement.SetRadius(m_Radius);
180 structuringElement.CreateStructuringElement();
182 //---------------------------------
183 // Switch according to operation type
184 //---------------------------------
185 typedef itk::ImageToImageFilter<InternalImageType, InternalImageType> ImageFilterType;
186 typename ImageFilterType::Pointer filter;
187 switch(m_OperationType)
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);
198 if (GetVerboseFlag()) std::cout<<"Using the erode filter..."<<std::endl;
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);
212 if (GetVerboseFlag()) std::cout<<"Using the dilate filter..."<<std::endl;
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);
225 if (GetVerboseFlag()) std::cout<<"Using the closing filter..."<<std::endl;
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);
238 if (GetVerboseFlag()) std::cout<<"Using the opening filter..."<<std::endl;
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);
252 if (GetVerboseFlag()) std::cout<<"Using the conditional erode filter..."<<std::endl;
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);
266 if (GetVerboseFlag()) std::cout<<"Using the conditional dilate filter..."<<std::endl;
273 //---------------------------------
274 // Execute the filter
275 //---------------------------------
276 filter->SetInput(input);
279 //---------------------------------
281 //---------------------------------
282 typedef itk::CastImageFilter< InternalImageType, ImageType > OutputCastImageFilterType;
283 typename OutputCastImageFilterType::Pointer oCaster = OutputCastImageFilterType::New();
284 oCaster->SetInput(filter->GetOutput());
287 this->SetNthOutput(0, oCaster->GetOutput());
288 //this->GraftOutput(oCaster->GetOutput()); // NO
290 //--------------------------------------------------------------------