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