]> Creatis software - clitk.git/blob - itk/clitkSliceBySliceRelativePositionFilter.txx
correct intermediate spacing flag
[clitk.git] / itk / clitkSliceBySliceRelativePositionFilter.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://oncora1.lyon.fnclcc.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 // clitk
20 #include "clitkSegmentationUtils.h"
21 #include "clitkExtractSliceFilter.h"
22 #include "clitkResampleImageWithOptionsFilter.h"
23
24 // itk
25 #include <itkJoinSeriesImageFilter.h>
26
27 //--------------------------------------------------------------------
28 template <class ImageType>
29 clitk::SliceBySliceRelativePositionFilter<ImageType>::
30 SliceBySliceRelativePositionFilter():
31   clitk::AddRelativePositionConstraintToLabelImageFilter<ImageType>()
32 {
33   SetDirection(2);
34   UniqueConnectedComponentBySliceOff();
35   SetIgnoreEmptySliceObjectFlag(false);
36   this->SetCombineWithOrFlag(false);
37 }
38 //--------------------------------------------------------------------
39
40
41 //--------------------------------------------------------------------
42 template <class ImageType>
43 void 
44 clitk::SliceBySliceRelativePositionFilter<ImageType>::
45 SetInput(const ImageType * image) 
46 {
47   // Process object is not const-correct so the const casting is required.
48   this->SetNthInput(0, const_cast<ImageType *>(image));
49 }
50 //--------------------------------------------------------------------
51   
52
53 //--------------------------------------------------------------------
54 template <class ImageType>
55 void 
56 clitk::SliceBySliceRelativePositionFilter<ImageType>::
57 SetInputObject(const ImageType * image) 
58 {
59   // Process object is not const-correct so the const casting is required.
60   this->SetNthInput(1, const_cast<ImageType *>(image));
61 }
62 //--------------------------------------------------------------------
63   
64
65 //--------------------------------------------------------------------
66 template <class ImageType>
67 void 
68 clitk::SliceBySliceRelativePositionFilter<ImageType>::
69 PrintOptions() 
70 {
71   DD(this->GetDirection());
72   DD((int)this->GetObjectBackgroundValue());
73   DDV(this->GetOrientationTypeString(), (uint)this->GetNumberOfAngles());
74   DD(this->GetIntermediateSpacingFlag());
75   DD(this->GetIntermediateSpacing());
76   DD(this->GetFuzzyThreshold());
77   DD(this->GetUniqueConnectedComponentBySlice());
78   DD(this->GetAutoCropFlag());
79   DD(this->GetInverseOrientationFlag());
80   DD(this->GetRemoveObjectFlag());
81   DD(this->GetCombineWithOrFlag());
82 }
83 //--------------------------------------------------------------------
84
85
86 //--------------------------------------------------------------------
87 template <class ImageType>
88 void 
89 clitk::SliceBySliceRelativePositionFilter<ImageType>::
90 GenerateInputRequestedRegion() 
91 {
92   // Call default
93   itk::ImageToImageFilter<ImageType, ImageType>::GenerateInputRequestedRegion();
94   // Get input pointers and set requested region to common region
95   ImagePointer input1 = dynamic_cast<ImageType*>(itk::ProcessObject::GetInput(0));
96   ImagePointer input2 = dynamic_cast<ImageType*>(itk::ProcessObject::GetInput(1));
97   input1->SetRequestedRegion(input1->GetLargestPossibleRegion());
98   input2->SetRequestedRegion(input2->GetLargestPossibleRegion());
99 }
100 //--------------------------------------------------------------------
101
102
103 //--------------------------------------------------------------------
104 template <class ImageType>
105 void 
106 clitk::SliceBySliceRelativePositionFilter<ImageType>::
107 GenerateOutputInformation() 
108 {
109   if (this->GetVerboseOptionFlag()) {
110     PrintOptions();
111   }
112
113   // Get input pointer
114   input = dynamic_cast<ImageType*>(itk::ProcessObject::GetInput(0));
115   object = dynamic_cast<ImageType*>(itk::ProcessObject::GetInput(1));
116
117   //--------------------------------------------------------------------
118   // Resample object to the same spacing than input
119   if (!clitk::HaveSameSpacing<ImageType, ImageType>(object, input)) {
120     this->StartNewStep("Resample object to the same spacing than input");
121     m_working_object = clitk::ResampleImageSpacing<ImageType>(object, input->GetSpacing());
122     this->template StopCurrentStep<ImageType>(m_working_object);
123   }
124   else {
125     m_working_object = object;
126   }
127   
128   //--------------------------------------------------------------------
129   // Pad object to the same size than input
130   if (!clitk::HaveSameSizeAndSpacing<ImageType, ImageType>(m_working_object, input)) {
131     this->StartNewStep("Pad object to the same size than input");
132     m_working_object = clitk::ResizeImageLike<ImageType>(m_working_object, 
133                                                          input, 
134                                                          this->GetObjectBackgroundValue());
135     this->template StopCurrentStep<ImageType>(m_working_object);
136   }
137   else {
138   }
139
140   /*
141     - extract vector of slices in input, in object
142     - slice by slice rel position
143     - joint result
144     - post process
145   */
146
147
148   //--------------------------------------------------------------------
149   // Extract input slices
150   this->StartNewStep("Extract input slices");
151   typedef clitk::ExtractSliceFilter<ImageType> ExtractSliceFilterType;
152   typename ExtractSliceFilterType::Pointer extractSliceFilter = ExtractSliceFilterType::New();
153   extractSliceFilter->SetInput(input);
154   extractSliceFilter->SetDirection(GetDirection());
155   extractSliceFilter->Update();
156   typedef typename ExtractSliceFilterType::SliceType SliceType;
157   std::vector<typename SliceType::Pointer> mInputSlices;
158   extractSliceFilter->GetOutputSlices(mInputSlices);
159   this->template StopCurrentStep<SliceType>(mInputSlices[0]);
160   
161   //--------------------------------------------------------------------
162   // Extract object slices
163   this->StartNewStep("Extract object slices");
164   extractSliceFilter = ExtractSliceFilterType::New();
165   extractSliceFilter->SetInput(m_working_object);//object);
166   extractSliceFilter->SetDirection(GetDirection());
167   extractSliceFilter->Update();
168   std::vector<typename SliceType::Pointer> mObjectSlices;
169   extractSliceFilter->GetOutputSlices(mObjectSlices);
170   this->template StopCurrentStep<SliceType>(mObjectSlices[0]);
171
172   //--------------------------------------------------------------------
173   // Perform slice by slice relative position
174   this->StartNewStep("Perform slice by slice relative position");
175   for(unsigned int i=0; i<mInputSlices.size(); i++) {
176     // Select main CC in each object slice (required ?)
177     int nb=0;
178     mObjectSlices[i] = LabelizeAndCountNumberOfObjects<SliceType>(mObjectSlices[i], 0, true, 1, nb);
179     if ((!GetIgnoreEmptySliceObjectFlag()) || (nb!=0)) {
180       mObjectSlices[i] = KeepLabels<SliceType>(mObjectSlices[i], 0, 1, 1, 1, true);
181
182       // Relative position
183       typedef clitk::AddRelativePositionConstraintToLabelImageFilter<SliceType> RelPosFilterType;
184       typename RelPosFilterType::Pointer relPosFilter = RelPosFilterType::New();
185
186       relPosFilter->VerboseStepFlagOff();
187       relPosFilter->WriteStepFlagOff();
188       relPosFilter->SetBackgroundValue(this->GetBackgroundValue());
189       relPosFilter->SetInput(mInputSlices[i]); 
190       relPosFilter->SetInputObject(mObjectSlices[i]); 
191       relPosFilter->SetRemoveObjectFlag(this->GetRemoveObjectFlag());
192       for(int j=0; j<this->GetNumberOfAngles(); j++) {
193         relPosFilter->AddOrientationTypeString(this->GetOrientationTypeString(j));
194       }
195       relPosFilter->SetInverseOrientationFlag(this->GetInverseOrientationFlag());
196       //relPosFilter->SetOrientationType(this->GetOrientationType());
197       relPosFilter->SetIntermediateSpacing(this->GetIntermediateSpacing());
198       relPosFilter->SetIntermediateSpacingFlag(this->GetIntermediateSpacingFlag());
199       relPosFilter->SetFuzzyThreshold(this->GetFuzzyThreshold());
200       relPosFilter->AutoCropFlagOff(); // important ! because we join the slices after this loop
201       relPosFilter->SetCombineWithOrFlag(this->GetCombineWithOrFlag()); 
202       relPosFilter->Update();
203       mInputSlices[i] = relPosFilter->GetOutput();
204
205       // Select main CC if needed
206       if (GetUniqueConnectedComponentBySlice()) {
207         mInputSlices[i] = Labelize<SliceType>(mInputSlices[i], 0, true, 1);
208         mInputSlices[i] = KeepLabels<SliceType>(mInputSlices[i], 0, 1, 1, 1, true);
209       }
210
211     }
212   }
213
214   // Join the slices
215   m_working_input = clitk::JoinSlices<ImageType>(mInputSlices, input, GetDirection());
216   this->template StopCurrentStep<ImageType>(m_working_input);
217
218   //--------------------------------------------------------------------
219   // Step 7: autocrop
220   if (this->GetAutoCropFlag()) {
221     this->StartNewStep("Final AutoCrop");
222     typedef clitk::AutoCropFilter<ImageType> CropFilterType;
223     typename CropFilterType::Pointer cropFilter = CropFilterType::New();
224     cropFilter->SetInput(m_working_input);
225     cropFilter->ReleaseDataFlagOff();
226     cropFilter->Update();   
227     m_working_input = cropFilter->GetOutput();
228     this->template StopCurrentStep<ImageType>(m_working_input);    
229   }
230
231   // Update output info
232   this->GetOutput(0)->SetRegions(m_working_input->GetLargestPossibleRegion());  
233 }
234 //--------------------------------------------------------------------
235
236
237 //--------------------------------------------------------------------
238 template <class ImageType>
239 void 
240 clitk::SliceBySliceRelativePositionFilter<ImageType>::
241 GenerateData() 
242 {
243   // Get input pointer
244   //--------------------------------------------------------------------
245   //--------------------------------------------------------------------  
246   // Final Step -> set output
247   //this->SetNthOutput(0, m_working_input);
248   this->GraftOutput(m_working_input);
249   return;
250 }
251 //--------------------------------------------------------------------
252