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://oncora1.lyon.fnclcc.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>::
73 SetOperationType(int 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)");
85 //--------------------------------------------------------------------
88 //--------------------------------------------------------------------
89 template <class ImageType>
91 clitk::MorphoMathFilter<ImageType>::
92 GenerateInputRequestedRegion()
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());
100 //--------------------------------------------------------------------
103 //--------------------------------------------------------------------
104 template <class ImageType>
106 clitk::MorphoMathFilter<ImageType>::
107 GenerateOutputInformation()
109 //---------------------------------
111 //---------------------------------
112 ImagePointer m_input = dynamic_cast<ImageType*>(itk::ProcessObject::GetInput(0));
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);
121 input =caster->GetOutput();
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]);
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);
144 padFilter->SetPadLowerBound(lower);
145 padFilter->SetPadUpperBound(upper);
147 if (GetVerboseFlag()) std::cout << "Extend the image to 2x " << lower << std::endl;
148 input = padFilter->GetOutput();
152 ImagePointer outputImage = this->GetOutput(0);
153 outputImage->SetRegions(input->GetLargestPossibleRegion());
155 //--------------------------------------------------------------------
158 //--------------------------------------------------------------------
159 template <class ImageType>
161 clitk::MorphoMathFilter<ImageType>::
164 //---------------------------------
166 //---------------------------------
167 typedef itk::BinaryBallStructuringElement<PixelType,ImageDimension> KernelType;
168 KernelType structuringElement;
169 if (GetVerboseFlag()) {
170 std::cout << "Radius in pixel : " << m_Radius << std::endl;
172 structuringElement.SetRadius(m_Radius);
173 structuringElement.CreateStructuringElement();
175 //---------------------------------
176 // Switch according to operation type
177 //---------------------------------
178 typedef itk::ImageToImageFilter<InternalImageType, InternalImageType> ImageFilterType;
179 typename ImageFilterType::Pointer filter;
180 switch(m_OperationType)
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);
191 if (GetVerboseFlag()) std::cout<<"Using the erode filter..."<<std::endl;
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);
205 if (GetVerboseFlag()) std::cout<<"Using the dilate filter..."<<std::endl;
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);
218 if (GetVerboseFlag()) std::cout<<"Using the closing filter..."<<std::endl;
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);
231 if (GetVerboseFlag()) std::cout<<"Using the opening filter..."<<std::endl;
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);
245 if (GetVerboseFlag()) std::cout<<"Using the conditional erode filter..."<<std::endl;
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);
259 if (GetVerboseFlag()) std::cout<<"Using the conditional dilate filter..."<<std::endl;
266 //---------------------------------
267 // Execute the filter
268 //---------------------------------
269 filter->SetInput(input);
272 //---------------------------------
274 //---------------------------------
275 typedef itk::CastImageFilter< InternalImageType, ImageType > OutputCastImageFilterType;
276 typename OutputCastImageFilterType::Pointer oCaster = OutputCastImageFilterType::New();
277 oCaster->SetInput(filter->GetOutput());
279 this->SetNthOutput(0, oCaster->GetOutput());
281 //--------------------------------------------------------------------