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 #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);
34 //--------------------------------------------------------------------
37 //--------------------------------------------------------------------
38 template <class ImageType>
40 clitk::FillMaskFilter<ImageType>::
43 m_Directions.push_back(dir);
45 //--------------------------------------------------------------------
48 //--------------------------------------------------------------------
49 template <class ImageType>
51 clitk::FillMaskFilter<ImageType>::
56 //--------------------------------------------------------------------
59 //--------------------------------------------------------------------
60 template <class ImageType>
61 template<class ArgsInfoType>
63 clitk::FillMaskFilter<ImageType>::
64 SetOptionsFromArgsInfo(ArgsInfoType & mArgsInfo)
67 for(uint i=0; i<mArgsInfo.dir_given; i++) {
68 AddDirection(mArgsInfo.dir_arg[i]);
71 //--------------------------------------------------------------------
74 //--------------------------------------------------------------------
75 template <class ImageType>
76 template<class ArgsInfoType>
78 clitk::FillMaskFilter<ImageType>::
79 SetOptionsToArgsInfo(ArgsInfoType & mArgsInfo)
81 mArgsInfo.dir_arg = new int[m_Directions.size()];
82 mArgsInfo.dir_given = m_Directions.size();
83 for(uint i=0; i<mArgsInfo.dir_given; i++) {
84 mArgsInfo.dir_arg[i] = m_Directions[i];
87 //--------------------------------------------------------------------
90 //--------------------------------------------------------------------
91 template <class ImageType>
93 clitk::FillMaskFilter<ImageType>::
96 InputImagePointer input = dynamic_cast<ImageType*>(itk::ProcessObject::GetInput(0));
99 typedef int InternalPixelType;
100 typedef itk::Image<InternalPixelType, ImageType::ImageDimension> InternalImageType;
101 typedef itk::CastImageFilter<ImageType,InternalImageType> InputCastImageFilterType;
102 typename InputCastImageFilterType::Pointer inputCaster = InputCastImageFilterType::New();
103 inputCaster->SetInput(input);
104 inputCaster->Update();
106 //----------------------------------------
107 // Loop over directions
108 //----------------------------------------
109 typename InternalImageType::Pointer output = inputCaster->GetOutput();
110 for (unsigned int i=0; i<m_Directions.size();i++) {
112 //----------------------------------------
113 // Fill the holes of a mask in 2D
114 //----------------------------------------
116 // We define the region to be extracted.
117 typedef itk::Image<InternalPixelType, ImageType::ImageDimension-1> ImageSliceType;
118 typedef itk::Image<InternalPixelType, ImageType::ImageDimension-1> MaskSliceType;
119 typename InternalImageType::RegionType region3D = input->GetLargestPossibleRegion();
120 typename InternalImageType::RegionType::SizeType size3D = region3D.GetSize();
121 typename InternalImageType::RegionType::SizeType size2D = size3D;
122 size2D[m_Directions[i]]=0;
123 typename InternalImageType::IndexType start2D;
125 typename InternalImageType::RegionType desiredRegion;
126 desiredRegion.SetSize( size2D );
127 desiredRegion.SetIndex( start2D );
130 typedef itk::ExtractImageFilter<InternalImageType, ImageSliceType> ExtractImageFilterType;
131 typedef itk::JoinSeriesImageFilter<ImageSliceType, InternalImageType> JoinSeriesFilterType;
132 typename JoinSeriesFilterType::Pointer joinFilter=JoinSeriesFilterType::New();
133 joinFilter->SetSpacing(input->GetSpacing()[m_Directions[i]]);
135 //----------------------------------------
136 // Run over the sliceIndexs
137 // ----------------------------------------
138 for(unsigned int sliceIndex=0; sliceIndex <size3D[m_Directions[i]]; sliceIndex++)
140 //----------------------------------------
141 // Extract mask sliceIndex
142 //----------------------------------------
143 typename ExtractImageFilterType::Pointer extractFilter=ExtractImageFilterType::New();
144 extractFilter->SetInput(output);
145 start2D[m_Directions[i]]=sliceIndex;
146 desiredRegion.SetIndex( start2D );
147 extractFilter->SetExtractionRegion( desiredRegion );
148 extractFilter->Update( );
149 typename ImageSliceType::Pointer slice= extractFilter->GetOutput();
151 // Binarize the image (Before: OBJECT!=0, rest=0, After: object=1, rest=0 )
152 typedef itk::BinaryThresholdImageFilter<ImageSliceType,ImageSliceType> BinarizeFilterType;
153 typename BinarizeFilterType::Pointer binarizeFilter=BinarizeFilterType::New();
154 binarizeFilter->SetInput(slice);
155 binarizeFilter->SetUpperThreshold(0);
156 binarizeFilter->SetOutsideValue(0);
157 binarizeFilter->SetInsideValue(1);
158 // writeImage<ImageSliceType>(binarizeFilter->GetOutput(),"/home/jef/tmp/input.mhd");
160 // Perform connected labelling on the slice (body+air=0 )
161 typedef itk::ConnectedComponentImageFilter<ImageSliceType, ImageSliceType> ConnectFilterType;
162 typename ConnectFilterType::Pointer connectFilter=ConnectFilterType::New();
163 connectFilter->SetInput(binarizeFilter->GetOutput());
164 connectFilter->SetBackgroundValue(0);
165 connectFilter->SetFullyConnected(false);
166 //connectFilter->Update();
167 //writeImage<ImageSliceType>(connectFilter->GetOutput(),"/home/jef/tmp/connect.mhd");
170 typedef itk::RelabelComponentImageFilter<ImageSliceType, ImageSliceType> RelabelFilterType;
171 typename RelabelFilterType::Pointer relabelFilter=RelabelFilterType::New();
172 relabelFilter->SetInput(connectFilter->GetOutput());
173 //relabelFilter->Update();
174 //writeImage<ImageSliceType>(relabelFilter->GetOutput(),"/home/jef/tmp/label.mhd");
177 typedef itk::ThresholdImageFilter<ImageSliceType> ThresholdFilterType;
178 typename ThresholdFilterType::Pointer thresholdFilter=ThresholdFilterType::New();
179 thresholdFilter->SetInput(relabelFilter->GetOutput());
180 thresholdFilter->SetUpper(1);
181 thresholdFilter->SetOutsideValue(0);
182 // thresholdFilter->Update();
183 // writeImage<ImageSliceType>(thresholdFilter->GetOutput(),"/home/jef/tmp/bin.mhd");
185 // Invert the labels (lung 1, rest 0)
186 typename BinarizeFilterType::Pointer switchFilter=BinarizeFilterType::New();
187 switchFilter->SetInput(thresholdFilter->GetOutput());
188 switchFilter->SetUpperThreshold(0);
189 switchFilter->SetOutsideValue(0);
190 switchFilter->SetInsideValue(1);
191 switchFilter->Update();
192 //writeImage<ImageSliceType>(switchFilter->GetOutput(),"/home/jef/tmp/inv_bin.mhd");
195 joinFilter->SetInput( sliceIndex, switchFilter->GetOutput());
198 // Join to a 3D image
199 std::cout<<"Joining the slices..."<<std::endl;
200 joinFilter->Update();
202 // Permute the axes to reset to orientation
203 typedef itk::PermuteAxesImageFilter<InternalImageType> PermuteFilterType;
204 typename PermuteFilterType::Pointer permuteFilter=PermuteFilterType::New();
205 permuteFilter->SetInput(joinFilter->GetOutput());
206 typename PermuteFilterType::PermuteOrderArrayType order;
207 order[m_Directions[i]]=2;
208 if( m_Directions[i]==2)
213 else if ( m_Directions[i]==1)
218 else if (m_Directions[i]==0)
223 permuteFilter->SetOrder(order);
224 permuteFilter->Update();
225 output = permuteFilter->GetOutput();
227 // Set the image direction to the input one
228 output->SetDirection(input->GetDirection());
229 output->SetOrigin(input->GetOrigin());
232 writeImage<InternalImageType>(output, "toto.mhd");
236 typedef itk::CastImageFilter<InternalImageType,ImageType> OutputCastImageFilterType;
237 typename OutputCastImageFilterType::Pointer outputCaster =OutputCastImageFilterType::New();
238 outputCaster->SetInput(output);
239 outputCaster->Update();
243 this->GraftOutput(outputCaster->GetOutput());
245 //--------------------------------------------------------------------
247 #endif //#define CLITKFILLMASKFILTER_TXX