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 #ifndef CLITKFILLMASKFILTER_TXX
20 #define CLITKFILLMASKFILTER_TXX
22 //--------------------------------------------------------------------
23 template <class ImageType>
24 clitk::FillMaskFilter<ImageType>::FillMaskFilter():
25 itk::ImageToImageFilter<ImageType, ImageType>()
27 // Default global options
28 this->SetNumberOfRequiredInputs(1);
31 //--------------------------------------------------------------------
34 //--------------------------------------------------------------------
35 template <class ImageType>
37 clitk::FillMaskFilter<ImageType>::
40 m_Directions.push_back(dir);
42 //--------------------------------------------------------------------
45 //--------------------------------------------------------------------
46 template <class ImageType>
48 clitk::FillMaskFilter<ImageType>::
53 //--------------------------------------------------------------------
56 //--------------------------------------------------------------------
57 template <class ImageType>
58 template<class ArgsInfoType>
60 clitk::FillMaskFilter<ImageType>::
61 SetOptionsFromArgsInfo(ArgsInfoType & mArgsInfo)
64 for(uint i=0; i<mArgsInfo.dir_given; i++) {
65 AddDirection(mArgsInfo.dir_arg[i]);
68 //--------------------------------------------------------------------
71 //--------------------------------------------------------------------
72 template <class ImageType>
73 template<class ArgsInfoType>
75 clitk::FillMaskFilter<ImageType>::
76 SetOptionsToArgsInfo(ArgsInfoType & mArgsInfo)
78 mArgsInfo.dir_arg = new int[m_Directions.size()];
79 mArgsInfo.dir_given = m_Directions.size();
80 for(uint i=0; i<mArgsInfo.dir_given; i++) {
81 mArgsInfo.dir_arg[i] = m_Directions[i];
84 //--------------------------------------------------------------------
87 //--------------------------------------------------------------------
88 template <class ImageType>
90 clitk::FillMaskFilter<ImageType>::
93 InputImagePointer input = dynamic_cast<ImageType*>(itk::ProcessObject::GetInput(0));
96 typedef int InternalPixelType;
97 typedef itk::Image<InternalPixelType, ImageType::ImageDimension> InternalImageType;
98 typedef itk::CastImageFilter<ImageType,InternalImageType> InputCastImageFilterType;
99 typename InputCastImageFilterType::Pointer inputCaster = InputCastImageFilterType::New();
100 inputCaster->SetInput(input);
101 inputCaster->Update();
103 //----------------------------------------
104 // Loop over directions
105 //----------------------------------------
106 typename InternalImageType::Pointer output = inputCaster->GetOutput();
107 for (unsigned int i=0; i<m_Directions.size();i++) {
108 //----------------------------------------
109 // Fill the holes of a mask in 2D
110 //----------------------------------------
112 // We define the region to be extracted.
113 typedef itk::Image<InternalPixelType, ImageType::ImageDimension-1> ImageSliceType;
114 typedef itk::Image<InternalPixelType, ImageType::ImageDimension-1> MaskSliceType;
115 typename InternalImageType::RegionType region3D = input->GetLargestPossibleRegion();
116 typename InternalImageType::RegionType::SizeType size3D = region3D.GetSize();
117 typename InternalImageType::RegionType::SizeType size2D = size3D;
118 size2D[m_Directions[i]]=0;
119 typename InternalImageType::IndexType start2D;
121 typename InternalImageType::RegionType desiredRegion;
122 desiredRegion.SetSize( size2D );
123 desiredRegion.SetIndex( start2D );
126 typedef itk::ExtractImageFilter<InternalImageType, ImageSliceType> ExtractImageFilterType;
127 typedef itk::JoinSeriesImageFilter<ImageSliceType, InternalImageType> JoinSeriesFilterType;
128 typename JoinSeriesFilterType::Pointer joinFilter=JoinSeriesFilterType::New();
129 joinFilter->SetSpacing(input->GetSpacing()[m_Directions[i]]);
131 //----------------------------------------
132 // Run over the sliceIndexs
133 // ----------------------------------------
134 for(unsigned int sliceIndex=0; sliceIndex <size3D[m_Directions[i]]; sliceIndex++)
136 //----------------------------------------
137 // Extract mask sliceIndex
138 //----------------------------------------
139 typename ExtractImageFilterType::Pointer extractFilter=ExtractImageFilterType::New();
140 extractFilter->SetInput(output);
141 start2D[m_Directions[i]]=sliceIndex;
142 desiredRegion.SetIndex( start2D );
143 extractFilter->SetExtractionRegion( desiredRegion );
144 extractFilter->SetDirectionCollapseToSubmatrix();
145 extractFilter->Update( );
146 typename ImageSliceType::Pointer slice= extractFilter->GetOutput();
148 // Binarize the image (Before: OBJECT!=0, rest=0, After: object=1, rest=0 )
149 typedef itk::BinaryThresholdImageFilter<ImageSliceType,ImageSliceType> BinarizeFilterType;
150 typename BinarizeFilterType::Pointer binarizeFilter=BinarizeFilterType::New();
151 binarizeFilter->SetInput(slice);
152 binarizeFilter->SetUpperThreshold(0);
153 binarizeFilter->SetOutsideValue(0);
154 binarizeFilter->SetInsideValue(1);
155 // writeImage<ImageSliceType>(binarizeFilter->GetOutput(),"/home/jef/tmp/input.mhd");
157 // Perform connected labelling on the slice (body+air=0 )
158 typedef itk::ConnectedComponentImageFilter<ImageSliceType, ImageSliceType> ConnectFilterType;
159 typename ConnectFilterType::Pointer connectFilter=ConnectFilterType::New();
160 connectFilter->SetInput(binarizeFilter->GetOutput());
161 connectFilter->SetBackgroundValue(0);
162 connectFilter->SetFullyConnected(false);
163 //connectFilter->Update();
164 //writeImage<ImageSliceType>(connectFilter->GetOutput(),"/home/jef/tmp/connect.mhd");
167 typedef itk::RelabelComponentImageFilter<ImageSliceType, ImageSliceType> RelabelFilterType;
168 typename RelabelFilterType::Pointer relabelFilter=RelabelFilterType::New();
169 relabelFilter->SetInput(connectFilter->GetOutput());
170 //relabelFilter->Update();
171 //writeImage<ImageSliceType>(relabelFilter->GetOutput(),"/home/jef/tmp/label.mhd");
174 typedef itk::ThresholdImageFilter<ImageSliceType> ThresholdFilterType;
175 typename ThresholdFilterType::Pointer thresholdFilter=ThresholdFilterType::New();
176 thresholdFilter->SetInput(relabelFilter->GetOutput());
177 thresholdFilter->SetUpper(1);
178 thresholdFilter->SetOutsideValue(0);
179 // thresholdFilter->Update();
180 // writeImage<ImageSliceType>(thresholdFilter->GetOutput(),"/home/jef/tmp/bin.mhd");
182 // Invert the labels (lung 1, rest 0)
183 typename BinarizeFilterType::Pointer switchFilter=BinarizeFilterType::New();
184 switchFilter->SetInput(thresholdFilter->GetOutput());
185 switchFilter->SetUpperThreshold(0);
186 switchFilter->SetOutsideValue(0);
187 switchFilter->SetInsideValue(1);
188 switchFilter->Update();
189 //writeImage<ImageSliceType>(switchFilter->GetOutput(),"/home/jef/tmp/inv_bin.mhd");
192 joinFilter->SetInput( sliceIndex, switchFilter->GetOutput());
195 // Join to a 3D image
196 joinFilter->Update();
198 // Permute the axes to reset to orientation
199 typedef itk::PermuteAxesImageFilter<InternalImageType> PermuteFilterType;
200 typename PermuteFilterType::Pointer permuteFilter=PermuteFilterType::New();
201 permuteFilter->SetInput(joinFilter->GetOutput());
202 typename PermuteFilterType::PermuteOrderArrayType order;
203 order[m_Directions[i]]=2;
204 if( m_Directions[i]==2)
209 else if ( m_Directions[i]==1)
214 else if (m_Directions[i]==0)
219 permuteFilter->SetOrder(order);
220 permuteFilter->Update();
221 output = permuteFilter->GetOutput();
223 // Set the image direction to the input one
224 output->SetDirection(input->GetDirection());
225 output->SetOrigin(input->GetOrigin());
229 typedef itk::CastImageFilter<InternalImageType,ImageType> OutputCastImageFilterType;
230 typename OutputCastImageFilterType::Pointer outputCaster =OutputCastImageFilterType::New();
231 outputCaster->SetInput(output);
232 outputCaster->Update();
235 this->GraftOutput(outputCaster->GetOutput());
237 //--------------------------------------------------------------------
239 #endif //#define CLITKFILLMASKFILTER_TXX