2 //--------------------------------------------------------------------
3 template <class TImageType>
5 clitk::ExtractLymphStationsFilter<TImageType>::
6 ExtractStation_7_SetDefaultValues()
8 SetFuzzyThresholdForS7("Bronchi", 0.1);
9 SetFuzzyThresholdForS7("LeftSuperiorPulmonaryVein", 0.3);
10 SetFuzzyThresholdForS7("RightSuperiorPulmonaryVein", 0.2);
11 SetFuzzyThresholdForS7("RightPulmonaryArtery", 0.3);
12 SetFuzzyThresholdForS7("LeftPulmonaryArtery", 0.5);
13 SetFuzzyThresholdForS7("SVC", 0.2);
15 //--------------------------------------------------------------------
17 //--------------------------------------------------------------------
18 template <class TImageType>
20 clitk::ExtractLymphStationsFilter<TImageType>::
21 SetFuzzyThresholdForS7(std::string tag, double value)
23 m_FuzzyThresholdForS7[tag] = value;
25 //--------------------------------------------------------------------
28 //--------------------------------------------------------------------
29 template <class TImageType>
31 clitk::ExtractLymphStationsFilter<TImageType>::
32 GetFuzzyThresholdForS7(std::string tag)
34 if (m_FuzzyThresholdForS7.find(tag) != m_FuzzyThresholdForS7.end()) {
35 return m_FuzzyThresholdForS7[tag];
38 clitkExceptionMacro("Could not find options "+tag+" in the m_FuzzyThresholdForS7 list");
41 //--------------------------------------------------------------------
44 //--------------------------------------------------------------------
45 template <class TImageType>
47 clitk::ExtractLymphStationsFilter<TImageType>::
48 ExtractStation_7_SI_Limits()
50 StartNewStep("[Station7] Inf/Sup mediastinum limits with carina/LLLBronchus");
52 MaskImagePointer Trachea = GetAFDB()->template GetImage <MaskImageType>("Trachea");
54 // We suppoe that CarinaZ was already computed (S8)
55 double m_CarinaZ = GetAFDB()->GetDouble("CarinaZ");
57 // double m_OriginOfRightMiddleLobeBronchusZ = GetAFDB()->GetPoint3D("OriginOfRightMiddleLobeBronchus", 2);
58 // DD(m_OriginOfRightMiddleLobeBronchusZ);
59 MaskImagePointer UpperBorderOfLLLBronchus = GetAFDB()->template GetImage<MaskImageType>("UpperBorderOfLLLBronchus");
61 // Search most inf point (WHY ? IS IT THE RIGHT STRUCTURE ??)
62 MaskImagePointType ps = UpperBorderOfLLLBronchus->GetOrigin(); // initialise to avoid warning
63 clitk::FindExtremaPointInAGivenDirection<MaskImageType>(UpperBorderOfLLLBronchus, GetBackgroundValue(), 2, true, ps);
64 double m_UpperBorderOfLLLBronchusZ = ps[2];
67 std::vector<MaskImagePointType> centroids;
68 clitk::ComputeCentroids<MaskImageType>(UpperBorderOfLLLBronchus, GetBackgroundValue(), centroids);
69 double m_UpperBorderOfLLLBronchusZ = centroids[1][2];
70 DD(m_UpperBorderOfLLLBronchusZ)
75 clitk::CropImageAlongOneAxis<MaskImageType>(m_Working_Support, 2,
76 m_UpperBorderOfLLLBronchusZ,
78 GetBackgroundValue());
81 clitk::CropImageAlongOneAxis<MaskImageType>(Trachea, 2,
82 m_UpperBorderOfLLLBronchusZ,
84 GetBackgroundValue());
86 StopCurrentStep<MaskImageType>(m_Working_Support);
87 m_ListOfStations["7"] = m_Working_Support;
89 //--------------------------------------------------------------------
92 //--------------------------------------------------------------------
93 template <class TImageType>
95 clitk::ExtractLymphStationsFilter<TImageType>::
96 ExtractStation_7_RL_Limits()
98 // ----------------------------------------------------------------
99 StartNewStep("[Station7] Limits with bronchus : RightTo the left bronchus");
101 // First consider bronchus and keep the main CCL by slice
102 m_RightBronchus = GetAFDB()->template GetImage <MaskImageType>("RightBronchus");
103 m_LeftBronchus = GetAFDB()->template GetImage <MaskImageType>("LeftBronchus");
105 // Extract slices, Label, compute centroid, keep most central connected component
106 std::vector<MaskSlicePointer> slices_leftbronchus;
107 std::vector<MaskSlicePointer> slices_rightbronchus;
108 clitk::ExtractSlices<MaskImageType>(m_LeftBronchus, 2, slices_leftbronchus);
109 clitk::ExtractSlices<MaskImageType>(m_RightBronchus, 2, slices_rightbronchus);
112 for(uint i=0; i<slices_leftbronchus.size(); i++) {
113 slices_leftbronchus[i] = Labelize<MaskSliceType>(slices_leftbronchus[i], 0, false, 10);
114 std::vector<typename MaskSliceType::PointType> c;
115 clitk::ComputeCentroids<MaskSliceType>(slices_leftbronchus[i], GetBackgroundValue(), c);
117 double most_at_left = c[1][0];
118 int most_at_left_index=1;
119 for(uint j=1; j<c.size(); j++) {
120 if (c[j][0] < most_at_left) {
121 most_at_left = c[j][0];
122 most_at_left_index = j;
125 // Put all other CCL to Background
126 slices_leftbronchus[i] =
127 clitk::Binarize<MaskSliceType>(slices_leftbronchus[i], most_at_left_index,
128 most_at_left_index, GetBackgroundValue(), GetForegroundValue());
132 for(uint i=0; i<slices_rightbronchus.size(); i++) {
133 slices_rightbronchus[i] = Labelize<MaskSliceType>(slices_rightbronchus[i], 0, false, 10);
134 std::vector<typename MaskSliceType::PointType> c;
135 clitk::ComputeCentroids<MaskSliceType>(slices_rightbronchus[i], GetBackgroundValue(), c);
137 double most_at_right = c[1][0];
138 int most_at_right_index=1;
139 for(uint j=1; j<c.size(); j++) {
140 if (c[j][0] > most_at_right) {
141 most_at_right = c[j][0];
142 most_at_right_index = j;
145 // Put all other CCL to Background
146 slices_rightbronchus[i] =
147 clitk::Binarize<MaskSliceType>(slices_rightbronchus[i], most_at_right_index,
148 most_at_right_index, GetBackgroundValue(), GetForegroundValue());
153 m_LeftBronchus = clitk::JoinSlices<MaskImageType>(slices_leftbronchus, m_LeftBronchus, 2);
154 m_RightBronchus = clitk::JoinSlices<MaskImageType>(slices_rightbronchus, m_RightBronchus, 2);
156 writeImage<MaskImageType>(m_LeftBronchus, "step-left.mhd");
157 writeImage<MaskImageType>(m_RightBronchus, "step-right.mhd");
160 clitk::SliceBySliceRelativePosition<MaskImageType>(m_Working_Support, m_LeftBronchus, 2,
161 GetFuzzyThresholdForS7("Bronchi"), "RightTo",
163 StopCurrentStep<MaskImageType>(m_Working_Support);
166 // ----------------------------------------------------------------
167 StartNewStep("[Station7] Limits with bronchus : LeftTo the right bronchus");
169 clitk::SliceBySliceRelativePosition<MaskImageType>(m_Working_Support, m_RightBronchus, 2,
170 GetFuzzyThresholdForS7("Bronchi"), "LeftTo",
172 StopCurrentStep<MaskImageType>(m_Working_Support);
175 // ----------------------------------------------------------------
176 StartNewStep("[Station7] Limits with LeftSuperiorPulmonaryVein");
178 MaskImagePointer LeftSuperiorPulmonaryVein = GetAFDB()->template GetImage<MaskImageType>("LeftSuperiorPulmonaryVein");
179 typedef SliceBySliceRelativePositionFilter<MaskImageType> SliceRelPosFilterType;
180 typename SliceRelPosFilterType::Pointer sliceRelPosFilter = SliceRelPosFilterType::New();
181 sliceRelPosFilter->SetInput(m_Working_Support);
182 sliceRelPosFilter->SetInputObject(LeftSuperiorPulmonaryVein);
183 sliceRelPosFilter->SetDirection(2);
184 sliceRelPosFilter->SetFuzzyThreshold(GetFuzzyThresholdForS7("LeftSuperiorPulmonaryVein"));
185 sliceRelPosFilter->AddOrientationTypeString("NotLeftTo");
186 sliceRelPosFilter->AddOrientationTypeString("NotAntTo");
187 sliceRelPosFilter->SetIntermediateSpacingFlag(true);
188 sliceRelPosFilter->SetIntermediateSpacing(3);
189 sliceRelPosFilter->SetUniqueConnectedComponentBySlice(false);
190 sliceRelPosFilter->SetAutoCropFlag(false);
191 sliceRelPosFilter->IgnoreEmptySliceObjectFlagOn();
192 sliceRelPosFilter->Update();
193 m_Working_Support = sliceRelPosFilter->GetOutput();
194 StopCurrentStep<MaskImageType>(m_Working_Support);
196 catch (clitk::ExceptionObject e) {
197 std::cout << "Not LeftSuperiorPulmonaryVein, skip" << std::endl;
200 // ----------------------------------------------------------------
201 StartNewStep("[Station7] Limits with RightSuperiorPulmonaryVein");
203 MaskImagePointer RightSuperiorPulmonaryVein = GetAFDB()->template GetImage<MaskImageType>("RightSuperiorPulmonaryVein");
204 typedef SliceBySliceRelativePositionFilter<MaskImageType> SliceRelPosFilterType;
205 typename SliceRelPosFilterType::Pointer sliceRelPosFilter = SliceRelPosFilterType::New();
206 sliceRelPosFilter->SetInput(m_Working_Support);
207 sliceRelPosFilter->SetInputObject(RightSuperiorPulmonaryVein);
208 sliceRelPosFilter->SetDirection(2);
209 sliceRelPosFilter->SetFuzzyThreshold(GetFuzzyThresholdForS7("RightSuperiorPulmonaryVein"));
210 sliceRelPosFilter->AddOrientationTypeString("NotRightTo");
211 sliceRelPosFilter->AddOrientationTypeString("NotAntTo");
212 sliceRelPosFilter->AddOrientationTypeString("NotPostTo");
213 sliceRelPosFilter->SetIntermediateSpacingFlag(true);
214 sliceRelPosFilter->SetIntermediateSpacing(3);
215 sliceRelPosFilter->SetUniqueConnectedComponentBySlice(false);
216 sliceRelPosFilter->SetAutoCropFlag(false);
217 sliceRelPosFilter->IgnoreEmptySliceObjectFlagOn();
218 sliceRelPosFilter->Update();
219 m_Working_Support = sliceRelPosFilter->GetOutput();
220 StopCurrentStep<MaskImageType>(m_Working_Support);
222 catch (clitk::ExceptionObject e) {
223 std::cout << "Not RightSuperiorPulmonaryVein, skip" << std::endl;
226 // ----------------------------------------------------------------
227 StartNewStep("[Station7] Limits with RightPulmonaryArtery");
228 MaskImagePointer RightPulmonaryArtery = GetAFDB()->template GetImage<MaskImageType>("RightPulmonaryArtery");
229 typedef SliceBySliceRelativePositionFilter<MaskImageType> SliceRelPosFilterType;
230 typename SliceRelPosFilterType::Pointer sliceRelPosFilter = SliceRelPosFilterType::New();
231 sliceRelPosFilter->SetInput(m_Working_Support);
232 sliceRelPosFilter->SetInputObject(RightPulmonaryArtery);
233 sliceRelPosFilter->SetDirection(2);
234 sliceRelPosFilter->SetFuzzyThreshold(GetFuzzyThresholdForS7("RightPulmonaryArtery"));
235 sliceRelPosFilter->AddOrientationTypeString("NotAntTo");
236 sliceRelPosFilter->SetIntermediateSpacingFlag(true);
237 sliceRelPosFilter->SetIntermediateSpacing(3);
238 sliceRelPosFilter->SetUniqueConnectedComponentBySlice(false);
239 sliceRelPosFilter->SetAutoCropFlag(false);
240 sliceRelPosFilter->IgnoreEmptySliceObjectFlagOn();
241 sliceRelPosFilter->Update();
242 m_Working_Support = sliceRelPosFilter->GetOutput();
243 StopCurrentStep<MaskImageType>(m_Working_Support);
245 // ----------------------------------------------------------------
246 StartNewStep("[Station7] Limits with LeftPulmonaryArtery");
247 MaskImagePointer LeftPulmonaryArtery = GetAFDB()->template GetImage<MaskImageType>("LeftPulmonaryArtery");
248 sliceRelPosFilter = SliceRelPosFilterType::New();
249 sliceRelPosFilter->SetInput(m_Working_Support);
250 sliceRelPosFilter->SetInputObject(LeftPulmonaryArtery);
251 sliceRelPosFilter->SetDirection(2);
252 sliceRelPosFilter->SetFuzzyThreshold(GetFuzzyThresholdForS7("LeftPulmonaryArtery"));
253 sliceRelPosFilter->AddOrientationTypeString("NotAntTo");
254 sliceRelPosFilter->SetIntermediateSpacingFlag(true);
255 sliceRelPosFilter->SetIntermediateSpacing(3);
256 sliceRelPosFilter->SetUniqueConnectedComponentBySlice(false);
257 sliceRelPosFilter->SetAutoCropFlag(false);
258 sliceRelPosFilter->IgnoreEmptySliceObjectFlagOn();
259 sliceRelPosFilter->Update();
260 m_Working_Support = sliceRelPosFilter->GetOutput();
261 StopCurrentStep<MaskImageType>(m_Working_Support);
263 StartNewStep("[Station7] Limits with SVC");
264 MaskImagePointer SVC = GetAFDB()->template GetImage<MaskImageType>("SVC");
265 sliceRelPosFilter = SliceRelPosFilterType::New();
266 sliceRelPosFilter->SetInput(m_Working_Support);
267 sliceRelPosFilter->SetInputObject(SVC);
268 sliceRelPosFilter->SetDirection(2);
269 sliceRelPosFilter->SetFuzzyThreshold(GetFuzzyThresholdForS7("SVC"));
270 sliceRelPosFilter->AddOrientationTypeString("NotRightTo");
271 sliceRelPosFilter->AddOrientationTypeString("NotAntTo");
272 sliceRelPosFilter->SetIntermediateSpacingFlag(true);
273 sliceRelPosFilter->SetIntermediateSpacing(3);
274 sliceRelPosFilter->SetUniqueConnectedComponentBySlice(false);
275 sliceRelPosFilter->SetAutoCropFlag(true);
276 sliceRelPosFilter->IgnoreEmptySliceObjectFlagOn();
277 sliceRelPosFilter->Update();
278 m_Working_Support = sliceRelPosFilter->GetOutput();
279 StopCurrentStep<MaskImageType>(m_Working_Support);
282 m_ListOfStations["7"] = m_Working_Support;
284 //--------------------------------------------------------------------
287 //--------------------------------------------------------------------
288 template <class TImageType>
290 clitk::ExtractLymphStationsFilter<TImageType>::
291 ExtractStation_7_Posterior_Limits()
293 StartNewStep("[Station7] Posterior limits -> must be AntTo post wall of the bronchi (OLD CLASSIF)");
295 // Search for points that are the most left/post/ant and most
296 // right/post/ant of the left and right bronchus
298 // extract, loop slices, label/keep, find extrema x 3
299 /* FindExtremaPointsInBronchus(m_LeftBronchus, 0, 15, m_RightMostInLeftBronchus,
300 m_AntMostInLeftBronchus, m_PostMostInLeftBronchus);
301 FindExtremaPointsInBronchus(m_RightBronchus, 1, 15, m_LeftMostInRightBronchus,
302 m_AntMostInRightBronchus, m_PostMostInRightBronchus);
305 // First cut bronchus to the correct sup/inf support
306 MaskImagePointer RightBronchus = clitk::ResizeImageLike<MaskImageType>(m_RightBronchus, m_Working_Support, GetBackgroundValue());
307 MaskImagePointer LeftBronchus = clitk::ResizeImageLike<MaskImageType>(m_LeftBronchus, m_Working_Support, GetBackgroundValue());
309 // Find extrema points
310 FindExtremaPointsInBronchus(RightBronchus, 0, 10, m_LeftMostInRightBronchus,
311 m_AntMostInRightBronchus, m_PostMostInRightBronchus);
313 FindExtremaPointsInBronchus(LeftBronchus, 1, 10, m_RightMostInLeftBronchus,
314 m_AntMostInLeftBronchus, m_PostMostInLeftBronchus);
319 std::ofstream osrl; openFileForWriting(osrl, "osrl.txt"); osrl << "LANDMARKS1" << std::endl;
320 std::ofstream osal; openFileForWriting(osal, "osal.txt"); osal << "LANDMARKS1" << std::endl;
321 std::ofstream ospl; openFileForWriting(ospl, "ospl.txt"); ospl << "LANDMARKS1" << std::endl;
322 std::ofstream osrr; openFileForWriting(osrr, "osrr.txt"); osrr << "LANDMARKS1" << std::endl;
323 std::ofstream osar; openFileForWriting(osar, "osar.txt"); osar << "LANDMARKS1" << std::endl;
324 std::ofstream ospr; openFileForWriting(ospr, "ospr.txt"); ospr << "LANDMARKS1" << std::endl;
326 for(uint i=0; i<m_RightMostInLeftBronchus.size(); i++) {
327 osrl << i << " " << m_RightMostInLeftBronchus[i][0] << " " << m_RightMostInLeftBronchus[i][1]
328 << " " << m_RightMostInLeftBronchus[i][2] << " 0 0 " << std::endl;
329 osal << i << " " << m_AntMostInLeftBronchus[i][0] << " " << m_AntMostInLeftBronchus[i][1]
330 << " " << m_AntMostInLeftBronchus[i][2] << " 0 0 " << std::endl;
331 ospl << i << " " << m_PostMostInLeftBronchus[i][0] << " " << m_PostMostInLeftBronchus[i][1]
332 << " " << m_PostMostInLeftBronchus[i][2] << " 0 0 " << std::endl;
335 for(uint i=0; i<m_LeftMostInRightBronchus.size(); i++) {
336 osrr << i << " " << m_LeftMostInRightBronchus[i][0] << " " << m_LeftMostInRightBronchus[i][1]
337 << " " << m_LeftMostInRightBronchus[i][2] << " 0 0 " << std::endl;
338 osar << i << " " << m_AntMostInRightBronchus[i][0] << " " << m_AntMostInRightBronchus[i][1]
339 << " " << m_AntMostInRightBronchus[i][2] << " 0 0 " << std::endl;
340 ospr << i << " " << m_PostMostInRightBronchus[i][0] << " " << m_PostMostInRightBronchus[i][1]
341 << " " << m_PostMostInRightBronchus[i][2] << " 0 0 " << std::endl;
350 clitk::SliceBySliceSetBackgroundFromLineSeparation<MaskImageType>(m_Working_Support,
351 m_PostMostInRightBronchus,
352 m_PostMostInLeftBronchus,
353 GetBackgroundValue(), 1, -10);
354 // If needed -> can do the same with AntMost.
357 StopCurrentStep<MaskImageType>(m_Working_Support);
358 m_ListOfStations["7"] = m_Working_Support;
360 //--------------------------------------------------------------------
362 //--------------------------------------------------------------------
363 template <class ImageType>
365 clitk::ExtractLymphStationsFilter<ImageType>::
366 ExtractStation_7_Remove_Structures()
369 //--------------------------------------------------------------------
370 StartNewStep("[Station7] remove some structures");
372 Remove_Structures("AzygousVein");
373 Remove_Structures("Aorta");
374 Remove_Structures("Esophagus");
375 Remove_Structures("RightPulmonaryArtery");
376 Remove_Structures("LeftPulmonaryArtery");
377 Remove_Structures("LeftSuperiorPulmonaryVein");
378 Remove_Structures("PulmonaryTrunk");
379 Remove_Structures("VertebralBody");
382 StopCurrentStep<MaskImageType>(m_Working_Support);
383 m_ListOfStations["7"] = m_Working_Support;
386 //--------------------------------------------------------------------