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"
23 //--------------------------------------------------------------------
24 template <class ImageType>
25 clitk::SliceBySliceRelativePositionFilter<ImageType>::
26 SliceBySliceRelativePositionFilter():
28 itk::ImageToImageFilter<ImageType, ImageType>()
30 this->SetNumberOfRequiredInputs(2);
32 SetObjectBackgroundValue(0);
33 SetFuzzyThreshold(0.6);
34 SetOrientationType(RelPosFilterType::LeftTo);
35 SetIntermediateSpacing(10);
36 ResampleBeforeRelativePositionFilterOff();
38 //--------------------------------------------------------------------
41 //--------------------------------------------------------------------
42 template <class ImageType>
44 clitk::SliceBySliceRelativePositionFilter<ImageType>::
45 SetInput(const ImageType * image)
47 // Process object is not const-correct so the const casting is required.
48 this->SetNthInput(0, const_cast<ImageType *>(image));
50 //--------------------------------------------------------------------
53 //--------------------------------------------------------------------
54 template <class ImageType>
56 clitk::SliceBySliceRelativePositionFilter<ImageType>::
57 SetInputObject(const ImageType * image)
59 // Process object is not const-correct so the const casting is required.
60 this->SetNthInput(1, const_cast<ImageType *>(image));
62 //--------------------------------------------------------------------
65 //--------------------------------------------------------------------
66 template <class ImageType>
68 clitk::SliceBySliceRelativePositionFilter<ImageType>::
69 GenerateOutputInformation()
71 ImagePointer input = dynamic_cast<ImageType*>(itk::ProcessObject::GetInput(0));
72 ImagePointer outputImage = this->GetOutput(0);
73 outputImage->SetRegions(input->GetLargestPossibleRegion());
75 //--------------------------------------------------------------------
78 //--------------------------------------------------------------------
79 template <class ImageType>
81 clitk::SliceBySliceRelativePositionFilter<ImageType>::
82 GenerateInputRequestedRegion()
85 itk::ImageToImageFilter<ImageType, ImageType>::GenerateInputRequestedRegion();
86 // Get input pointers and set requested region to common region
87 ImagePointer input1 = dynamic_cast<ImageType*>(itk::ProcessObject::GetInput(0));
88 ImagePointer input2 = dynamic_cast<ImageType*>(itk::ProcessObject::GetInput(1));
89 input1->SetRequestedRegion(input1->GetLargestPossibleRegion());
90 input2->SetRequestedRegion(input2->GetLargestPossibleRegion());
92 //--------------------------------------------------------------------
95 //--------------------------------------------------------------------
96 template <class ImageType>
98 clitk::SliceBySliceRelativePositionFilter<ImageType>::
102 input = dynamic_cast<ImageType*>(itk::ProcessObject::GetInput(0));
103 object = dynamic_cast<ImageType*>(itk::ProcessObject::GetInput(1));
105 //--------------------------------------------------------------------
106 // Resample object to the same spacing than input
107 if (!clitk::HaveSameSpacing<ImageType, ImageType>(object, input)) {
108 StartNewStep("Resample object to the same spacing than input");
109 m_working_object = clitk::ResampleImageSpacing<ImageType>(object, input->GetSpacing());
110 StopCurrentStep<ImageType>(m_working_object);
114 m_working_object = object;
117 //--------------------------------------------------------------------
118 // Pad object to the same size than input
119 if (!clitk::HaveSameSizeAndSpacing<ImageType, ImageType>(m_working_object, input)) {
120 StartNewStep("Pad object to the same size than input");
121 m_working_object = clitk::EnlargeImageLike<ImageType>(m_working_object,
123 GetObjectBackgroundValue());
124 StopCurrentStep<ImageType>(m_working_object);
131 - extract vector of slices in input, in object
132 - slice by slice rel position
138 //--------------------------------------------------------------------
139 // Extract input slices
140 StartNewStep("Extract input slices");
141 writeImage<ImageType>(input, "beforex.mhd");
142 typedef clitk::ExtractSliceFilter<ImageType> ExtractSliceFilterType;
143 typename ExtractSliceFilterType::Pointer extractSliceFilter = ExtractSliceFilterType::New();
144 extractSliceFilter->SetInput(input);
145 extractSliceFilter->SetDirection(GetDirection());
146 extractSliceFilter->Update();
147 typedef typename ExtractSliceFilterType::SliceType SliceType;
148 std::vector<typename SliceType::Pointer> mInputSlices;
149 extractSliceFilter->GetOutputSlices(mInputSlices);
150 DD(mInputSlices.size());
151 StopCurrentStep<SliceType>(mInputSlices[0]);
153 //--------------------------------------------------------------------
154 // Extract object slices
155 StartNewStep("Extract object slices");
156 extractSliceFilter = ExtractSliceFilterType::New();
157 extractSliceFilter->SetInput(object);
158 extractSliceFilter->SetDirection(GetDirection());
159 extractSliceFilter->Update();
160 std::vector<typename SliceType::Pointer> mObjectSlices;
161 extractSliceFilter->GetOutputSlices(mObjectSlices);
162 DD(mObjectSlices.size());
163 StopCurrentStep<SliceType>(mObjectSlices[0]);
165 //--------------------------------------------------------------------
166 // Perform slice by slice relative position
167 StartNewStep("Perform slice by slice relative position");
168 for(unsigned int i=0; i<mInputSlices.size(); i++) {
170 // DD(mInputSlices[i]->GetOrigin());
171 // writeImage<SliceType>(mInputSlices[i], "inp"+clitk::toString(i)+".mhd");
173 // Select main CC in each object slice : this should be the main bronchus
174 mObjectSlices[i] = Labelize<SliceType>(mObjectSlices[i], 0, true, 1);
175 mObjectSlices[i] = KeepLabels<SliceType>(mObjectSlices[i], 0, 1, 1, 1, true);
178 typedef clitk::AddRelativePositionConstraintToLabelImageFilter<SliceType> RelPosFilterType;
179 typename RelPosFilterType::Pointer relPosFilter = RelPosFilterType::New();
180 relPosFilter->VerboseStepOff();
181 relPosFilter->WriteStepOff();
182 relPosFilter->SetCurrentStepBaseId(this->GetCurrentStepId());
183 relPosFilter->SetInput(mInputSlices[i]);
184 relPosFilter->SetInputObject(mObjectSlices[i]);
185 relPosFilter->SetOrientationType(this->GetOrientationType());
186 relPosFilter->SetIntermediateSpacing(this->GetIntermediateSpacing());
187 relPosFilter->SetResampleBeforeRelativePositionFilter(this->GetResampleBeforeRelativePositionFilter());
188 relPosFilter->SetFuzzyThreshold(this->GetFuzzyThreshold());
189 relPosFilter->AutoCropOff(); // important ! because we join the slices after this loop
190 relPosFilter->Update();
191 // writeImage<SliceType>(relPosFilter->GetOutput(), "inp-after"+clitk::toString(i)+".mhd");
192 mInputSlices[i] = relPosFilter->GetOutput();
194 DD(this->GetIntermediateSpacing());
195 DD(this->GetResampleBeforeRelativePositionFilter());
198 typedef itk::JoinSeriesImageFilter<SliceType, ImageType> JoinSeriesFilterType;
199 typename JoinSeriesFilterType::Pointer joinFilter = JoinSeriesFilterType::New();
200 joinFilter->SetOrigin(input->GetOrigin()[GetDirection()]);
201 joinFilter->SetSpacing(input->GetSpacing()[GetDirection()]);
202 for(unsigned int i=0; i<mInputSlices.size(); i++) {
203 // DD(mInputSlices[i]->GetLargestPossibleRegion().GetIndex());
204 // DD(mInputSlices[i]->GetLargestPossibleRegion().GetSize());
205 // DD(mInputSlices[i]->GetRequestedRegion().GetIndex());
206 // DD(mInputSlices[i]->GetRequestedRegion().GetSize());
207 joinFilter->PushBackInput(mInputSlices[i]);
208 //SetInput(i, mInputSlices[i]);
211 joinFilter->Update();
213 m_working_input = joinFilter->GetOutput();
216 DD(input->GetSpacing());
217 DD(input->GetOrigin());
218 DD(mInputSlices[0]->GetSpacing());
219 DD(mInputSlices[0]->GetOrigin());
220 DD(m_working_input->GetSpacing());
221 DD(m_working_input->GetOrigin());
222 // typename ImageType::PointType origin = m_working_input->GetOrigin();
223 // origin[GetDirection()] = input->GetOrigin()[GetDirection()];
224 // m_working_input->SetOrigin(origin);
225 // DD(m_working_input->GetOrigin());
226 StopCurrentStep<ImageType>(m_working_input);
228 //--------------------------------------------------------------------
229 //--------------------------------------------------------------------
230 // Final Step -> set output
231 this->SetNthOutput(0, m_working_input);
234 //--------------------------------------------------------------------