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 ======================================================================-====*/
20 #include "clitkSegmentationUtils.h"
21 #include "clitkExtractSliceFilter.h"
22 #include "clitkResampleImageWithOptionsFilter.h"
25 #include <itkJoinSeriesImageFilter.h>
27 //--------------------------------------------------------------------
28 template <class ImageType>
29 clitk::SliceBySliceRelativePositionFilter<ImageType>::
30 SliceBySliceRelativePositionFilter():
31 clitk::AddRelativePositionConstraintToLabelImageFilter<ImageType>()
34 UniqueConnectedComponentBySliceOff();
36 //--------------------------------------------------------------------
39 //--------------------------------------------------------------------
40 template <class ImageType>
42 clitk::SliceBySliceRelativePositionFilter<ImageType>::
43 SetInput(const ImageType * image)
45 // Process object is not const-correct so the const casting is required.
46 this->SetNthInput(0, const_cast<ImageType *>(image));
48 //--------------------------------------------------------------------
51 //--------------------------------------------------------------------
52 template <class ImageType>
54 clitk::SliceBySliceRelativePositionFilter<ImageType>::
55 SetInputObject(const ImageType * image)
57 // Process object is not const-correct so the const casting is required.
58 this->SetNthInput(1, const_cast<ImageType *>(image));
60 //--------------------------------------------------------------------
63 //--------------------------------------------------------------------
64 template <class ImageType>
66 clitk::SliceBySliceRelativePositionFilter<ImageType>::
69 DD(this->GetDirection());
70 DD((int)this->GetObjectBackgroundValue());
71 DDV(this->GetOrientationTypeString(), (uint)this->GetNumberOfAngles());
72 DD(this->GetResampleBeforeRelativePositionFilter());
73 DD(this->GetIntermediateSpacing());
74 DD(this->GetFuzzyThreshold());
75 DD(this->GetUniqueConnectedComponentBySlice());
76 DD(this->GetAutoCropFlag());
77 DD(this->GetInverseOrientationFlag());
78 DD(this->GetRemoveObjectFlag());
79 DD(this->GetCombineWithOrFlag());
81 //--------------------------------------------------------------------
84 //--------------------------------------------------------------------
85 template <class ImageType>
87 clitk::SliceBySliceRelativePositionFilter<ImageType>::
88 GenerateInputRequestedRegion()
91 itk::ImageToImageFilter<ImageType, ImageType>::GenerateInputRequestedRegion();
92 // Get input pointers and set requested region to common region
93 ImagePointer input1 = dynamic_cast<ImageType*>(itk::ProcessObject::GetInput(0));
94 ImagePointer input2 = dynamic_cast<ImageType*>(itk::ProcessObject::GetInput(1));
95 input1->SetRequestedRegion(input1->GetLargestPossibleRegion());
96 input2->SetRequestedRegion(input2->GetLargestPossibleRegion());
98 //--------------------------------------------------------------------
101 //--------------------------------------------------------------------
102 template <class ImageType>
104 clitk::SliceBySliceRelativePositionFilter<ImageType>::
105 GenerateOutputInformation()
107 if (this->GetVerboseOptionFlag()) {
112 input = dynamic_cast<ImageType*>(itk::ProcessObject::GetInput(0));
113 object = dynamic_cast<ImageType*>(itk::ProcessObject::GetInput(1));
115 //--------------------------------------------------------------------
116 // Resample object to the same spacing than input
117 if (!clitk::HaveSameSpacing<ImageType, ImageType>(object, input)) {
118 this->StartNewStep("Resample object to the same spacing than input");
119 m_working_object = clitk::ResampleImageSpacing<ImageType>(object, input->GetSpacing());
120 this->template StopCurrentStep<ImageType>(m_working_object);
123 m_working_object = object;
126 //--------------------------------------------------------------------
127 // Pad object to the same size than input
128 if (!clitk::HaveSameSizeAndSpacing<ImageType, ImageType>(m_working_object, input)) {
129 this->StartNewStep("Pad object to the same size than input");
130 m_working_object = clitk::ResizeImageLike<ImageType>(m_working_object,
132 this->GetObjectBackgroundValue());
133 this->template StopCurrentStep<ImageType>(m_working_object);
139 - extract vector of slices in input, in object
140 - slice by slice rel position
146 //--------------------------------------------------------------------
147 // Extract input slices
148 this->StartNewStep("Extract input slices");
149 typedef clitk::ExtractSliceFilter<ImageType> ExtractSliceFilterType;
150 typename ExtractSliceFilterType::Pointer extractSliceFilter = ExtractSliceFilterType::New();
151 extractSliceFilter->SetInput(input);
152 extractSliceFilter->SetDirection(GetDirection());
153 extractSliceFilter->Update();
154 typedef typename ExtractSliceFilterType::SliceType SliceType;
155 std::vector<typename SliceType::Pointer> mInputSlices;
156 extractSliceFilter->GetOutputSlices(mInputSlices);
157 this->template StopCurrentStep<SliceType>(mInputSlices[0]);
159 //--------------------------------------------------------------------
160 // Extract object slices
161 this->StartNewStep("Extract object slices");
162 extractSliceFilter = ExtractSliceFilterType::New();
163 extractSliceFilter->SetInput(m_working_object);//object);
164 extractSliceFilter->SetDirection(GetDirection());
165 extractSliceFilter->Update();
166 std::vector<typename SliceType::Pointer> mObjectSlices;
167 extractSliceFilter->GetOutputSlices(mObjectSlices);
168 this->template StopCurrentStep<SliceType>(mObjectSlices[0]);
170 //--------------------------------------------------------------------
171 // Perform slice by slice relative position
172 this->StartNewStep("Perform slice by slice relative position");
173 for(unsigned int i=0; i<mInputSlices.size(); i++) {
174 // Select main CC in each object slice (required ?)
175 mObjectSlices[i] = Labelize<SliceType>(mObjectSlices[i], 0, true, 1);
176 mObjectSlices[i] = KeepLabels<SliceType>(mObjectSlices[i], 0, 1, 1, 1, true);
179 typedef clitk::AddRelativePositionConstraintToLabelImageFilter<SliceType> RelPosFilterType;
180 typename RelPosFilterType::Pointer relPosFilter = RelPosFilterType::New();
181 relPosFilter->VerboseStepFlagOff();
182 relPosFilter->WriteStepFlagOff();
183 relPosFilter->SetCurrentStepBaseId(this->GetCurrentStepId());
184 relPosFilter->SetBackgroundValue(this->GetBackgroundValue());
185 relPosFilter->SetInput(mInputSlices[i]);
186 relPosFilter->SetInputObject(mObjectSlices[i]);
187 relPosFilter->SetRemoveObjectFlag(this->GetRemoveObjectFlag());
188 for(int j=0; j<this->GetNumberOfAngles(); j++) {
189 relPosFilter->AddOrientationTypeString(this->GetOrientationTypeString(j));
191 relPosFilter->SetInverseOrientationFlag(this->GetInverseOrientationFlag());
192 //relPosFilter->SetOrientationType(this->GetOrientationType());
193 relPosFilter->SetIntermediateSpacing(this->GetIntermediateSpacing());
194 relPosFilter->SetResampleBeforeRelativePositionFilter(this->GetResampleBeforeRelativePositionFilter());
195 relPosFilter->SetFuzzyThreshold(this->GetFuzzyThreshold());
196 relPosFilter->AutoCropFlagOff(); // important ! because we join the slices after this loop
197 relPosFilter->SetCombineWithOrFlag(this->GetCombineWithOrFlag());
198 relPosFilter->Update();
199 mInputSlices[i] = relPosFilter->GetOutput();
201 // Select main CC if needed
202 if (GetUniqueConnectedComponentBySlice()) {
203 mInputSlices[i] = Labelize<SliceType>(mInputSlices[i], 0, true, 1);
204 mInputSlices[i] = KeepLabels<SliceType>(mInputSlices[i], 0, 1, 1, 1, true);
210 m_working_input = clitk::JoinSlices<ImageType>(mInputSlices, input, GetDirection());
211 this->template StopCurrentStep<ImageType>(m_working_input);
213 //--------------------------------------------------------------------
215 if (this->GetAutoCropFlag()) {
216 this->StartNewStep("Final AutoCrop");
217 typedef clitk::AutoCropFilter<ImageType> CropFilterType;
218 typename CropFilterType::Pointer cropFilter = CropFilterType::New();
219 cropFilter->SetInput(m_working_input);
220 cropFilter->ReleaseDataFlagOff();
221 cropFilter->Update();
222 m_working_input = cropFilter->GetOutput();
223 this->template StopCurrentStep<ImageType>(m_working_input);
226 // Update output info
227 this->GetOutput(0)->SetRegions(m_working_input->GetLargestPossibleRegion());
229 //--------------------------------------------------------------------
232 //--------------------------------------------------------------------
233 template <class ImageType>
235 clitk::SliceBySliceRelativePositionFilter<ImageType>::
239 //--------------------------------------------------------------------
240 //--------------------------------------------------------------------
241 // Final Step -> set output
242 //this->SetNthOutput(0, m_working_input);
243 this->GraftOutput(m_working_input);
246 //--------------------------------------------------------------------