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();
35 SetIgnoreEmptySliceObject(false);
37 //--------------------------------------------------------------------
40 //--------------------------------------------------------------------
41 template <class ImageType>
43 clitk::SliceBySliceRelativePositionFilter<ImageType>::
44 SetInput(const ImageType * image)
46 // Process object is not const-correct so the const casting is required.
47 this->SetNthInput(0, const_cast<ImageType *>(image));
49 //--------------------------------------------------------------------
52 //--------------------------------------------------------------------
53 template <class ImageType>
55 clitk::SliceBySliceRelativePositionFilter<ImageType>::
56 SetInputObject(const ImageType * image)
58 // Process object is not const-correct so the const casting is required.
59 this->SetNthInput(1, const_cast<ImageType *>(image));
61 //--------------------------------------------------------------------
64 //--------------------------------------------------------------------
65 template <class ImageType>
67 clitk::SliceBySliceRelativePositionFilter<ImageType>::
70 DD(this->GetDirection());
71 DD((int)this->GetObjectBackgroundValue());
72 DDV(this->GetOrientationTypeString(), (uint)this->GetNumberOfAngles());
73 DD(this->GetResampleBeforeRelativePositionFilter());
74 DD(this->GetIntermediateSpacing());
75 DD(this->GetFuzzyThreshold());
76 DD(this->GetUniqueConnectedComponentBySlice());
77 DD(this->GetAutoCropFlag());
78 DD(this->GetInverseOrientationFlag());
79 DD(this->GetRemoveObjectFlag());
80 DD(this->GetCombineWithOrFlag());
82 //--------------------------------------------------------------------
85 //--------------------------------------------------------------------
86 template <class ImageType>
88 clitk::SliceBySliceRelativePositionFilter<ImageType>::
89 GenerateInputRequestedRegion()
92 itk::ImageToImageFilter<ImageType, ImageType>::GenerateInputRequestedRegion();
93 // Get input pointers and set requested region to common region
94 ImagePointer input1 = dynamic_cast<ImageType*>(itk::ProcessObject::GetInput(0));
95 ImagePointer input2 = dynamic_cast<ImageType*>(itk::ProcessObject::GetInput(1));
96 input1->SetRequestedRegion(input1->GetLargestPossibleRegion());
97 input2->SetRequestedRegion(input2->GetLargestPossibleRegion());
99 //--------------------------------------------------------------------
102 //--------------------------------------------------------------------
103 template <class ImageType>
105 clitk::SliceBySliceRelativePositionFilter<ImageType>::
106 GenerateOutputInformation()
108 if (this->GetVerboseOptionFlag()) {
113 input = dynamic_cast<ImageType*>(itk::ProcessObject::GetInput(0));
114 object = dynamic_cast<ImageType*>(itk::ProcessObject::GetInput(1));
116 //--------------------------------------------------------------------
117 // Resample object to the same spacing than input
118 if (!clitk::HaveSameSpacing<ImageType, ImageType>(object, input)) {
119 this->StartNewStep("Resample object to the same spacing than input");
120 m_working_object = clitk::ResampleImageSpacing<ImageType>(object, input->GetSpacing());
121 this->template StopCurrentStep<ImageType>(m_working_object);
124 m_working_object = object;
127 //--------------------------------------------------------------------
128 // Pad object to the same size than input
129 if (!clitk::HaveSameSizeAndSpacing<ImageType, ImageType>(m_working_object, input)) {
130 this->StartNewStep("Pad object to the same size than input");
131 m_working_object = clitk::ResizeImageLike<ImageType>(m_working_object,
133 this->GetObjectBackgroundValue());
134 this->template StopCurrentStep<ImageType>(m_working_object);
140 - extract vector of slices in input, in object
141 - slice by slice rel position
147 //--------------------------------------------------------------------
148 // Extract input slices
149 this->StartNewStep("Extract input slices");
150 typedef clitk::ExtractSliceFilter<ImageType> ExtractSliceFilterType;
151 typename ExtractSliceFilterType::Pointer extractSliceFilter = ExtractSliceFilterType::New();
152 extractSliceFilter->SetInput(input);
153 extractSliceFilter->SetDirection(GetDirection());
154 extractSliceFilter->Update();
155 typedef typename ExtractSliceFilterType::SliceType SliceType;
156 std::vector<typename SliceType::Pointer> mInputSlices;
157 extractSliceFilter->GetOutputSlices(mInputSlices);
158 this->template StopCurrentStep<SliceType>(mInputSlices[0]);
160 //--------------------------------------------------------------------
161 // Extract object slices
162 this->StartNewStep("Extract object slices");
163 extractSliceFilter = ExtractSliceFilterType::New();
164 extractSliceFilter->SetInput(m_working_object);//object);
165 extractSliceFilter->SetDirection(GetDirection());
166 extractSliceFilter->Update();
167 std::vector<typename SliceType::Pointer> mObjectSlices;
168 extractSliceFilter->GetOutputSlices(mObjectSlices);
169 this->template StopCurrentStep<SliceType>(mObjectSlices[0]);
171 //--------------------------------------------------------------------
172 // Perform slice by slice relative position
173 this->StartNewStep("Perform slice by slice relative position");
174 for(unsigned int i=0; i<mInputSlices.size(); i++) {
175 // Select main CC in each object slice (required ?)
177 mObjectSlices[i] = LabelizeAndCountNumberOfObjects<SliceType>(mObjectSlices[i], 0, true, 1, nb);
178 if ((!GetIgnoreEmptySliceObject()) || (nb!=0)) {
179 mObjectSlices[i] = KeepLabels<SliceType>(mObjectSlices[i], 0, 1, 1, 1, true);
182 typedef clitk::AddRelativePositionConstraintToLabelImageFilter<SliceType> RelPosFilterType;
183 typename RelPosFilterType::Pointer relPosFilter = RelPosFilterType::New();
184 relPosFilter->VerboseStepFlagOff();
185 relPosFilter->WriteStepFlagOff();
186 relPosFilter->SetCurrentStepBaseId(this->GetCurrentStepId());
187 relPosFilter->SetBackgroundValue(this->GetBackgroundValue());
188 relPosFilter->SetInput(mInputSlices[i]);
189 relPosFilter->SetInputObject(mObjectSlices[i]);
190 relPosFilter->SetRemoveObjectFlag(this->GetRemoveObjectFlag());
191 for(int j=0; j<this->GetNumberOfAngles(); j++) {
192 relPosFilter->AddOrientationTypeString(this->GetOrientationTypeString(j));
194 relPosFilter->SetInverseOrientationFlag(this->GetInverseOrientationFlag());
195 //relPosFilter->SetOrientationType(this->GetOrientationType());
196 relPosFilter->SetIntermediateSpacing(this->GetIntermediateSpacing());
197 relPosFilter->SetResampleBeforeRelativePositionFilter(this->GetResampleBeforeRelativePositionFilter());
198 relPosFilter->SetFuzzyThreshold(this->GetFuzzyThreshold());
199 relPosFilter->AutoCropFlagOff(); // important ! because we join the slices after this loop
200 relPosFilter->SetCombineWithOrFlag(this->GetCombineWithOrFlag());
201 relPosFilter->Update();
202 mInputSlices[i] = relPosFilter->GetOutput();
204 // Select main CC if needed
205 if (GetUniqueConnectedComponentBySlice()) {
206 mInputSlices[i] = Labelize<SliceType>(mInputSlices[i], 0, true, 1);
207 mInputSlices[i] = KeepLabels<SliceType>(mInputSlices[i], 0, 1, 1, 1, true);
214 m_working_input = clitk::JoinSlices<ImageType>(mInputSlices, input, GetDirection());
215 this->template StopCurrentStep<ImageType>(m_working_input);
217 //--------------------------------------------------------------------
219 if (this->GetAutoCropFlag()) {
220 this->StartNewStep("Final AutoCrop");
221 typedef clitk::AutoCropFilter<ImageType> CropFilterType;
222 typename CropFilterType::Pointer cropFilter = CropFilterType::New();
223 cropFilter->SetInput(m_working_input);
224 cropFilter->ReleaseDataFlagOff();
225 cropFilter->Update();
226 m_working_input = cropFilter->GetOutput();
227 this->template StopCurrentStep<ImageType>(m_working_input);
230 // Update output info
231 this->GetOutput(0)->SetRegions(m_working_input->GetLargestPossibleRegion());
233 //--------------------------------------------------------------------
236 //--------------------------------------------------------------------
237 template <class ImageType>
239 clitk::SliceBySliceRelativePositionFilter<ImageType>::
243 //--------------------------------------------------------------------
244 //--------------------------------------------------------------------
245 // Final Step -> set output
246 //this->SetNthOutput(0, m_working_input);
247 this->GraftOutput(m_working_input);
250 //--------------------------------------------------------------------