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));
120 const unsigned int dim = ImageType::ImageDimension;
122 //---------------------------------
123 // Cast into internalimagetype
124 //---------------------------------
125 typedef itk::CastImageFilter<ImageType, InternalImageType> InputCastImageFilterType;
126 typename InputCastImageFilterType::Pointer caster = InputCastImageFilterType::New();
127 caster->SetInput(m_input);
129 input =caster->GetOutput();
131 //---------------------------------
132 // Compute the radius in pixel
133 //---------------------------------
134 if (m_RadiusInMMIsSet) {
135 for(uint i=0; i<dim; i++) {
136 m_Radius[i] = (uint)lrint(m_RadiusInMM[i]/input->GetSpacing()[i]);
140 //---------------------------------
141 // Extend the image if needed
142 //---------------------------------
143 if (GetExtendSupportFlag()) {
144 typedef itk::ConstantPadImageFilter<InternalImageType, InternalImageType> PadFilterType;
145 typename PadFilterType::Pointer padFilter = PadFilterType::New();
146 padFilter->SetInput(input);
147 typename ImageType::SizeType lower;
148 typename ImageType::SizeType upper;
149 for(uint i=0; i<dim; i++) {
150 lower[i] = upper[i] = 2*(m_Radius[i]+1);
152 padFilter->SetPadLowerBound(lower);
153 padFilter->SetPadUpperBound(upper);
155 if (GetVerboseFlag()) std::cout << "Extend the image to 2x " << lower << std::endl;
156 input = padFilter->GetOutput();
160 ImagePointer outputImage = this->GetOutput(0);
161 outputImage->SetRegions(input->GetLargestPossibleRegion());
163 //--------------------------------------------------------------------
166 //--------------------------------------------------------------------
167 template <class ImageType>
169 clitk::MorphoMathFilter<ImageType>::
172 //---------------------------------
174 //---------------------------------
175 typedef itk::BinaryBallStructuringElement<PixelType,ImageDimension> KernelType;
176 KernelType structuringElement;
177 if (GetVerboseFlag()) {
178 std::cout << "Radius in pixel : " << m_Radius << std::endl;
180 structuringElement.SetRadius(m_Radius);
181 structuringElement.CreateStructuringElement();
183 //---------------------------------
184 // Switch according to operation type
185 //---------------------------------
186 typedef itk::ImageToImageFilter<InternalImageType, InternalImageType> ImageFilterType;
187 typename ImageFilterType::Pointer filter;
188 switch(m_OperationType)
191 typedef itk::BinaryErodeImageFilter<InternalImageType, InternalImageType , KernelType> FilterType;
192 typename FilterType::Pointer m = FilterType::New();
193 m->SetBackgroundValue(this->GetBackgroundValue());
194 m->SetForegroundValue(this->GetForegroundValue());
195 m->SetBoundaryToForeground(GetBoundaryToForegroundFlag());
196 m->SetKernel(structuringElement);
199 if (GetVerboseFlag()) std::cout<<"Using the erode filter..."<<std::endl;
205 typedef itk::BinaryDilateImageFilter<InternalImageType, InternalImageType , KernelType> FilterType;
206 typename FilterType::Pointer m = FilterType::New();
207 m->SetBackgroundValue(this->GetBackgroundValue());
208 m->SetForegroundValue(this->GetForegroundValue());
209 m->SetBoundaryToForeground(GetBoundaryToForegroundFlag());
210 m->SetKernel(structuringElement);
213 if (GetVerboseFlag()) std::cout<<"Using the dilate filter..."<<std::endl;
219 typedef itk::BinaryMorphologicalClosingImageFilter<InternalImageType, InternalImageType , KernelType> FilterType;
220 typename FilterType::Pointer m = FilterType::New();
221 m->SetForegroundValue(this->GetForegroundValue());
222 m->SetSafeBorder(GetBoundaryToForegroundFlag());
223 m->SetKernel(structuringElement);
226 if (GetVerboseFlag()) std::cout<<"Using the closing filter..."<<std::endl;
232 typedef itk::BinaryMorphologicalOpeningImageFilter<InternalImageType, InternalImageType , KernelType> FilterType;
233 typename FilterType::Pointer m = FilterType::New();
234 m->SetBackgroundValue(this->GetBackgroundValue());
235 m->SetForegroundValue(this->GetForegroundValue());
236 m->SetKernel(structuringElement);
239 if (GetVerboseFlag()) std::cout<<"Using the opening filter..."<<std::endl;
245 typedef clitk::ConditionalBinaryErodeImageFilter<InternalImageType, InternalImageType , KernelType> FilterType;
246 typename FilterType::Pointer m = FilterType::New();
247 m->SetBackgroundValue(this->GetBackgroundValue());
248 m->SetForegroundValue(this->GetForegroundValue());
249 m->SetBoundaryToForeground(GetBoundaryToForegroundFlag());
250 m->SetKernel(structuringElement);
253 if (GetVerboseFlag()) std::cout<<"Using the conditional erode filter..."<<std::endl;
259 typedef clitk::ConditionalBinaryDilateImageFilter<InternalImageType, InternalImageType , KernelType> FilterType;
260 typename FilterType::Pointer m = FilterType::New();
261 m->SetBackgroundValue(this->GetBackgroundValue());
262 m->SetForegroundValue(this->GetForegroundValue());
263 m->SetBoundaryToForeground(GetBoundaryToForegroundFlag());
264 m->SetKernel(structuringElement);
267 if (GetVerboseFlag()) std::cout<<"Using the conditional dilate filter..."<<std::endl;
274 //---------------------------------
275 // Execute the filter
276 //---------------------------------
277 filter->SetInput(input);
280 //---------------------------------
282 //---------------------------------
283 typedef itk::CastImageFilter< InternalImageType, ImageType > OutputCastImageFilterType;
284 typename OutputCastImageFilterType::Pointer oCaster = OutputCastImageFilterType::New();
285 oCaster->SetInput(filter->GetOutput());
288 this->SetNthOutput(0, oCaster->GetOutput());
289 //this->GraftOutput(oCaster->GetOutput()); // NO
291 //--------------------------------------------------------------------