]> Creatis software - clitk.git/blob - segmentation/clitkFillMaskFilter.txx
Debug RTStruct conversion with empty struc
[clitk.git] / segmentation / clitkFillMaskFilter.txx
1 /*=========================================================================
2   Program:   vv                     http://www.creatis.insa-lyon.fr/rio/vv
3
4   Authors belong to: 
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
8
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.
12
13   It is distributed under dual licence
14
15   - BSD        See included LICENSE.txt file
16   - CeCILL-B   http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html
17   ===========================================================================**/
18
19 #ifndef CLITKFILLMASKFILTER_TXX
20 #define CLITKFILLMASKFILTER_TXX
21
22 //--------------------------------------------------------------------
23 template <class ImageType>
24 clitk::FillMaskFilter<ImageType>::FillMaskFilter():
25   itk::ImageToImageFilter<ImageType, ImageType>()
26 {
27   // Default global options
28   this->SetNumberOfRequiredInputs(1);
29   ResetDirections();
30 }
31 //--------------------------------------------------------------------
32
33
34 //--------------------------------------------------------------------
35 template <class ImageType>
36 void 
37 clitk::FillMaskFilter<ImageType>::
38 AddDirection(int dir)
39 {
40   m_Directions.push_back(dir);
41 }
42 //--------------------------------------------------------------------
43
44
45 //--------------------------------------------------------------------
46 template <class ImageType>
47 void 
48 clitk::FillMaskFilter<ImageType>::
49 ResetDirections()
50 {
51   m_Directions.clear();
52 }
53 //--------------------------------------------------------------------
54
55
56 //--------------------------------------------------------------------
57 template <class ImageType>
58 template<class ArgsInfoType>
59 void 
60 clitk::FillMaskFilter<ImageType>::
61 SetOptionsFromArgsInfo(ArgsInfoType & mArgsInfo)
62 {
63   ResetDirections();
64   for(uint i=0; i<mArgsInfo.dir_given; i++) {
65     AddDirection(mArgsInfo.dir_arg[i]);
66   }
67 }
68 //--------------------------------------------------------------------
69
70
71 //--------------------------------------------------------------------
72 template <class ImageType>
73 template<class ArgsInfoType>
74 void 
75 clitk::FillMaskFilter<ImageType>::
76 SetOptionsToArgsInfo(ArgsInfoType & mArgsInfo)
77 {
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];
82   }
83 }
84 //--------------------------------------------------------------------
85
86
87 //--------------------------------------------------------------------
88 template <class ImageType>
89 void 
90 clitk::FillMaskFilter<ImageType>::
91 GenerateData() 
92 {
93   InputImagePointer input  = dynamic_cast<ImageType*>(itk::ProcessObject::GetInput(0));
94
95   // Cast 
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();
102
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     //----------------------------------------
111         
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; 
120     start2D.Fill(0);
121     typename InternalImageType::RegionType desiredRegion;
122     desiredRegion.SetSize( size2D );
123     desiredRegion.SetIndex( start2D );
124     
125     // Extract and Join 
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]]);
130       
131     //---------------------------------------- 
132     // Run over the sliceIndexs
133     // ----------------------------------------
134     for(unsigned int sliceIndex=0; sliceIndex <size3D[m_Directions[i]]; sliceIndex++)
135       {
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();
147         
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");
156         
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");
165         
166         // Sort the labels
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");     
172         
173         // Keep the first
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");    
181         
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");    
190         
191         //Join
192         joinFilter->SetInput( sliceIndex, switchFilter->GetOutput());
193       }
194     
195     // Join to a 3D image       
196     joinFilter->Update();
197     
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)
205       {
206         order[0]=0;
207         order[1]=1;
208       }
209     else if ( m_Directions[i]==1)
210       {
211         order[0]=0;
212         order[2]=1;
213       }
214     else if (m_Directions[i]==0)
215       {
216         order[1]=0;
217         order[2]=1;
218       }
219     permuteFilter->SetOrder(order);
220     permuteFilter->Update();
221     output = permuteFilter->GetOutput();
222     
223     // Set the image direction to the input one
224     output->SetDirection(input->GetDirection());
225     output->SetOrigin(input->GetOrigin());
226   }
227   
228   // Cast
229   typedef itk::CastImageFilter<InternalImageType,ImageType> OutputCastImageFilterType;
230   typename OutputCastImageFilterType::Pointer outputCaster =OutputCastImageFilterType::New();
231   outputCaster->SetInput(output);
232   outputCaster->Update();
233   
234   // Output
235   this->GraftOutput(outputCaster->GetOutput());
236 }
237 //--------------------------------------------------------------------
238
239 #endif //#define CLITKFILLMASKFILTER_TXX