]> Creatis software - clitk.git/blob - segmentation/clitkExtractLymphStation_2RL.txx
Merge branch 'master' of /home/dsarrut/clitk3.server
[clitk.git] / segmentation / clitkExtractLymphStation_2RL.txx
1
2
3 // vtk
4 #include <vtkAppendPolyData.h>
5 #include <vtkPolyDataWriter.h>
6 #include <vtkCellArray.h>
7
8 // clitk
9 #include "clitkMeshToBinaryImageFilter.h"
10
11 // itk
12 #include <itkImageDuplicator.h>
13
14 //--------------------------------------------------------------------
15 template <class ImageType>
16 void 
17 clitk::ExtractLymphStationsFilter<ImageType>::
18 ExtractStation_2RL_SetDefaultValues()
19 {
20   SetFuzzyThreshold("2RL", "CommonCarotidArtery", 0.7);
21   SetFuzzyThreshold("2RL", "BrachioCephalicArtery", 0.7);
22   SetFuzzyThreshold("2RL", "BrachioCephalicVein", 0.3);
23   SetFuzzyThreshold("2RL", "Aorta", 0.7);
24   SetFuzzyThreshold("2RL", "SubclavianArteryRight", 0.5);
25   SetFuzzyThreshold("2RL", "SubclavianArteryLeft", 0.8);
26 }
27 //--------------------------------------------------------------------
28
29
30 //--------------------------------------------------------------------
31 template <class TImageType>
32 void 
33 clitk::ExtractLymphStationsFilter<TImageType>::
34 ExtractStation_2RL()
35 {
36   if ((!CheckForStation("2R")) && (!CheckForStation("2L"))) return;
37
38   ExtractStation_2RL_SI_Limits();
39   ExtractStation_2RL_Post_Limits();
40   
41   ExtractStation_2RL_Ant_Limits2();
42   //ExtractStation_2RL_Ant_Limits(); 
43   
44   ExtractStation_2RL_LR_Limits(); 
45   ExtractStation_2RL_Remove_Structures(); 
46   ExtractStation_2RL_SeparateRL(); 
47   
48   // Store image filenames into AFDB 
49   writeImage<MaskImageType>(m_ListOfStations["2R"], "seg/Station2R.mhd");
50   writeImage<MaskImageType>(m_ListOfStations["2L"], "seg/Station2L.mhd");
51   GetAFDB()->SetImageFilename("Station2R", "seg/Station2R.mhd"); 
52   GetAFDB()->SetImageFilename("Station2L", "seg/Station2L.mhd"); 
53   WriteAFDB(); 
54
55 }
56 //--------------------------------------------------------------------
57
58
59 //--------------------------------------------------------------------
60 template <class ImageType>
61 void 
62 clitk::ExtractLymphStationsFilter<ImageType>::
63 ExtractStation_2RL_SI_Limits() 
64 {
65   // Apex of the chest or Sternum & Carina.
66   StartNewStep("[Station 2RL] Inf/Sup limits with Sternum and TopOfAorticArch/CaudalMarginOfLeftBrachiocephalicVein");
67
68   /* Rod says: "For the inferior border, unlike in Atlas – UM, there
69    is now a difference between 2R and 2L.  2R stops at the
70    intersection of the caudal margin of the innominate vein with the
71    trachea.  2L extends less inferiorly to the superior border of the
72    aortic arch." */
73
74   /* Get TopOfAorticArch and CaudalMarginOfLeftBrachiocephalicVein 
75      - TopOfAorticArch -> can be obtain from Aorta -> most sup part.  
76      - CaudalMarginOfLeftBrachiocephalicVein -> must inf part of BrachicephalicVein
77    */
78   MaskImagePointer Aorta = GetAFDB()->template GetImage<MaskImageType>("Aorta");
79   MaskImagePointType p = Aorta->GetOrigin(); // initialise to avoid warning 
80   clitk::FindExtremaPointInAGivenDirection<MaskImageType>(Aorta, GetBackgroundValue(), 2, false, p);
81   double TopOfAorticArchZ=p[2];
82   GetAFDB()->SetDouble("TopOfAorticArchZ", TopOfAorticArchZ);
83
84   MaskImagePointer BrachioCephalicVein = GetAFDB()->template GetImage<MaskImageType>("BrachioCephalicVein");
85   clitk::FindExtremaPointInAGivenDirection<MaskImageType>(BrachioCephalicVein, GetBackgroundValue(), 2, true, p);
86   double CaudalMarginOfLeftBrachiocephalicVeinZ=p[2];
87   GetAFDB()->SetDouble("CaudalMarginOfLeftBrachiocephalicVeinZ", CaudalMarginOfLeftBrachiocephalicVeinZ);
88   
89   // First, cut on the most inferior part. Add one slice because this
90   // inf slice should not be included.
91   double inf = std::min(CaudalMarginOfLeftBrachiocephalicVeinZ, TopOfAorticArchZ) + m_Working_Support->GetSpacing()[2];
92
93   // Get Sternum and search for the upper position
94   MaskImagePointer Sternum = GetAFDB()->template GetImage<MaskImageType>("Sternum");
95
96   // Search most sup point
97   clitk::FindExtremaPointInAGivenDirection<MaskImageType>(Sternum, GetBackgroundValue(), 2, false, p);
98   double m_SternumZ = p[2];
99   // +Sternum->GetSpacing()[2]; // One more slice, because it is below this point // NOT HERE ?? WHY DIFFERENT FROM 3A ??
100
101   //* Crop support :
102   m_Working_Support = 
103     clitk::CropImageAlongOneAxis<MaskImageType>(m_Working_Support, 2, 
104                                                 inf, m_SternumZ, true,
105                                                 GetBackgroundValue());
106
107   StopCurrentStep<MaskImageType>(m_Working_Support);
108   m_ListOfStations["2R"] = m_Working_Support;
109   m_ListOfStations["2L"] = m_Working_Support;
110 }
111 //--------------------------------------------------------------------
112
113
114 //--------------------------------------------------------------------
115 template <class ImageType>
116 void 
117 clitk::ExtractLymphStationsFilter<ImageType>::
118 ExtractStation_2RL_Ant_Limits() 
119 {
120   // -----------------------------------------------------
121   /* Rod says: "The anterior border, as with the Atlas – UM, is
122     posterior to the vessels (right subclavian vein, left
123     brachiocephalic vein, right brachiocephalic vein, left subclavian
124     artery, left common carotid artery and brachiocephalic trunk).
125     These vessels are not included in the nodal station.  The anterior
126     border is drawn to the midpoint of the vessel and an imaginary
127     line joins the middle of these vessels.  Between the vessels,
128     station 2 is in contact with station 3a." */
129
130   // -----------------------------------------------------
131   StartNewStep("[Station 2RL] Ant limits with CommonCarotidArtery");
132
133   // Get CommonCarotidArtery
134   MaskImagePointer CommonCarotidArtery = GetAFDB()->template GetImage<MaskImageType>("CommonCarotidArtery");
135   
136   // Remove Ant to CommonCarotidArtery
137   typedef SliceBySliceRelativePositionFilter<MaskImageType> SliceRelPosFilterType;
138   typename SliceRelPosFilterType::Pointer sliceRelPosFilter = SliceRelPosFilterType::New();
139   sliceRelPosFilter->VerboseStepFlagOff();
140   sliceRelPosFilter->WriteStepFlagOff();
141   sliceRelPosFilter->SetInput(m_Working_Support);
142   sliceRelPosFilter->SetInputObject(CommonCarotidArtery);
143   sliceRelPosFilter->SetDirection(2);
144   sliceRelPosFilter->SetFuzzyThreshold(GetFuzzyThreshold("2RL", "CommonCarotidArtery"));
145   sliceRelPosFilter->AddOrientationTypeString("NotAntTo");
146   sliceRelPosFilter->IntermediateSpacingFlagOn();
147   sliceRelPosFilter->SetIntermediateSpacing(2);
148   sliceRelPosFilter->UniqueConnectedComponentBySliceOff();
149   sliceRelPosFilter->UseASingleObjectConnectedComponentBySliceFlagOff();
150   sliceRelPosFilter->AutoCropFlagOn(); 
151   sliceRelPosFilter->IgnoreEmptySliceObjectFlagOn();
152   sliceRelPosFilter->RemoveObjectFlagOff();
153   sliceRelPosFilter->Update();
154   m_Working_Support = sliceRelPosFilter->GetOutput();
155
156   // End
157   StopCurrentStep<MaskImageType>(m_Working_Support);
158   m_ListOfStations["2R"] = m_Working_Support;
159   m_ListOfStations["2L"] = m_Working_Support;
160
161   // -----------------------------------------------------
162   // Remove Ant to H line from the Ant most part of the
163   // CommonCarotidArtery until we reach the first slice of
164   // BrachioCephalicArtery
165   StartNewStep("[Station 2RL] Ant limits with CommonCarotidArtery, H line");
166
167   // First, find the first slice of BrachioCephalicArtery
168   MaskImagePointer BrachioCephalicArtery = GetAFDB()->template GetImage<MaskImageType>("BrachioCephalicArtery");
169   MaskImagePointType p = BrachioCephalicArtery->GetOrigin(); // initialise to avoid warning 
170   clitk::FindExtremaPointInAGivenDirection<MaskImageType>(BrachioCephalicArtery, GetBackgroundValue(), 2, false, p);
171   double TopOfBrachioCephalicArteryZ=p[2] + BrachioCephalicArtery->GetSpacing()[2]; // Add one slice
172
173   // Remove CommonCarotidArtery below this point
174   CommonCarotidArtery = clitk::CropImageRemoveLowerThan<MaskImageType>(CommonCarotidArtery, 2, TopOfBrachioCephalicArteryZ, true, GetBackgroundValue());  
175
176   // Find most Ant points
177   std::vector<MaskImagePointType> ccaAntPositionA;
178   std::vector<MaskImagePointType> ccaAntPositionB;
179   clitk::SliceBySliceBuildLineSegmentAccordingToExtremaPosition<MaskImageType>(CommonCarotidArtery, 
180                                                                                GetBackgroundValue(), 2,
181                                                                                1, true, // Ant
182                                                                                0, // Horizontal line
183                                                                                -3, // margin
184                                                                                ccaAntPositionA, 
185                                                                                ccaAntPositionB);
186   // Cut ant to this line
187   clitk::SliceBySliceSetBackgroundFromLineSeparation<MaskImageType>(m_Working_Support, 
188                                                                     ccaAntPositionA,
189                                                                     ccaAntPositionB,
190                                                                     GetBackgroundValue(), 1, 10); 
191
192   // End
193   StopCurrentStep<MaskImageType>(m_Working_Support);
194   m_ListOfStations["2R"] = m_Working_Support;
195   m_ListOfStations["2L"] = m_Working_Support;
196
197   // -----------------------------------------------------
198   // Ant limit with the BrachioCephalicArtery
199   StartNewStep("[Station 2RL] Ant limits with BrachioCephalicArtery line");
200
201   // Remove Ant to BrachioCephalicArtery
202   m_Working_Support = 
203     clitk::SliceBySliceRelativePosition<MaskImageType>(m_Working_Support, BrachioCephalicArtery, 2, 
204                                                        GetFuzzyThreshold("2RL", "BrachioCephalicArtery"), "NotAntTo", false, 2, true, false);
205   // End
206   StopCurrentStep<MaskImageType>(m_Working_Support);
207   m_ListOfStations["2R"] = m_Working_Support;
208   m_ListOfStations["2L"] = m_Working_Support;
209
210   // -----------------------------------------------------
211   // Ant limit with the BrachioCephalicArtery H line
212   StartNewStep("[Station 2RL] Ant limits with BrachioCephalicArtery, Horizontal line");
213   
214   // Find most Ant points
215   std::vector<MaskImagePointType> bctAntPositionA;
216   std::vector<MaskImagePointType> bctAntPositionB;
217   clitk::SliceBySliceBuildLineSegmentAccordingToExtremaPosition<MaskImageType>(BrachioCephalicArtery, 
218                                                                                GetBackgroundValue(), 2,
219                                                                                1, true, // Ant
220                                                                                0, // Horizontal line
221                                                                                -1, // margin
222                                                                                bctAntPositionA, 
223                                                                                bctAntPositionB);
224   // Cut ant to this line
225   clitk::SliceBySliceSetBackgroundFromLineSeparation<MaskImageType>(m_Working_Support, 
226                                                                     bctAntPositionA,
227                                                                     bctAntPositionB,
228                                                                     GetBackgroundValue(), 1, 10); 
229  // End
230   StopCurrentStep<MaskImageType>(m_Working_Support);
231   m_ListOfStations["2R"] = m_Working_Support;
232   m_ListOfStations["2L"] = m_Working_Support;
233
234   // -----------------------------------------------------
235   // Ant limit with the BrachioCephalicVein
236   StartNewStep("[Station 2RL] Ant limits with BrachioCephalicVein");
237
238   // Remove Ant to BrachioCephalicVein
239   MaskImagePointer BrachioCephalicVein = GetAFDB()->template GetImage<MaskImageType>("BrachioCephalicVein");
240   m_Working_Support = 
241     clitk::SliceBySliceRelativePosition<MaskImageType>(m_Working_Support, BrachioCephalicVein, 2, 
242                                                        GetFuzzyThreshold("2RL", "BrachioCephalicVein"), "NotAntTo", false, 2, true, false);
243   // End
244   StopCurrentStep<MaskImageType>(m_Working_Support);
245   m_ListOfStations["2R"] = m_Working_Support;
246   m_ListOfStations["2L"] = m_Working_Support;
247 }
248 //--------------------------------------------------------------------
249
250
251 //--------------------------------------------------------------------
252 template <class ImageType>
253 void 
254 clitk::ExtractLymphStationsFilter<ImageType>::
255 ExtractStation_2RL_Ant_Limits2()
256 {
257   // -----------------------------------------------------
258   StartNewStep("[Station 2RL] Ant limits with vessels centroids");
259   
260   // WARNING, as I used "And" after, empty slice in binarizedContour
261   // lead to remove part of the support, although we want to keep
262   // unchanged. So we decide to ResizeImageLike but pad with
263   // ForegroundValue instead of BG
264
265   // Get or compute the binary mask that separate Ant/Post part
266   // according to vessels
267   MaskImagePointer binarizedContour = FindAntPostVessels2();
268   binarizedContour = clitk::ResizeImageLike<MaskImageType>(binarizedContour, 
269                                                            m_Working_Support, 
270                                                            GetForegroundValue());
271   
272   // remove from support
273   typedef clitk::BooleanOperatorLabelImageFilter<MaskImageType> BoolFilterType;
274   typename BoolFilterType::Pointer boolFilter = BoolFilterType::New(); 
275   boolFilter->InPlaceOn();
276   boolFilter->SetInput1(m_Working_Support);
277   boolFilter->SetInput2(binarizedContour);
278   boolFilter->SetBackgroundValue1(GetBackgroundValue());
279   boolFilter->SetBackgroundValue2(GetBackgroundValue());
280   boolFilter->SetOperationType(BoolFilterType::And);
281   boolFilter->Update();
282   m_Working_Support = boolFilter->GetOutput();
283
284   // End
285   StopCurrentStep<MaskImageType>(m_Working_Support);
286   m_ListOfStations["2R"] = m_Working_Support;
287   m_ListOfStations["2L"] = m_Working_Support;
288 }
289 //--------------------------------------------------------------------
290
291
292 //--------------------------------------------------------------------
293 template <class ImageType>
294 void 
295 clitk::ExtractLymphStationsFilter<ImageType>::
296 ExtractStation_2RL_Post_Limits() 
297 {
298   StartNewStep("[Station 2RL] Post limits with post wall of Trachea");
299
300   // Get Trachea
301   MaskImagePointer Trachea = GetAFDB()->template GetImage<MaskImageType>("Trachea");
302   
303   // Resize like the current support (to have the same number of slices)
304   Trachea = clitk::ResizeImageLike<MaskImageType>(Trachea, m_Working_Support, GetBackgroundValue());
305
306   // Find extrema post positions
307   std::vector<MaskImagePointType> tracheaPostPositionsA;
308   std::vector<MaskImagePointType> tracheaPostPositionsB;
309   clitk::SliceBySliceBuildLineSegmentAccordingToExtremaPosition<MaskImageType>(Trachea, 
310                                                                                GetBackgroundValue(), 2, 
311                                                                                1, false, // Post
312                                                                                0, // Horizontal line 
313                                                                                1, 
314                                                                                tracheaPostPositionsA, 
315                                                                                tracheaPostPositionsB);
316   // Cut post to this line
317   clitk::SliceBySliceSetBackgroundFromLineSeparation<MaskImageType>(m_Working_Support, 
318                                                                     tracheaPostPositionsA,
319                                                                     tracheaPostPositionsB,
320                                                                     GetBackgroundValue(), 1, -10); 
321   // END
322   StopCurrentStep<MaskImageType>(m_Working_Support);
323   m_ListOfStations["2R"] = m_Working_Support;
324   m_ListOfStations["2L"] = m_Working_Support;
325 }
326 //--------------------------------------------------------------------
327
328
329 //--------------------------------------------------------------------
330 // Build a vtk mesh from a list of slice number/closed-contours
331 template <class ImageType>
332 vtkSmartPointer<vtkPolyData> 
333 clitk::ExtractLymphStationsFilter<ImageType>::
334 Build3DMeshFrom2DContour(const std::vector<ImagePointType> & points)
335 {
336   // create a contour, polydata. 
337   vtkSmartPointer<vtkPolyData> mesh = vtkSmartPointer<vtkPolyData>::New();
338   mesh->Allocate(); //for cell structures
339   mesh->SetPoints(vtkPoints::New());
340   vtkIdType ids[2];
341   int point_number = points.size();
342   for (unsigned int i=0; i<points.size(); i++) {
343     mesh->GetPoints()->InsertNextPoint(points[i][0],points[i][1],points[i][2]);
344     ids[0]=i;
345     ids[1]=(ids[0]+1)%point_number; //0-1,1-2,...,n-1-0
346     mesh->GetLines()->InsertNextCell(2,ids);
347   }
348   // Return
349   return mesh;
350 }
351 //--------------------------------------------------------------------
352
353
354 //--------------------------------------------------------------------
355 template <class ImageType>
356 void
357 clitk::ExtractLymphStationsFilter<ImageType>::
358 ExtractStation_2RL_LR_Limits()
359 {
360   // ---------------------------------------------------------------------------
361   StartNewStep("[Station 2RL] Left/Right limits with Aorta");
362   MaskImagePointer Aorta = GetAFDB()->template GetImage<MaskImageType>("Aorta");
363   //  DD(GetFuzzyThreshold("2RL", "BrachioCephalicVein"));
364   m_Working_Support = 
365     clitk::SliceBySliceRelativePosition<MaskImageType>(m_Working_Support, Aorta, 2, 
366                                                        GetFuzzyThreshold("2RL", "Aorta"),
367                                                        "RightTo", false, 2, true, false);  
368   // END
369   StopCurrentStep<MaskImageType>(m_Working_Support);
370   m_ListOfStations["2R"] = m_Working_Support;
371   m_ListOfStations["2L"] = m_Working_Support;
372
373   // ---------------------------------------------------------------------------
374   StartNewStep("[Station 2RL] Left/Right limits with SubclavianArtery (Right)");
375   
376   // SliceBySliceRelativePosition + select CCL most at Right
377   MaskImagePointer SubclavianArtery = GetAFDB()->template GetImage<MaskImageType>("SubclavianArtery");
378   typedef SliceBySliceRelativePositionFilter<MaskImageType> SliceRelPosFilterType;
379   typename SliceRelPosFilterType::Pointer sliceRelPosFilter = SliceRelPosFilterType::New();
380   sliceRelPosFilter->VerboseStepFlagOff();
381   sliceRelPosFilter->WriteStepFlagOff();
382   sliceRelPosFilter->SetInput(m_Working_Support);
383   sliceRelPosFilter->SetInputObject(SubclavianArtery);
384   sliceRelPosFilter->SetDirection(2);
385   sliceRelPosFilter->SetFuzzyThreshold(GetFuzzyThreshold("2RL", "SubclavianArteryRight"));
386   sliceRelPosFilter->AddOrientationTypeString("NotRightTo");
387   sliceRelPosFilter->IntermediateSpacingFlagOn();
388   sliceRelPosFilter->SetIntermediateSpacing(2);
389   sliceRelPosFilter->UniqueConnectedComponentBySliceOff();
390   sliceRelPosFilter->UseASingleObjectConnectedComponentBySliceFlagOff();
391
392   sliceRelPosFilter->CCLSelectionFlagOn(); // select one CCL by slice
393   sliceRelPosFilter->SetCCLSelectionDimension(0); // select according to X (0) axis
394   sliceRelPosFilter->SetCCLSelectionDirection(-1); // select most at Right
395   sliceRelPosFilter->CCLSelectionIgnoreSingleCCLFlagOn(); // ignore if only one CCL
396
397   sliceRelPosFilter->AutoCropFlagOn(); 
398   sliceRelPosFilter->IgnoreEmptySliceObjectFlagOn();
399   sliceRelPosFilter->RemoveObjectFlagOff();
400   sliceRelPosFilter->Update();
401   m_Working_Support = sliceRelPosFilter->GetOutput();
402
403   // END
404   StopCurrentStep<MaskImageType>(m_Working_Support);
405   m_ListOfStations["2R"] = m_Working_Support;
406   m_ListOfStations["2L"] = m_Working_Support;
407
408
409   // ---------------------------------------------------------------------------
410   StartNewStep("[Station 2RL] Left/Right limits with SubclavianArtery (Left)");
411   
412   // SliceBySliceRelativePosition + select CCL most at Right
413    sliceRelPosFilter = SliceRelPosFilterType::New();
414   sliceRelPosFilter->VerboseStepFlagOff();
415   sliceRelPosFilter->WriteStepFlagOff();
416   sliceRelPosFilter->SetInput(m_Working_Support);
417   sliceRelPosFilter->SetInputObject(SubclavianArtery);
418   sliceRelPosFilter->SetDirection(2);
419   sliceRelPosFilter->SetFuzzyThreshold(GetFuzzyThreshold("2RL", "SubclavianArteryLeft"));
420   sliceRelPosFilter->AddOrientationTypeString("NotLeftTo");
421   sliceRelPosFilter->IntermediateSpacingFlagOn();
422   sliceRelPosFilter->SetIntermediateSpacing(2);
423   sliceRelPosFilter->UniqueConnectedComponentBySliceOff();
424   sliceRelPosFilter->UseASingleObjectConnectedComponentBySliceFlagOff();
425
426   sliceRelPosFilter->CCLSelectionFlagOn(); // select one CCL by slice
427   sliceRelPosFilter->SetCCLSelectionDimension(0); // select according to X (0) axis
428   sliceRelPosFilter->SetCCLSelectionDirection(+1); // select most at Left
429   sliceRelPosFilter->CCLSelectionIgnoreSingleCCLFlagOff(); // do not ignore if only one CCL
430
431   sliceRelPosFilter->AutoCropFlagOn(); 
432   sliceRelPosFilter->IgnoreEmptySliceObjectFlagOn();
433   sliceRelPosFilter->RemoveObjectFlagOff();
434   sliceRelPosFilter->Update();
435   m_Working_Support = sliceRelPosFilter->GetOutput();
436
437   // END
438   StopCurrentStep<MaskImageType>(m_Working_Support);
439   m_ListOfStations["2R"] = m_Working_Support;
440   m_ListOfStations["2L"] = m_Working_Support;
441 }
442 //--------------------------------------------------------------------
443
444 //--------------------------------------------------------------------
445 template <class ImageType>
446 void
447 clitk::ExtractLymphStationsFilter<ImageType>::
448 ExtractStation_2RL_Remove_Structures()
449 {
450   Remove_Structures("2RL", "BrachioCephalicVein");
451   Remove_Structures("2RL", "CommonCarotidArtery");
452   Remove_Structures("2RL", "SubclavianArtery");
453   Remove_Structures("2RL", "Thyroid");
454   Remove_Structures("2RL", "Aorta");
455   
456   // END
457   StopCurrentStep<MaskImageType>(m_Working_Support);
458   m_ListOfStations["2R"] = m_Working_Support;
459   m_ListOfStations["2L"] = m_Working_Support;
460 }
461 //--------------------------------------------------------------------
462
463
464 //--------------------------------------------------------------------
465 template <class ImageType>
466 void
467 clitk::ExtractLymphStationsFilter<ImageType>::
468 ExtractStation_2RL_SeparateRL()
469 {
470   // ---------------------------------------------------------------------------
471   StartNewStep("[Station 2RL] Separate 2R/2L according to Trachea");
472
473   /*Rod says: 
474     
475    "For station 2 there is a shift, dividing 2R from 2L, from midline
476    to the left paratracheal border."
477
478    Algo: 
479     - Consider Trachea SliceBySlice
480     - find extrema at Left
481     - add margins towards Right
482     - remove what is at Left of this line
483    */
484
485   // Get Trachea
486   MaskImagePointer Trachea = GetAFDB()->template GetImage<MaskImageType>("Trachea");
487   
488   // Resize like the current support (to have the same number of slices)
489   Trachea = clitk::ResizeImageLike<MaskImageType>(Trachea, m_Working_Support, GetBackgroundValue());
490
491   // Find extrema post positions
492   std::vector<MaskImagePointType> tracheaLeftPositionsA;
493   std::vector<MaskImagePointType> tracheaLeftPositionsB;
494   clitk::SliceBySliceBuildLineSegmentAccordingToExtremaPosition<MaskImageType>(Trachea, 
495                                                                                GetBackgroundValue(), 2, 
496                                                                                0, false, // Left
497                                                                                1, // Vertical line 
498                                                                                1, // margins 
499                                                                                tracheaLeftPositionsA, 
500                                                                                tracheaLeftPositionsB);
501   // Copy support for R and L
502   typedef itk::ImageDuplicator<MaskImageType> DuplicatorType;
503   DuplicatorType::Pointer duplicator = DuplicatorType::New();
504   duplicator->SetInputImage(m_Working_Support);
505   duplicator->Update();
506   MaskImageType::Pointer m_Working_Support2 = duplicator->GetOutput();
507   
508   // Cut post to this line for Right part
509   clitk::SliceBySliceSetBackgroundFromLineSeparation<MaskImageType>(m_Working_Support, 
510                                                                     tracheaLeftPositionsA,
511                                                                     tracheaLeftPositionsB,
512                                                                     GetBackgroundValue(), 0, -10); 
513   writeImage<MaskImageType>(m_Working_Support, "R.mhd");
514
515   // Cut post to this line for Left part
516   clitk::SliceBySliceSetBackgroundFromLineSeparation<MaskImageType>(m_Working_Support2, 
517                                                                     tracheaLeftPositionsA,
518                                                                     tracheaLeftPositionsB,
519                                                                     GetBackgroundValue(), 0, +10); 
520   writeImage<MaskImageType>(m_Working_Support2, "L.mhd");
521
522   // END
523   StopCurrentStep<MaskImageType>(m_Working_Support);
524   m_ListOfStations["2R"] = m_Working_Support;
525   m_ListOfStations["2L"] = m_Working_Support2;
526 }
527 //--------------------------------------------------------------------