]> Creatis software - clitk.git/blob - segmentation/clitkExtractLymphStation_3A.txx
4b1d3c2906b13dac04cd915b881f66673f2f446b
[clitk.git] / segmentation / clitkExtractLymphStation_3A.txx
1
2 //--------------------------------------------------------------------
3 template <class ImageType>
4 void 
5 clitk::ExtractLymphStationsFilter<ImageType>::
6 ExtractStation_3A_SetDefaultValues()
7 {
8   SetFuzzyThreshold("3A", "Sternum", 0.5);
9   SetFuzzyThreshold("3A", "SubclavianArtery", 0.5);
10 }
11 //--------------------------------------------------------------------
12
13
14 //--------------------------------------------------------------------
15 template <class TImageType>
16 void 
17 clitk::ExtractLymphStationsFilter<TImageType>::
18 ExtractStation_3A()
19 {
20   if (!CheckForStation("3A")) return;
21
22   StartNewStep("Station 3A");
23   StartSubStep();   
24
25   // Get the current support 
26   StartNewStep("[Station 3A] Get the current 3A suppport");
27   m_Working_Support = m_ListOfSupports["S3A"];
28   m_ListOfStations["3A"] = m_Working_Support;
29   StopCurrentStep<MaskImageType>(m_Working_Support);
30   
31   ExtractStation_3A_AntPost_S5();
32   ExtractStation_3A_AntPost_S6();
33   ExtractStation_3A_AntPost_Superiorly();
34   ExtractStation_3A_Remove_Structures();
35
36   Remove_Structures("3A", "Aorta");
37   Remove_Structures("3A", "SubclavianArteryLeft");
38   Remove_Structures("3A", "SubclavianArteryRight");
39   Remove_Structures("3A", "Thyroid");
40   Remove_Structures("3A", "CommonCarotidArteryLeft");
41   Remove_Structures("3A", "CommonCarotidArteryRight");
42   Remove_Structures("3A", "BrachioCephalicArtery");
43
44   ExtractStation_3A_PostToBones();
45   
46   
47
48   // ExtractStation_3A_Ant_Limits(); --> No, already in support; to remove
49   // ExtractStation_3A_Post_Limits(); --> No, more complex, see Vessels etc
50
51   // Store image filenames into AFDB 
52   writeImage<MaskImageType>(m_ListOfStations["3A"], "seg/Station3A.mhd");
53   GetAFDB()->SetImageFilename("Station3A", "seg/Station3A.mhd"); 
54   WriteAFDB(); 
55   StopSubStep();
56 }
57 //--------------------------------------------------------------------
58
59
60 //--------------------------------------------------------------------
61 template <class ImageType>
62 void 
63 clitk::ExtractLymphStationsFilter<ImageType>::
64 ExtractStation_3A_Ant_Limits() 
65 {
66   StartNewStep("[Station 3A] Ant limits with Sternum");
67
68   // Get Sternum, keep posterior part.
69   MaskImagePointer Sternum = GetAFDB()->template GetImage<MaskImageType>("Sternum");
70   m_Working_Support = 
71     clitk::SliceBySliceRelativePosition<MaskImageType>(m_Working_Support, Sternum, 2, 
72                                                        GetFuzzyThreshold("3A", "Sternum"), "PostTo", 
73                                                        false, 3, true, false);
74   StopCurrentStep<MaskImageType>(m_Working_Support);
75   m_ListOfStations["3A"] = m_Working_Support;
76 }
77 //--------------------------------------------------------------------
78
79
80 //--------------------------------------------------------------------
81 template <class ImageType>
82 void 
83 clitk::ExtractLymphStationsFilter<ImageType>::
84 ExtractStation_3A_Post_Limits() 
85 {
86   StartNewStep("[Station 3A] Post limits with SubclavianArtery");
87
88   // Get Sternum, keep posterior part.
89   MaskImagePointer SubclavianArteryLeft = 
90     GetAFDB()->template GetImage<MaskImageType>("SubclavianArteryLeft");
91   MaskImagePointer SubclavianArteryRight = 
92     GetAFDB()->template GetImage<MaskImageType>("SubclavianArteryRight");
93
94   m_Working_Support = 
95     clitk::SliceBySliceRelativePosition<MaskImageType>(m_Working_Support, SubclavianArteryLeft, 2, 
96                                                        GetFuzzyThreshold("3A", "SubclavianArtery"), "AntTo", 
97                                                        false, 3, true, false);
98   m_Working_Support = 
99     clitk::SliceBySliceRelativePosition<MaskImageType>(m_Working_Support, SubclavianArteryRight, 2, 
100                                                        GetFuzzyThreshold("3A", "SubclavianArtery"), "AntTo", 
101                                                        false, 3, true, false);
102   StopCurrentStep<MaskImageType>(m_Working_Support);
103   m_ListOfStations["3A"] = m_Working_Support;
104 }
105 //--------------------------------------------------------------------
106
107
108 //--------------------------------------------------------------------
109 template <class ImageType>
110 void 
111 clitk::ExtractLymphStationsFilter<ImageType>::
112 ExtractStation_3A_AntPost_S5() 
113 {
114   StartNewStep("[Station 3A] Post limits around S5");
115
116   // First remove post to SVC
117   MaskImagePointer SVC = GetAFDB()->template GetImage <MaskImageType>("SVC");
118
119   // Trial in 3D -> difficulties superiorly. Stay slice by slice.
120   // Slice by slice not post to SVC. Use initial spacing
121   m_Working_Support = 
122     clitk::SliceBySliceRelativePosition<MaskImageType>(m_Working_Support, SVC, 2, 
123                                                        GetFuzzyThreshold("3A", "SVC"), 
124                                                        "NotPostTo", true, 
125                                                        SVC->GetSpacing()[0], false, false);  
126
127   // Consider Aorta, remove Left/Post part ; only around S5
128   // Get S5 support and Aorta
129   MaskImagePointer S5 = m_ListOfSupports["S5"];
130   MaskImagePointer Aorta = GetAFDB()->template GetImage <MaskImageType>("Aorta");
131   Aorta = clitk::ResizeImageLike<MaskImageType>(Aorta, S5, GetBackgroundValue());
132   
133   // Inferiorly, Aorta has two CCL that merge into a single one when
134   // S6 appears. Loop on Aorta slices, select the most ant one, detect
135   // the most ant point.
136   std::vector<MaskSlicePointer> slices;
137   clitk::ExtractSlices<MaskImageType>(Aorta, 2, slices);
138   std::vector<MaskImagePointType> points;
139   for(uint i=0; i<slices.size(); i++) {
140     // Select most ant CCL
141     slices[i] = clitk::Labelize<MaskSliceType>(slices[i], GetBackgroundValue(), false, 1);
142     std::vector<MaskSlicePointType> c;
143     clitk::ComputeCentroids<MaskSliceType>(slices[i], GetBackgroundValue(), c);
144     assert(c.size() == 3); // only 2 CCL
145     typename MaskSliceType::PixelType l;
146     if (c[1][1] > c[2][1]) { // We will remove the label=1
147       l = 1;
148     }
149     else {
150       l = 2;// We will remove the label=2
151     }
152     slices[i] = clitk::SetBackground<MaskSliceType, MaskSliceType>(slices[i], slices[i], l, 
153                                                                    GetBackgroundValue(), true);
154     
155     // Detect the most ant point
156     MaskSlicePointType p;
157     MaskImagePointType pA;
158     clitk::FindExtremaPointInAGivenDirection<MaskSliceType>(slices[i], GetBackgroundValue(), 1, true, p);
159     // Set the X coordinate to the X coordinate of the centroid
160     if (l==1) p[0] = c[2][0];
161     else p[0] = c[1][0];
162     
163     // Convert in 3D and store
164     clitk::PointsUtils<MaskImageType>::Convert2DTo3D(p, Aorta, i, pA);
165     points.push_back(pA);
166   }
167   
168   // DEBUG
169   // MaskImagePointer o = clitk::JoinSlices<MaskImageType>(slices, Aorta, 2);
170   // writeImage<MaskImageType>(o, "o.mhd");
171   // clitk::WriteListOfLandmarks<MaskImageType>(points, "Ant-Aorta.txt");
172
173   // Remove Post/Left to this point
174   m_Working_Support = 
175     clitk::SliceBySliceSetBackgroundFromPoints<MaskImageType>(m_Working_Support, 
176                                                               GetBackgroundValue(), 2,
177                                                               points, 
178                                                               true, // Set BG if X greater than point[x], and 
179                                                               true); // if Y greater than point[y]
180   
181   StopCurrentStep<MaskImageType>(m_Working_Support);
182   m_ListOfStations["3A"] = m_Working_Support;
183 }
184 //--------------------------------------------------------------------
185
186
187 //--------------------------------------------------------------------
188 template <class ImageType>
189 void 
190 clitk::ExtractLymphStationsFilter<ImageType>::
191 ExtractStation_3A_AntPost_S6() 
192 {
193   StartNewStep("[Station 3A] Post limits around S6");
194
195   // Consider Aorta
196   MaskImagePointer Aorta = GetAFDB()->template GetImage <MaskImageType>("Aorta");
197   
198   // Limits the support to S6
199   MaskImagePointer S6 = m_ListOfSupports["S6"];
200   Aorta = clitk::ResizeImageLike<MaskImageType>(Aorta, S6, GetBackgroundValue());
201   
202   // Extend 1cm anteriorly
203   MaskImagePointType radius; // in mm
204   radius[0] = 10;
205   radius[1] = 10;
206   radius[2] = 0; // required
207   Aorta = clitk::Dilate<MaskImageType>(Aorta, radius, GetBackgroundValue(), GetForegroundValue(), false);
208   
209   // Not Post to
210   m_Working_Support = 
211     clitk::SliceBySliceRelativePosition<MaskImageType>(m_Working_Support, Aorta, 2, 
212                                                        GetFuzzyThreshold("3A", "Aorta"), 
213                                                        "NotPostTo", true, 
214                                                        Aorta->GetSpacing()[0], false, false);
215   
216   StopCurrentStep<MaskImageType>(m_Working_Support);
217   m_ListOfStations["3A"] = m_Working_Support;
218 }
219 //--------------------------------------------------------------------
220
221
222 //--------------------------------------------------------------------
223 template <class ImageType>
224 void 
225 clitk::ExtractLymphStationsFilter<ImageType>::
226 ExtractStation_3A_AntPost_Superiorly() 
227 {
228   StartNewStep("[Station 3A] Post limits superiorly");
229
230   /*
231  MaskImagePointer BrachioCephalicVein = GetAFDB()->template GetImage <MaskImageType>("BrachioCephalicVein");
232  MaskImagePointer BrachioCephalicArtery = GetAFDB()->template GetImage <MaskImageType>("BrachioCephalicArtery");
233  MaskImagePointer CommonCarotidArteryLeft = GetAFDB()->template GetImage <MaskImageType>("CommonCarotidArteryLeft");
234  MaskImagePointer CommonCarotidArteryRight = GetAFDB()->template GetImage <MaskImageType>("CommonCarotidArteryRight");
235  MaskImagePointer SubclavianArteryLeft = GetAFDB()->template GetImage <MaskImageType>("SubclavianArteryLeft");
236  MaskImagePointer SubclavianArteryRight = GetAFDB()->template GetImage <MaskImageType>("SubclavianArteryRight");
237
238   // Not Post to
239 #define RP(STRUCTURE)                                                   \
240  m_Working_Support =                                                    \
241    clitk::SliceBySliceRelativePosition<MaskImageType>(m_Working_Support, STRUCTURE, 2, \
242                                                       0.5,              \
243                                                       "NotPostTo", true, \
244                                                       STRUCTURE->GetSpacing()[0], false, false);
245  
246  // RP(BrachioCephalicVein);
247  RP(BrachioCephalicArtery);
248  RP(CommonCarotidArteryRight);
249  RP(CommonCarotidArteryLeft);
250  RP(SubclavianArteryRight);
251  RP(SubclavianArteryLeft);
252   */
253   
254   // Get or compute the binary mask that separate Ant/Post part
255   // according to vessels
256   MaskImagePointer binarizedContour = FindAntPostVessels2();
257   binarizedContour = clitk::ResizeImageLike<MaskImageType>(binarizedContour, 
258                                                            m_Working_Support, 
259                                                            GetBackgroundValue());
260
261   // remove from support
262   typedef clitk::BooleanOperatorLabelImageFilter<MaskImageType> BoolFilterType;
263   typename BoolFilterType::Pointer boolFilter = BoolFilterType::New(); 
264   boolFilter->InPlaceOn();
265   boolFilter->SetInput1(m_Working_Support);
266   boolFilter->SetInput2(binarizedContour);
267   boolFilter->SetBackgroundValue1(GetBackgroundValue());
268   boolFilter->SetBackgroundValue2(GetBackgroundValue());
269   boolFilter->SetOperationType(BoolFilterType::AndNot);
270   boolFilter->Update();
271   m_Working_Support = boolFilter->GetOutput();
272   
273   StopCurrentStep<MaskImageType>(m_Working_Support);
274   m_ListOfStations["3A"] = m_Working_Support;
275 }
276 //--------------------------------------------------------------------
277
278
279 //--------------------------------------------------------------------
280 template <class ImageType>
281 void 
282 clitk::ExtractLymphStationsFilter<ImageType>::
283 ExtractStation_3A_Remove_Structures() 
284 {
285   Remove_Structures("3A", "Aorta");
286   Remove_Structures("3A", "SubclavianArteryLeft");
287   Remove_Structures("3A", "SubclavianArteryRight");
288   Remove_Structures("3A", "Thyroid");
289   Remove_Structures("3A", "CommonCarotidArteryLeft");
290   Remove_Structures("3A", "CommonCarotidArteryRight");
291   Remove_Structures("3A", "BrachioCephalicArtery");
292   //  Remove_Structures("3A", "BrachioCephalicVein"); ?
293
294   StartNewStep("[Station 3A] Remove part of BrachioCephalicVein");
295   // resize like support, extract slices
296   // while single CCL -> remove
297   // when two remove only the most post
298   MaskImagePointer BrachioCephalicVein = 
299     GetAFDB()->template GetImage <MaskImageType>("BrachioCephalicVein");
300   BrachioCephalicVein = clitk::ResizeImageLike<MaskImageType>(BrachioCephalicVein, 
301                                                               m_Working_Support, 
302                                                               GetBackgroundValue());
303   std::vector<MaskSlicePointer> slices;
304   std::vector<MaskSlicePointer> slices_BCV;
305   clitk::ExtractSlices<MaskImageType>(m_Working_Support, 2, slices);
306   clitk::ExtractSlices<MaskImageType>(BrachioCephalicVein, 2, slices_BCV);
307   for(uint i=0; i<slices.size(); i++) {
308     // Labelize slices_BCV
309     slices_BCV[i] = Labelize<MaskSliceType>(slices_BCV[i], 0, true, 1);
310
311     // Compute centroids
312     std::vector<typename MaskSliceType::PointType> centroids;
313     ComputeCentroids<MaskSliceType>(slices_BCV[i], GetBackgroundValue(), centroids);
314
315     // If several centroid, select the one most anterior
316     if (centroids.size() > 2) {
317       // Only keep the one most post
318       typename MaskSliceType::PixelType label;
319       if (centroids[1][1] > centroids[2][1]) {
320         label = 2;
321       }
322       else {
323         label = 1;
324       }      
325       // "remove" the CCL 
326       slices_BCV[i] = clitk::SetBackground<MaskSliceType, MaskSliceType>(slices_BCV[i], 
327                                                                          slices_BCV[i], 
328                                                                          label, 
329                                                                          GetBackgroundValue(), 
330                                                                          true);
331     }
332     
333     // Remove from the support
334     clitk::AndNot<MaskSliceType>(slices[i], slices_BCV[i], GetBackgroundValue());
335   }
336   
337   // Joint
338   m_Working_Support = clitk::JoinSlices<MaskImageType>(slices, m_Working_Support, 2);
339
340   StopCurrentStep<MaskImageType>(m_Working_Support);
341   m_ListOfStations["3A"] = m_Working_Support;
342 }
343 //--------------------------------------------------------------------