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