2 //--------------------------------------------------------------------
3 template <class ImageType>
5 clitk::ExtractLymphStationsFilter<ImageType>::
6 ExtractStation_3A_SetDefaultValues()
8 SetFuzzyThreshold("3A", "Sternum", 0.5);
9 SetFuzzyThreshold("3A", "SubclavianArtery", 0.5);
11 //--------------------------------------------------------------------
14 //--------------------------------------------------------------------
15 template <class TImageType>
17 clitk::ExtractLymphStationsFilter<TImageType>::
20 if (!CheckForStation("3A")) return;
22 StartNewStep("Station 3A");
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);
31 ExtractStation_3A_AntPost_S5();
32 ExtractStation_3A_AntPost_S6();
33 ExtractStation_3A_AntPost_Superiorly();
34 ExtractStation_3A_Remove_Structures();
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");
44 ExtractStation_3A_PostToBones();
48 // ExtractStation_3A_Ant_Limits(); --> No, already in support; to remove
49 // ExtractStation_3A_Post_Limits(); --> No, more complex, see Vessels etc
51 // Store image filenames into AFDB
52 writeImage<MaskImageType>(m_ListOfStations["3A"], "seg/Station3A.mhd");
53 GetAFDB()->SetImageFilename("Station3A", "seg/Station3A.mhd");
57 //--------------------------------------------------------------------
60 //--------------------------------------------------------------------
61 template <class ImageType>
63 clitk::ExtractLymphStationsFilter<ImageType>::
64 ExtractStation_3A_Ant_Limits()
66 StartNewStep("[Station 3A] Ant limits with Sternum");
68 // Get Sternum, keep posterior part.
69 MaskImagePointer Sternum = GetAFDB()->template GetImage<MaskImageType>("Sternum");
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;
77 //--------------------------------------------------------------------
80 //--------------------------------------------------------------------
81 template <class ImageType>
83 clitk::ExtractLymphStationsFilter<ImageType>::
84 ExtractStation_3A_Post_Limits()
86 StartNewStep("[Station 3A] Post limits with SubclavianArtery");
88 // Get Sternum, keep posterior part.
89 MaskImagePointer SubclavianArteryLeft =
90 GetAFDB()->template GetImage<MaskImageType>("SubclavianArteryLeft");
91 MaskImagePointer SubclavianArteryRight =
92 GetAFDB()->template GetImage<MaskImageType>("SubclavianArteryRight");
95 clitk::SliceBySliceRelativePosition<MaskImageType>(m_Working_Support, SubclavianArteryLeft, 2,
96 GetFuzzyThreshold("3A", "SubclavianArtery"), "AntTo",
97 false, 3, true, false);
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;
105 //--------------------------------------------------------------------
108 //--------------------------------------------------------------------
109 template <class ImageType>
111 clitk::ExtractLymphStationsFilter<ImageType>::
112 ExtractStation_3A_AntPost_S5()
114 StartNewStep("[Station 3A] Post limits around S5");
116 // First remove post to SVC
117 MaskImagePointer SVC = GetAFDB()->template GetImage <MaskImageType>("SVC");
119 // Trial in 3D -> difficulties superiorly. Stay slice by slice.
120 // Slice by slice not post to SVC. Use initial spacing
122 clitk::SliceBySliceRelativePosition<MaskImageType>(m_Working_Support, SVC, 2,
123 GetFuzzyThreshold("3A", "SVC"),
125 SVC->GetSpacing()[0], false, false);
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());
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
150 l = 2;// We will remove the label=2
152 slices[i] = clitk::SetBackground<MaskSliceType, MaskSliceType>(slices[i], slices[i], l,
153 GetBackgroundValue(), true);
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];
163 // Convert in 3D and store
164 clitk::PointsUtils<MaskImageType>::Convert2DTo3D(p, Aorta, i, pA);
165 points.push_back(pA);
169 // MaskImagePointer o = clitk::JoinSlices<MaskImageType>(slices, Aorta, 2);
170 // writeImage<MaskImageType>(o, "o.mhd");
171 // clitk::WriteListOfLandmarks<MaskImageType>(points, "Ant-Aorta.txt");
173 // Remove Post/Left to this point
175 clitk::SliceBySliceSetBackgroundFromPoints<MaskImageType>(m_Working_Support,
176 GetBackgroundValue(), 2,
178 true, // Set BG if X greater than point[x], and
179 true); // if Y greater than point[y]
181 StopCurrentStep<MaskImageType>(m_Working_Support);
182 m_ListOfStations["3A"] = m_Working_Support;
184 //--------------------------------------------------------------------
187 //--------------------------------------------------------------------
188 template <class ImageType>
190 clitk::ExtractLymphStationsFilter<ImageType>::
191 ExtractStation_3A_AntPost_S6()
193 StartNewStep("[Station 3A] Post limits around S6");
196 MaskImagePointer Aorta = GetAFDB()->template GetImage <MaskImageType>("Aorta");
198 // Limits the support to S6
199 MaskImagePointer S6 = m_ListOfSupports["S6"];
200 Aorta = clitk::ResizeImageLike<MaskImageType>(Aorta, S6, GetBackgroundValue());
202 // Extend 1cm anteriorly
203 MaskImagePointType radius; // in mm
206 radius[2] = 0; // required
207 Aorta = clitk::Dilate<MaskImageType>(Aorta, radius, GetBackgroundValue(), GetForegroundValue(), false);
211 clitk::SliceBySliceRelativePosition<MaskImageType>(m_Working_Support, Aorta, 2,
212 GetFuzzyThreshold("3A", "Aorta"),
214 Aorta->GetSpacing()[0], false, false);
216 StopCurrentStep<MaskImageType>(m_Working_Support);
217 m_ListOfStations["3A"] = m_Working_Support;
219 //--------------------------------------------------------------------
222 //--------------------------------------------------------------------
223 template <class ImageType>
225 clitk::ExtractLymphStationsFilter<ImageType>::
226 ExtractStation_3A_AntPost_Superiorly()
228 StartNewStep("[Station 3A] Post limits superiorly");
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");
239 #define RP(STRUCTURE) \
240 m_Working_Support = \
241 clitk::SliceBySliceRelativePosition<MaskImageType>(m_Working_Support, STRUCTURE, 2, \
244 STRUCTURE->GetSpacing()[0], false, false);
246 // RP(BrachioCephalicVein);
247 RP(BrachioCephalicArtery);
248 RP(CommonCarotidArteryRight);
249 RP(CommonCarotidArteryLeft);
250 RP(SubclavianArteryRight);
251 RP(SubclavianArteryLeft);
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,
259 GetBackgroundValue());
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();
273 StopCurrentStep<MaskImageType>(m_Working_Support);
274 m_ListOfStations["3A"] = m_Working_Support;
276 //--------------------------------------------------------------------
279 //--------------------------------------------------------------------
280 template <class ImageType>
282 clitk::ExtractLymphStationsFilter<ImageType>::
283 ExtractStation_3A_Remove_Structures()
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"); ?
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,
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);
312 std::vector<typename MaskSliceType::PointType> centroids;
313 ComputeCentroids<MaskSliceType>(slices_BCV[i], GetBackgroundValue(), centroids);
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]) {
326 slices_BCV[i] = clitk::SetBackground<MaskSliceType, MaskSliceType>(slices_BCV[i],
329 GetBackgroundValue(),
333 // Remove from the support
334 clitk::AndNot<MaskSliceType>(slices[i], slices_BCV[i], GetBackgroundValue());
338 m_Working_Support = clitk::JoinSlices<MaskImageType>(slices, m_Working_Support, 2);
340 StopCurrentStep<MaskImageType>(m_Working_Support);
341 m_ListOfStations["3A"] = m_Working_Support;
343 //--------------------------------------------------------------------