]> Creatis software - clitk.git/blob - segmentation/clitkExtractLymphStation_3A.txx
26e478b81b763d190f318432da353ae01aef3c69
[clitk.git] / segmentation / clitkExtractLymphStation_3A.txx
1
2 //--------------------------------------------------------------------
3 template <class ImageType>
4 void 
5 clitk::ExtractLymphStationsFilter<ImageType>::
6 ExtractStation_3A_SetDefaultValues()
7 {
8 }
9 //--------------------------------------------------------------------
10
11
12 //--------------------------------------------------------------------
13 template <class TImageType>
14 void 
15 clitk::ExtractLymphStationsFilter<TImageType>::
16 ExtractStation_3A()
17 {
18   if (!CheckForStation("3A")) return;
19
20   StartNewStep("Station 3A");
21   StartSubStep();   
22
23   // Get the current support 
24   StartNewStep("[Station 3A] Get the current 3A suppport");
25   m_Working_Support = m_ListOfSupports["S3A"];
26   m_ListOfStations["3A"] = m_Working_Support;
27   StopCurrentStep<MaskImageType>(m_Working_Support);
28   
29   ExtractStation_3A_Post_Left_Limits_With_Aorta_S5_Support();
30   ExtractStation_3A_Post_Limits_With_Dilated_Aorta_S6_Support();
31   ExtractStation_3A_AntPost_Superiorly();
32   ExtractStation_3A_Remove_Structures();
33   
34   // Generic RelativePosition processes
35   m_ListOfStations["3A"] = this->ApplyRelativePositionList("Station_3A", m_ListOfStations["3A"]);
36
37   // Keep a single CCL
38   m_ListOfStations["3A"] = 
39     clitk::SliceBySliceKeepMainCCL<MaskImageType>(m_ListOfStations["3A"], 
40                                                   GetBackgroundValue(), 
41                                                   GetForegroundValue());
42
43   // Store image filenames into AFDB 
44   writeImage<MaskImageType>(m_ListOfStations["3A"], "seg/Station3A.mhd");
45   GetAFDB()->SetImageFilename("Station3A", "seg/Station3A.mhd"); 
46   WriteAFDB(); 
47   StopSubStep();
48 }
49 //--------------------------------------------------------------------
50
51
52
53 //--------------------------------------------------------------------
54 template <class ImageType>
55 void 
56 clitk::ExtractLymphStationsFilter<ImageType>::
57 ExtractStation_3A_Post_Left_Limits_With_Aorta_S5_Support() 
58 {
59   StartNewStep("[Station 3A] Post limits in S5 support according to Aorta");
60
61    // Consider Aorta, remove Left/Post part ; only around S5
62   // Get S5 support and Aorta
63   MaskImagePointer S5 = m_ListOfSupports["S5"];
64   MaskImagePointer Aorta = GetAFDB()->template GetImage <MaskImageType>("Aorta");
65   Aorta = clitk::ResizeImageLike<MaskImageType>(Aorta, S5, GetBackgroundValue());
66   
67   // Inferiorly, Aorta has two CCL that merge into a single one when
68   // S6 appears. Loop on Aorta slices, select the most ant one, detect
69   // the most ant point.
70
71
72
73   // ====> TO BE CHANGED USING AscendingAorta and DescendingAorta
74
75
76
77   std::vector<MaskSlicePointer> slices;
78   clitk::ExtractSlices<MaskImageType>(Aorta, 2, slices);
79   std::vector<MaskImagePointType> points;
80   for(uint i=0; i<slices.size(); i++) {
81     // Select most ant CCL
82     slices[i] = clitk::Labelize<MaskSliceType>(slices[i], GetBackgroundValue(), false, 1);
83     std::vector<MaskSlicePointType> c;
84     clitk::ComputeCentroids<MaskSliceType>(slices[i], GetBackgroundValue(), c);
85     assert(c.size() == 3); // only 2 CCL
86     typename MaskSliceType::PixelType l;
87     if (c[1][1] > c[2][1]) { // We will remove the label=1
88       l = 1;
89     }
90     else {
91       l = 2;// We will remove the label=2
92     }
93     slices[i] = clitk::SetBackground<MaskSliceType, MaskSliceType>(slices[i], slices[i], l, 
94                                                                    GetBackgroundValue(), true);
95     
96     // Detect the most ant point
97     MaskSlicePointType p;
98     MaskImagePointType pA;
99     clitk::FindExtremaPointInAGivenDirection<MaskSliceType>(slices[i], GetBackgroundValue(), 1, true, p);
100     // Set the X coordinate to the X coordinate of the centroid
101     if (l==1) p[0] = c[2][0];
102     else p[0] = c[1][0];
103     
104     // Convert in 3D and store
105     clitk::PointsUtils<MaskImageType>::Convert2DTo3D(p, Aorta, i, pA);
106     points.push_back(pA);
107   }
108   
109   // DEBUG
110   // MaskImagePointer o = clitk::JoinSlices<MaskImageType>(slices, Aorta, 2);
111   // writeImage<MaskImageType>(o, "o.mhd");
112   // clitk::WriteListOfLandmarks<MaskImageType>(points, "Ant-Aorta.txt");
113
114   // Remove Post/Left to this point
115   m_Working_Support = 
116     clitk::SliceBySliceSetBackgroundFromPoints<MaskImageType>(m_Working_Support, 
117                                                               GetBackgroundValue(), 2,
118                                                               points, 
119                                                               true, // Set BG if X greater than point[x], and 
120                                                               true); // if Y greater than point[y]
121   
122   StopCurrentStep<MaskImageType>(m_Working_Support);
123   m_ListOfStations["3A"] = m_Working_Support;
124 }
125 //--------------------------------------------------------------------
126
127
128 //--------------------------------------------------------------------
129 template <class ImageType>
130 void 
131 clitk::ExtractLymphStationsFilter<ImageType>::
132 ExtractStation_3A_Post_Limits_With_Dilated_Aorta_S6_Support() 
133 {
134   StartNewStep("[Station 3A] Post limits with dilated Aorta");
135
136   // Consider Aorta
137   MaskImagePointer Aorta = GetAFDB()->template GetImage <MaskImageType>("Aorta");
138   
139   // Limits the support to S6
140   MaskImagePointer S6 = m_ListOfSupports["S6"];
141   Aorta = clitk::ResizeImageLike<MaskImageType>(Aorta, S6, GetBackgroundValue());
142   
143   // Extend 1cm anteriorly
144   MaskImagePointType radius; // in mm
145   radius[0] = 10;
146   radius[1] = 10;
147   radius[2] = 0; // required
148   Aorta = clitk::Dilate<MaskImageType>(Aorta, radius, GetBackgroundValue(), GetForegroundValue(), false);
149   
150   // Now, insert this image in the AFDB (but do not store on disk)
151   GetAFDB()->template SetImage<MaskImageType>("Aorta_Dilated_Anteriorly", "bidon", 
152                                               Aorta, false);
153   /*
154   // Not Post to
155   m_Working_Support = 
156     clitk::SliceBySliceRelativePosition<MaskImageType>(m_Working_Support, Aorta, 2, 
157                                                        GetFuzzyThreshold("3A", "Aorta"), 
158                                                        "NotPostTo", true, 
159                                                        Aorta->GetSpacing()[0], false, false);
160
161   */
162
163   
164   StopCurrentStep<MaskImageType>(m_Working_Support);
165   m_ListOfStations["3A"] = m_Working_Support;
166 }
167 //--------------------------------------------------------------------
168
169
170 //--------------------------------------------------------------------
171 template <class ImageType>
172 void 
173 clitk::ExtractLymphStationsFilter<ImageType>::
174 ExtractStation_3A_AntPost_Superiorly() 
175 {
176   StartNewStep("[Station 3A] Post limits superiorly");
177   
178   // Get or compute the binary mask that separate Ant/Post part
179   // according to vessels
180   MaskImagePointer binarizedContour = FindAntPostVessels2();
181   binarizedContour = clitk::ResizeImageLike<MaskImageType>(binarizedContour, 
182                                                            m_Working_Support, 
183                                                            GetBackgroundValue());
184
185   // remove from support
186   typedef clitk::BooleanOperatorLabelImageFilter<MaskImageType> BoolFilterType;
187   typename BoolFilterType::Pointer boolFilter = BoolFilterType::New(); 
188   boolFilter->InPlaceOn();
189   boolFilter->SetInput1(m_Working_Support);
190   boolFilter->SetInput2(binarizedContour);
191   boolFilter->SetBackgroundValue1(GetBackgroundValue());
192   boolFilter->SetBackgroundValue2(GetBackgroundValue());
193   boolFilter->SetOperationType(BoolFilterType::AndNot);
194   boolFilter->Update();
195   m_Working_Support = boolFilter->GetOutput();
196   
197   StopCurrentStep<MaskImageType>(m_Working_Support);
198   m_ListOfStations["3A"] = m_Working_Support;
199 }
200 //--------------------------------------------------------------------
201
202
203 //--------------------------------------------------------------------
204 template <class ImageType>
205 void 
206 clitk::ExtractLymphStationsFilter<ImageType>::
207 ExtractStation_3A_Remove_Structures() 
208 {
209   Remove_Structures(" 3A", "Aorta");
210   Remove_Structures(" 3A", "SubclavianArteryLeft");
211   Remove_Structures(" 3A", "SubclavianArteryRight");
212   Remove_Structures(" 3A", "Thyroid");
213   Remove_Structures(" 3A", "CommonCarotidArteryLeft");
214   Remove_Structures(" 3A", "CommonCarotidArteryRight");
215   Remove_Structures(" 3A", "BrachioCephalicArtery");
216   //  Remove_Structures("3A", "Bones"); --> should be in extractmediastinum
217   //  Remove_Structures("3A", "BrachioCephalicVein"); ?
218
219   StartNewStep("[Station 3A] Remove part of BrachioCephalicVein");
220   // resize like support, extract slices
221   // while single CCL -> remove
222   // when two remove only the most post
223   MaskImagePointer BrachioCephalicVein = 
224     GetAFDB()->template GetImage <MaskImageType>("BrachioCephalicVein");
225   BrachioCephalicVein = clitk::ResizeImageLike<MaskImageType>(BrachioCephalicVein, 
226                                                               m_Working_Support, 
227                                                               GetBackgroundValue());
228   std::vector<MaskSlicePointer> slices;
229   std::vector<MaskSlicePointer> slices_BCV;
230   clitk::ExtractSlices<MaskImageType>(m_Working_Support, 2, slices);
231   clitk::ExtractSlices<MaskImageType>(BrachioCephalicVein, 2, slices_BCV);
232   for(uint i=0; i<slices.size(); i++) {
233     // Labelize slices_BCV
234     slices_BCV[i] = Labelize<MaskSliceType>(slices_BCV[i], 0, true, 1);
235
236     // Compute centroids
237     std::vector<typename MaskSliceType::PointType> centroids;
238     ComputeCentroids<MaskSliceType>(slices_BCV[i], GetBackgroundValue(), centroids);
239
240     // If several centroid, select the one most anterior
241     if (centroids.size() > 2) {
242       // Only keep the one most post
243       typename MaskSliceType::PixelType label;
244       if (centroids[1][1] > centroids[2][1]) {
245         label = 2;
246       }
247       else {
248         label = 1;
249       }      
250       // "remove" the CCL 
251       slices_BCV[i] = clitk::SetBackground<MaskSliceType, MaskSliceType>(slices_BCV[i], 
252                                                                          slices_BCV[i], 
253                                                                          label, 
254                                                                          GetBackgroundValue(), 
255                                                                          true);
256     }
257     
258     // Remove from the support
259     clitk::AndNot<MaskSliceType>(slices[i], slices_BCV[i], GetBackgroundValue());
260   }
261   
262   // Joint
263   m_Working_Support = clitk::JoinSlices<MaskImageType>(slices, m_Working_Support, 2);
264
265   StopCurrentStep<MaskImageType>(m_Working_Support);
266   m_ListOfStations["3A"] = m_Working_Support;
267 }
268 //--------------------------------------------------------------------
269
270