]> Creatis software - clitk.git/blob - segmentation/clitkExtractLymphStation_Supports.txx
Correct but when using LimitsWithTrachea (not taken into account)
[clitk.git] / segmentation / clitkExtractLymphStation_Supports.txx
1
2 #include <itkBinaryDilateImageFilter.h>
3 #include <itkMirrorPadImageFilter.h>
4
5 //--------------------------------------------------------------------
6 template <class ImageType>
7 void 
8 clitk::ExtractLymphStationsFilter<ImageType>::
9 ExtractStationSupports()
10 {
11   // Get initial Mediastinum
12   m_Working_Support = m_Mediastinum = this->GetAFDB()->template GetImage<MaskImageType>("Mediastinum", true);
13
14   // Consider sup/inf to Carina
15   double m_CarinaZ = FindCarina();
16   MaskImagePointer m_Support_Superior_to_Carina = 
17     clitk::CropImageRemoveLowerThan<MaskImageType>(m_Working_Support, 2, 
18                                                    m_CarinaZ, true, GetBackgroundValue());
19   MaskImagePointer m_Support_Inferior_to_Carina = 
20     clitk::CropImageRemoveGreaterThan<MaskImageType>(m_Working_Support, 2, 
21                                                      m_CarinaZ, true, GetBackgroundValue());
22   m_ListOfSupports["Support_Superior_to_Carina"] = m_Support_Superior_to_Carina;
23   m_ListOfSupports["Support_Inferior_to_Carina"] = m_Support_Inferior_to_Carina;
24   writeImage<MaskImageType>(m_Support_Inferior_to_Carina, "seg/Support_Inf_Carina.mha");
25   this->GetAFDB()->SetImageFilename("Support_Inf_Carina", "seg/Support_Inf_Carina.mha");
26   writeImage<MaskImageType>(m_Support_Superior_to_Carina, "seg/Support_Sup_Carina.mha");
27   this->GetAFDB()->SetImageFilename("Support_Sup_Carina", "seg/Support_Sup_Carina.mha");
28
29   // S1RL
30   Support_SupInf_S1RL();
31   Support_LeftRight_S1R_S1L();
32
33   // S2RL
34   Support_SupInf_S2R_S2L();
35   Support_LeftRight_S2R_S2L();
36
37   // S4RL
38   Support_SupInf_S4R_S4L();
39   Support_LeftRight_S4R_S4L();
40   
41   // Post limits of S1,S2,S4
42   Support_Post_S1S2S4();
43
44   // S3AP
45   Support_S3P();
46   Support_S3A();
47   
48   // S5, S6
49   Support_S5();
50   Support_S6();
51   
52   // Below Carina S7,8,9,10
53   m_ListOfSupports["S7"] = clitk::Clone<MaskImageType>(m_Support_Inferior_to_Carina);
54   m_ListOfSupports["S8"] = clitk::Clone<MaskImageType>(m_Support_Inferior_to_Carina);
55   m_ListOfSupports["S9"] = clitk::Clone<MaskImageType>(m_Support_Inferior_to_Carina);
56   m_ListOfSupports["S10"] = clitk::Clone<MaskImageType>(m_Support_Inferior_to_Carina);
57   m_ListOfSupports["S11"] = clitk::Clone<MaskImageType>(m_Support_Inferior_to_Carina);
58
59   // Store image filenames into AFDB 
60   writeImage<MaskImageType>(m_ListOfSupports["S1R"], "seg/Support_S1R.mha");
61   this->GetAFDB()->SetImageFilename("Support_S1R", "seg/Support_S1R.mha");
62   writeImage<MaskImageType>(m_ListOfSupports["S1L"], "seg/Support_S1L.mha");
63   this->GetAFDB()->SetImageFilename("Support_S1L", "seg/Support_S1L.mha");
64
65   writeImage<MaskImageType>(m_ListOfSupports["S2L"], "seg/Support_S2L.mha");
66   this->GetAFDB()->SetImageFilename("Support_S2L", "seg/Support_S2L.mha");
67   writeImage<MaskImageType>(m_ListOfSupports["S2R"], "seg/Support_S2R.mha");
68   this->GetAFDB()->SetImageFilename("Support_S2R", "seg/Support_S2R.mha");
69
70   writeImage<MaskImageType>(m_ListOfSupports["S3P"], "seg/Support_S3P.mha");
71   this->GetAFDB()->SetImageFilename("Support_S3P", "seg/Support_S3P.mha");
72   writeImage<MaskImageType>(m_ListOfSupports["S3A"], "seg/Support_S3A.mha");
73   this->GetAFDB()->SetImageFilename("Support_S3A", "seg/Support_S3A.mha");
74
75   writeImage<MaskImageType>(m_ListOfSupports["S4L"], "seg/Support_S4L.mha");
76   this->GetAFDB()->SetImageFilename("Support_S4L", "seg/Support_S4L.mha");
77   writeImage<MaskImageType>(m_ListOfSupports["S4R"], "seg/Support_S4R.mha");
78   this->GetAFDB()->SetImageFilename("Support_S4R", "seg/Support_S4R.mha");
79
80   writeImage<MaskImageType>(m_ListOfSupports["S5"], "seg/Support_S5.mha");
81   this->GetAFDB()->SetImageFilename("Support_S5", "seg/Support_S5.mha");
82   writeImage<MaskImageType>(m_ListOfSupports["S6"], "seg/Support_S6.mha");
83   this->GetAFDB()->SetImageFilename("Support_S6", "seg/Support_S6.mha");
84
85   writeImage<MaskImageType>(m_ListOfSupports["S7"], "seg/Support_S7.mha");
86   this->GetAFDB()->SetImageFilename("Support_S7", "seg/Support_S7.mha");
87
88   writeImage<MaskImageType>(m_ListOfSupports["S8"], "seg/Support_S8.mha");
89   this->GetAFDB()->SetImageFilename("Support_S8", "seg/Support_S8.mha");
90
91   writeImage<MaskImageType>(m_ListOfSupports["S9"], "seg/Support_S9.mha");
92   this->GetAFDB()->SetImageFilename("Support_S9", "seg/Support_S9.mha");
93
94   writeImage<MaskImageType>(m_ListOfSupports["S10"], "seg/Support_S10.mha");
95   this->GetAFDB()->SetImageFilename("Support_S10", "seg/Support_S10.mha");  
96
97   writeImage<MaskImageType>(m_ListOfSupports["S11"], "seg/Support_S11.mha");
98   this->GetAFDB()->SetImageFilename("Support_S11", "seg/Support_S11.mha");  
99   WriteAFDB();
100 }
101 //--------------------------------------------------------------------
102
103
104 //--------------------------------------------------------------------
105 template <class ImageType>
106 void 
107 clitk::ExtractLymphStationsFilter<ImageType>::
108 Support_SupInf_S1RL()
109 {
110   // Step : S1RL
111   StartNewStep("[Support] Sup-Inf S1RL");
112   /*
113     2R: Upper border: apex of the right lung and pleural space, and in
114     the midline, the upper border of the manubrium
115     
116     2L: Upper border: apex of the left lung and pleural space, and in the
117     midline, the upper border of the manubrium
118
119     => apex / manubrium = up Sternum
120   */
121   m_Working_Support = m_ListOfSupports["Support_Superior_to_Carina"];
122   MaskImagePointer Sternum = this->GetAFDB()->template GetImage <MaskImageType>("Sternum");
123   MaskImagePointType p;
124   p[0] = p[1] = p[2] =  0.0; // to avoid warning
125   clitk::FindExtremaPointInAGivenDirection<MaskImageType>(Sternum, GetBackgroundValue(), 2, false, p);
126   //  DD(p);
127   p[2] += Sternum->GetSpacing()[2]; // add one slice:  start just superiorly
128   MaskImagePointer S1RL = 
129     clitk::CropImageRemoveLowerThan<MaskImageType>(m_Working_Support, 2, 
130                                                    p[2], true, GetBackgroundValue());
131   m_Working_Support = 
132     clitk::CropImageRemoveGreaterThan<MaskImageType>(m_Working_Support, 2, 
133                                                      p[2], true, GetBackgroundValue());
134   m_ListOfSupports["S1RL"] = S1RL;
135 }
136 //--------------------------------------------------------------------
137
138
139 //--------------------------------------------------------------------
140 template <class ImageType>
141 void 
142 clitk::ExtractLymphStationsFilter<ImageType>::
143 Support_LeftRight_S1R_S1L()
144 {
145   // Step S1RL : Left-Right
146   StartNewStep("[Support] Left-Right S1R S1L");
147   std::vector<ImagePointType> A;
148   std::vector<ImagePointType> B;
149   // Search for centroid positions of trachea
150   MaskImagePointer Trachea = this->GetAFDB()->template GetImage <MaskImageType>("Trachea");
151   MaskImagePointer S1RL = m_ListOfSupports["S1RL"];
152   Trachea = clitk::ResizeImageLike<MaskImageType>(Trachea, S1RL, GetBackgroundValue());
153   std::vector<MaskSlicePointer> slices;
154   clitk::ExtractSlices<MaskImageType>(Trachea, 2, slices);
155   for(uint i=0; i<slices.size(); i++) {
156     slices[i] = Labelize<MaskSliceType>(slices[i], 0, false, 10);
157     std::vector<typename MaskSliceType::PointType> c;
158     clitk::ComputeCentroids<MaskSliceType>(slices[i], GetBackgroundValue(), c);
159     ImagePointType a,b;
160     clitk::PointsUtils<MaskImageType>::Convert2DTo3D(c[1], Trachea, i, a);
161     A.push_back(a);
162     b = a; 
163     b[1] += 50;
164     B.push_back(b);
165   }
166   clitk::WriteListOfLandmarks<MaskImageType>(A, "S1LR_A.txt");
167   clitk::WriteListOfLandmarks<MaskImageType>(B, "S1LR_B.txt");
168
169   // Clone support
170   MaskImagePointer S1R = clitk::Clone<MaskImageType>(S1RL);
171   MaskImagePointer S1L = clitk::Clone<MaskImageType>(S1RL);
172
173   // Right part
174   clitk::SliceBySliceSetBackgroundFromLineSeparation<MaskImageType>(S1R, A, B, 
175                                                                     GetBackgroundValue(), 0, -10);
176   S1R = clitk::AutoCrop<MaskImageType>(S1R, GetBackgroundValue());
177   m_ListOfSupports["S1R"] = S1R;
178
179   // Left part
180   clitk::SliceBySliceSetBackgroundFromLineSeparation<MaskImageType>(S1L, A, B, 
181                                                                     GetBackgroundValue(), 0, 10);
182   S1L = clitk::AutoCrop<MaskImageType>(S1L, GetBackgroundValue());
183   m_ListOfSupports["S1L"] = S1L;
184 }
185 //--------------------------------------------------------------------
186
187
188 //--------------------------------------------------------------------
189 template <class ImageType>
190 void 
191 clitk::ExtractLymphStationsFilter<ImageType>::
192 Support_SupInf_S2R_S2L()
193 {
194   // Step : S2RL Sup-Inf limits
195   /*
196     2R Lower border: intersection of caudal margin of innominate vein with
197     the trachea
198     2L Lower border: superior border of the aortic arch
199   */
200   StartNewStep("[Support] Sup-Inf S2RL");
201   m_Working_Support = m_ListOfSupports["Support_Superior_to_Carina"];
202   
203   // S2R Caudal Margin Of Left BrachiocephalicVein
204   MaskImagePointer BrachioCephalicVein = this->GetAFDB()->template GetImage<MaskImageType>("BrachioCephalicVein");
205   MaskImagePointType p;
206   clitk::FindExtremaPointInAGivenDirection<MaskImageType>(BrachioCephalicVein, GetBackgroundValue(), 2, true, p);
207
208   // I add slightly more than a slice --> NO !!
209   double CaudalMarginOfLeftBrachiocephalicVeinZ=p[2];//+ 1.1*m_Working_Support->GetSpacing()[2];
210
211   this->GetAFDB()->SetDouble("CaudalMarginOfLeftBrachiocephalicVeinZ", CaudalMarginOfLeftBrachiocephalicVeinZ);
212   MaskImagePointer S2R = 
213     clitk::CropImageRemoveLowerThan<MaskImageType>(m_Working_Support, 2, 
214                                                    CaudalMarginOfLeftBrachiocephalicVeinZ, true,
215                                                    GetBackgroundValue());
216   // S2L : Top Of Aortic Arch
217   MaskImagePointer Aorta = this->GetAFDB()->template GetImage<MaskImageType>("Aorta");
218   clitk::FindExtremaPointInAGivenDirection<MaskImageType>(Aorta, GetBackgroundValue(), 2, false, p);
219
220   // Save the TopOfAorticArchZ
221   this->GetAFDB()->SetDouble("TopOfAorticArchZ", p[2]);
222
223   // I substract slightly more than a slice to respect delineation
224   double TopOfAorticArchZ=p[2]- 1.1*m_Working_Support->GetSpacing()[2];
225   //  this->GetAFDB()->SetDouble("TopOfAorticArchZ", TopOfAorticArchZ);
226
227   MaskImagePointer S2L = 
228     clitk::CropImageRemoveLowerThan<MaskImageType>(m_Working_Support, 2, 
229                                                    TopOfAorticArchZ, true,
230                                                    GetBackgroundValue());
231
232   /*
233   // S2RL: Superior support, I use inferior part of S1RL
234   MaskImagePointer S1L = m_ListOfSupports["S1L"];
235   clitk::FindExtremaPointInAGivenDirection<MaskImageType>(S1L, GetBackgroundValue(), 2, true, p);
236   DD(p);
237   S2L = 
238     clitk::CropImageRemoveGreaterThan<MaskImageType>(S2L, 2, 
239                                                      p[2], true,
240                                                      GetBackgroundValue());
241
242   MaskImagePointer S1R = m_ListOfSupports["S1R"];
243   clitk::FindExtremaPointInAGivenDirection<MaskImageType>(S1R, GetBackgroundValue(), 2, true, p);
244   DD(p);
245   S2R = 
246     clitk::CropImageRemoveGreaterThan<MaskImageType>(S2R, 2, 
247                                                      p[2], true,
248                                                      GetBackgroundValue());          
249   */
250
251   // Superior limits, use Sternum (but not strictly inf to S1RL
252   MaskImagePointer Sternum = this->GetAFDB()->template GetImage <MaskImageType>("Sternum");
253   clitk::FindExtremaPointInAGivenDirection<MaskImageType>(Sternum, GetBackgroundValue(), 2, false, p);
254   // Add one slice
255   p[2] = p[2] +  m_Working_Support->GetSpacing()[2];
256   S2L = 
257     clitk::CropImageRemoveGreaterThan<MaskImageType>(S2L, 2, 
258                                                      p[2], true, GetBackgroundValue());
259   S2R = 
260     clitk::CropImageRemoveGreaterThan<MaskImageType>(S2R, 2, 
261                                                      p[2], true, GetBackgroundValue());
262
263   // The is the end
264   m_ListOfSupports["S2L"] = S2L;
265   m_ListOfSupports["S2R"] = S2R;
266 }
267 //--------------------------------------------------------------------
268
269
270
271 //--------------------------------------------------------------------
272 template <class ImageType>
273 void 
274 clitk::ExtractLymphStationsFilter<ImageType>::
275 Support_LeftRight_S2R_S2L()
276 {
277   // ---------------------------------------------------------------------------
278   /* Step : S2RL LeftRight
279      As for lymph node station 4R, 2R includes nodes extending to the
280      left lateral border of the trachea
281      Rod says:  "For station 2 there is a shift, dividing 2R from 2L, from midline
282      to the left paratracheal border."
283   */
284   StartNewStep("[Support] Separate 2R/2L according to Trachea");
285   MaskImagePointer S2R = m_ListOfSupports["S2R"];
286   MaskImagePointer S2L = m_ListOfSupports["S2L"];
287   S2R = LimitsWithTrachea(S2R, 0, 1, -10);
288   S2L = LimitsWithTrachea(S2L, 0, 1, 10);
289   S2R = clitk::AutoCrop<MaskImageType>(S2R, GetBackgroundValue());
290   S2L = clitk::AutoCrop<MaskImageType>(S2L, GetBackgroundValue());
291   m_ListOfSupports["S2R"] = S2R;
292   m_ListOfSupports["S2L"] = S2L;  
293   this->GetAFDB()->template ReleaseImage<MaskImageType>("Trachea");
294 }
295 //--------------------------------------------------------------------
296
297
298 //--------------------------------------------------------------------
299 template <class ImageType>
300 void 
301 clitk::ExtractLymphStationsFilter<ImageType>::
302 Support_SupInf_S4R_S4L()
303 {
304   // ---------------------------------------------------------------------------
305   /* Step : S4RL Sup-Inf
306      - start at the end of 2R and 2L
307      - stop ?
308      - 4R
309      Rod says : "The inferior border is at the lower border of the azygous vein."
310      Rod says : difficulties
311      (was : "ends at the upper lobe bronchus or where the right pulmonary artery
312      crosses the midline of the mediastinum ")
313      - 4L
314      Rod says : "The lower border is to upper margin of the left main pulmonary artery."
315      (was LLL bronchus)
316   */
317   StartNewStep("[Support] Sup-Inf limits of 4R/4L");
318
319   // Start from the support
320   MaskImagePointer S4RL = clitk::Clone<MaskImageType>(m_Working_Support);
321   MaskImagePointer S4R = clitk::Clone<MaskImageType>(S4RL);
322   MaskImagePointer S4L = clitk::Clone<MaskImageType>(S4RL);
323
324   // Keep only what is lower than S2
325   MaskImagePointer S2R = m_ListOfSupports["S2R"];
326   MaskImagePointer S2L = m_ListOfSupports["S2L"];
327   MaskImagePointType p;
328   // Right part
329   clitk::FindExtremaPointInAGivenDirection<MaskImageType>(S2R, GetBackgroundValue(), 
330                                                           2, true, p);
331   S4R = clitk::CropImageRemoveGreaterThan<MaskImageType>(S4R, 2, 
332                                                        p[2], true, GetBackgroundValue());
333   // Left part
334   clitk::FindExtremaPointInAGivenDirection<MaskImageType>(S2L, GetBackgroundValue(), 
335                                                           2, true, p);
336   S4L = clitk::CropImageRemoveGreaterThan<MaskImageType>(S4L, 2, 
337                                                          p[2], true, GetBackgroundValue());
338
339   // Get AzygousVein and limit according to LowerBorderAzygousVein
340   MaskImagePointer LowerBorderAzygousVein 
341     = this->GetAFDB()->template GetImage<MaskImageType>("LowerBorderAzygousVein");
342   std::vector<MaskImagePointType> c;
343   clitk::ComputeCentroids<MaskImageType>(LowerBorderAzygousVein, GetBackgroundValue(), c);
344   S4R = clitk::CropImageRemoveLowerThan<MaskImageType>(S4R, 2, 
345                                                        c[1][2], true, GetBackgroundValue());
346   S4R = clitk::AutoCrop<MaskImageType>(S4R, GetBackgroundValue());
347   m_ListOfSupports["S4R"] = S4R;
348
349
350   // Limit according to LeftPulmonaryArtery
351   MaskImagePointer LeftPulmonaryArtery 
352     = this->GetAFDB()->template GetImage<MaskImageType>("LeftPulmonaryArtery");
353   clitk::FindExtremaPointInAGivenDirection<MaskImageType>(LeftPulmonaryArtery, GetBackgroundValue(), 
354                                                           2, false, p);
355   S4L = clitk::CropImageRemoveLowerThan<MaskImageType>(S4L, 2, 
356                                                        p[2], true, GetBackgroundValue());
357   S4L = clitk::AutoCrop<MaskImageType>(S4L, GetBackgroundValue());
358   m_ListOfSupports["S4L"] = S4L;
359 }
360 //--------------------------------------------------------------------
361
362
363 //--------------------------------------------------------------------
364 template <class ImageType>
365 void 
366 clitk::ExtractLymphStationsFilter<ImageType>::
367 Support_LeftRight_S4R_S4L()
368 {
369   // ---------------------------------------------------------------------------
370   /* Step : S4RL LeftRight 
371      
372      - 4R: includes right paratracheal nodes, and pretracheal nodes
373      extending to the left lateral border of trachea
374      
375      - 4L: includes nodes to the left of the left lateral border of
376      the trachea, medial to the ligamentum arteriosum
377      
378      => same than 2RL
379   */
380   StartNewStep("[Support] Left Right separation of 4R/4L");
381
382   MaskImagePointer S4R = m_ListOfSupports["S4R"];
383   MaskImagePointer S4L = m_ListOfSupports["S4L"];
384   S4R = LimitsWithTrachea(S4R, 0, 1, -10);
385   S4L = LimitsWithTrachea(S4L, 0, 1, 10);
386   m_ListOfSupports["S4R"] = S4R;
387   m_ListOfSupports["S4L"] = S4L;
388 }
389 //--------------------------------------------------------------------
390
391
392 //--------------------------------------------------------------------
393 template <class ImageType>
394 typename clitk::ExtractLymphStationsFilter<ImageType>::MaskImagePointer
395 clitk::ExtractLymphStationsFilter<ImageType>::
396 LimitsWithTrachea(MaskImageType * input, int extremaDirection, int lineDirection, 
397                   double offset) 
398 {
399   MaskImagePointType min, max;
400   GetMinMaxBoundary<MaskImageType>(input, min, max);
401   return LimitsWithTrachea(input, extremaDirection, lineDirection, offset, max[2]);
402 }
403 template <class ImageType>
404 typename clitk::ExtractLymphStationsFilter<ImageType>::MaskImagePointer
405 clitk::ExtractLymphStationsFilter<ImageType>::
406 LimitsWithTrachea(MaskImageType * input, int extremaDirection, int lineDirection, 
407                   double offset, double maxSupPosition)
408 {
409   /*
410     Take the input mask, consider the trachea and limit according to
411     Left border of the trachea. Keep at Left or at Right according to
412     the offset
413   */
414   // Read the trachea
415   MaskImagePointer Trachea = this->GetAFDB()->template GetImage<MaskImageType>("Trachea");
416
417   // Find extrema post positions
418   std::vector<MaskImagePointType> tracheaLeftPositionsA;
419   std::vector<MaskImagePointType> tracheaLeftPositionsB;
420
421   // Crop Trachea only on the Sup-Inf axes, without autocrop
422   //  Trachea = clitk::ResizeImageLike<MaskImageType>(Trachea, input, GetBackgroundValue());
423   MaskImagePointType min, max;
424   GetMinMaxBoundary<MaskImageType>(input, min, max);
425   Trachea = clitk::CropImageAlongOneAxis<MaskImageType>(Trachea, 2, min[2], max[2], 
426                                                         false, GetBackgroundValue()); 
427   
428   // Select the main CCL (because of bronchus)
429   Trachea = SliceBySliceKeepMainCCL<MaskImageType>(Trachea, GetBackgroundValue(), GetForegroundValue());
430
431   // Slice by slice, build the separation line 
432   clitk::SliceBySliceBuildLineSegmentAccordingToExtremaPosition<MaskImageType>(Trachea, 
433                                                                                GetBackgroundValue(), 2, 
434                                                                                extremaDirection, false, // Left
435                                                                                lineDirection, // Vertical line 
436                                                                                -1, // margins 
437                                                                                tracheaLeftPositionsA, 
438                                                                                tracheaLeftPositionsB);
439   // Do not consider trachea above the limit
440   int indexMax=tracheaLeftPositionsA.size();
441   for(uint i=0; i<tracheaLeftPositionsA.size(); i++) {
442     if (tracheaLeftPositionsA[i][2] > maxSupPosition) {
443       indexMax = i;
444       i = tracheaLeftPositionsA.size(); // stop loop
445     }
446   }  
447   tracheaLeftPositionsA.erase(tracheaLeftPositionsA.begin()+indexMax, tracheaLeftPositionsA.end());
448   tracheaLeftPositionsB.erase(tracheaLeftPositionsB.begin()+indexMax, tracheaLeftPositionsB.end());
449
450   // Cut post to this line 
451   clitk::SliceBySliceSetBackgroundFromLineSeparation<MaskImageType>(input, 
452                                                                     tracheaLeftPositionsA,
453                                                                     tracheaLeftPositionsB,
454                                                                     GetBackgroundValue(), 
455                                                                     extremaDirection, offset); 
456   MaskImagePointer output = clitk::AutoCrop<MaskImageType>(input, GetBackgroundValue());
457   return output;
458 }
459 //--------------------------------------------------------------------
460
461
462 //--------------------------------------------------------------------
463 template <class ImageType>
464 void
465 clitk::ExtractLymphStationsFilter<ImageType>::
466 Support_Post_S1S2S4()
467 {
468   StartNewStep("[Support] Post limits of S1RL, S2RL, S4RL");
469   
470   double m_ApexOfTheChest = FindApexOfTheChest();
471   
472   // Post limits with Trachea 
473   MaskImagePointer S1R = m_ListOfSupports["S1R"];
474   MaskImagePointer S1L = m_ListOfSupports["S1L"];
475   MaskImagePointer S2R = m_ListOfSupports["S2R"];
476   MaskImagePointer S2L = m_ListOfSupports["S2L"];
477   MaskImagePointer S4R = m_ListOfSupports["S4R"];
478   MaskImagePointer S4L = m_ListOfSupports["S4L"];
479   m_ListOfSupports["S1R"] = LimitsWithTrachea(S1L, 1, 0, -10, m_ApexOfTheChest);
480   m_ListOfSupports["S1L"] = LimitsWithTrachea(S1R, 1, 0, -10, m_ApexOfTheChest);
481   m_ListOfSupports["S2R"] = LimitsWithTrachea(S2R, 1, 0, -10, m_ApexOfTheChest);
482   m_ListOfSupports["S2L"] = LimitsWithTrachea(S2L, 1, 0, -10, m_ApexOfTheChest);
483   m_ListOfSupports["S4R"] = LimitsWithTrachea(S4R, 1, 0, -10, m_ApexOfTheChest);
484   m_ListOfSupports["S4L"] = LimitsWithTrachea(S4L, 1, 0, -10, m_ApexOfTheChest);
485 }
486 //--------------------------------------------------------------------
487
488
489 //--------------------------------------------------------------------
490 template <class ImageType>
491 void
492 clitk::ExtractLymphStationsFilter<ImageType>::
493 Support_S3P()
494 {
495   StartNewStep("[Support] Ant limits of S3P and Post limits of S1RL, S2RL, S4RL");
496   
497   // Initial S3P support
498   MaskImagePointer S3P = clitk::Clone<MaskImageType>(m_ListOfSupports["Support_Superior_to_Carina"]);
499
500   // Stop at Lung Apex
501   double m_ApexOfTheChest = FindApexOfTheChest();
502   S3P = 
503     clitk::CropImageRemoveGreaterThan<MaskImageType>(S3P, 2, 
504                                                      m_ApexOfTheChest, true,
505                                                      GetBackgroundValue());
506   // Ant limits with Trachea
507   S3P = LimitsWithTrachea(S3P, 1, 0, 10);
508   m_ListOfSupports["S3P"] = S3P;
509 }
510 //--------------------------------------------------------------------
511
512
513 //--------------------------------------------------------------------
514 template <class ImageType>
515 void
516 clitk::ExtractLymphStationsFilter<ImageType>::
517 Support_S3A()
518 {
519   StartNewStep("[Support] Sup-Inf and Post limits for S3A");
520
521   // Initial S3A support
522   MaskImagePointer S3A = clitk::Clone<MaskImageType>(m_ListOfSupports["Support_Superior_to_Carina"]);
523
524   // Stop at Lung Apex or like S2/S1 (upper border Sternum - manubrium) ?
525
526   //double m_ApexOfTheChest = FindApexOfTheChest();
527
528   MaskImagePointer Sternum = this->GetAFDB()->template GetImage <MaskImageType>("Sternum");
529   MaskImagePointType p;
530   p[0] = p[1] = p[2] =  0.0; // to avoid warning
531   clitk::FindExtremaPointInAGivenDirection<MaskImageType>(Sternum, GetBackgroundValue(), 2, false, p);
532   p[2] += Sternum->GetSpacing()[2]; // we add one slice to stop 3A at the same slice than Sternum stop
533   S3A = 
534     clitk::CropImageRemoveGreaterThan<MaskImageType>(S3A, 2, 
535                                                      //m_ApexOfTheChest
536                                                      p[2], true,
537                                                      GetBackgroundValue());
538   // Ant limits with Trachea
539   S3A = LimitsWithTrachea(S3A, 1, 0, -10);
540   m_ListOfSupports["S3A"] = S3A;  
541 }
542 //--------------------------------------------------------------------
543
544
545 //--------------------------------------------------------------------
546 template <class ImageType>
547 void
548 clitk::ExtractLymphStationsFilter<ImageType>::
549 Support_S5()
550 {
551   StartNewStep("[Support] Sup-Inf limits S5 with Aorta and MainPulmonaryArtery");
552
553   // Initial S5 support
554   MaskImagePointer S5 = 
555     clitk::Clone<MaskImageType>(this->GetAFDB()->template GetImage<MaskImageType>("Mediastinum", true));
556
557   // Sup limits with Aorta
558   double sup = FindInferiorBorderOfAorticArch();
559   
560   // Inf limits with "upper rim of the left main pulmonary artery"
561   // For the moment only, it will change.
562   MaskImagePointer MainPulmonaryArtery = this->GetAFDB()->template GetImage<MaskImageType>("MainPulmonaryArtery");
563   MaskImagePointType p;
564   p[0] = p[1] = p[2] =  0.0; // to avoid warning
565   clitk::FindExtremaPointInAGivenDirection<MaskImageType>(MainPulmonaryArtery, GetBackgroundValue(), 2, false, p);
566   p[2] += MainPulmonaryArtery->GetSpacing()[2];
567   
568   // Cut Sup/Inf
569   S5 = clitk::CropImageAlongOneAxis<MaskImageType>(S5, 2, p[2], sup, true, GetBackgroundValue());
570
571   m_ListOfSupports["S5"] = S5; 
572 }
573 //--------------------------------------------------------------------
574
575 //--------------------------------------------------------------------
576 template <class ImageType>
577 void
578 clitk::ExtractLymphStationsFilter<ImageType>::
579 Support_S6()
580 {
581   StartNewStep("[Support] Sup-Inf limits S6 with aorta");
582
583   // Initial S6 support like S3A
584   MaskImagePointer S6 = clitk::Clone<MaskImageType>(m_ListOfSupports["S3A"]);
585
586   // Inf Sup limits with Aorta
587   double sup = FindSuperiorBorderOfAorticArch();
588   double inf = FindInferiorBorderOfAorticArch();
589   
590   // Cut Sup/Inf
591   S6 = clitk::CropImageAlongOneAxis<MaskImageType>(S6, 2, inf, sup, true, GetBackgroundValue());
592
593   m_ListOfSupports["S6"] = S6;  
594 }
595 //--------------------------------------------------------------------
596