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();
47 m_ListOfStations["3A"] =
48 clitk::SliceBySliceKeepMainCCL<MaskImageType>(m_ListOfStations["3A"],
50 GetForegroundValue());
52 // Store image filenames into AFDB
53 writeImage<MaskImageType>(m_ListOfStations["3A"], "seg/Station3A.mhd");
54 GetAFDB()->SetImageFilename("Station3A", "seg/Station3A.mhd");
58 //--------------------------------------------------------------------
62 //--------------------------------------------------------------------
63 template <class ImageType>
65 clitk::ExtractLymphStationsFilter<ImageType>::
66 ExtractStation_3A_AntPost_S5()
68 StartNewStep("[Station 3A] Post limits around S5");
70 // First remove post to SVC
71 MaskImagePointer SVC = GetAFDB()->template GetImage <MaskImageType>("SVC");
73 // Trial in 3D -> difficulties superiorly. Stay slice by slice.
74 // Slice by slice not post to SVC. Use initial spacing
76 clitk::SliceBySliceRelativePosition<MaskImageType>(m_Working_Support, SVC, 2,
77 GetFuzzyThreshold("3A", "SVC"),
79 SVC->GetSpacing()[0], false, false);
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());
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
104 l = 2;// We will remove the label=2
106 slices[i] = clitk::SetBackground<MaskSliceType, MaskSliceType>(slices[i], slices[i], l,
107 GetBackgroundValue(), true);
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];
117 // Convert in 3D and store
118 clitk::PointsUtils<MaskImageType>::Convert2DTo3D(p, Aorta, i, pA);
119 points.push_back(pA);
123 // MaskImagePointer o = clitk::JoinSlices<MaskImageType>(slices, Aorta, 2);
124 // writeImage<MaskImageType>(o, "o.mhd");
125 // clitk::WriteListOfLandmarks<MaskImageType>(points, "Ant-Aorta.txt");
127 // Remove Post/Left to this point
129 clitk::SliceBySliceSetBackgroundFromPoints<MaskImageType>(m_Working_Support,
130 GetBackgroundValue(), 2,
132 true, // Set BG if X greater than point[x], and
133 true); // if Y greater than point[y]
135 StopCurrentStep<MaskImageType>(m_Working_Support);
136 m_ListOfStations["3A"] = m_Working_Support;
138 //--------------------------------------------------------------------
141 //--------------------------------------------------------------------
142 template <class ImageType>
144 clitk::ExtractLymphStationsFilter<ImageType>::
145 ExtractStation_3A_AntPost_S6()
147 StartNewStep("[Station 3A] Post limits around S6");
150 MaskImagePointer Aorta = GetAFDB()->template GetImage <MaskImageType>("Aorta");
152 // Limits the support to S6
153 MaskImagePointer S6 = m_ListOfSupports["S6"];
154 Aorta = clitk::ResizeImageLike<MaskImageType>(Aorta, S6, GetBackgroundValue());
156 // Extend 1cm anteriorly
157 MaskImagePointType radius; // in mm
160 radius[2] = 0; // required
161 Aorta = clitk::Dilate<MaskImageType>(Aorta, radius, GetBackgroundValue(), GetForegroundValue(), false);
165 clitk::SliceBySliceRelativePosition<MaskImageType>(m_Working_Support, Aorta, 2,
166 GetFuzzyThreshold("3A", "Aorta"),
168 Aorta->GetSpacing()[0], false, false);
170 StopCurrentStep<MaskImageType>(m_Working_Support);
171 m_ListOfStations["3A"] = m_Working_Support;
173 //--------------------------------------------------------------------
176 //--------------------------------------------------------------------
177 template <class ImageType>
179 clitk::ExtractLymphStationsFilter<ImageType>::
180 ExtractStation_3A_AntPost_Superiorly()
182 StartNewStep("[Station 3A] Post limits superiorly");
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");
193 #define RP(STRUCTURE) \
194 m_Working_Support = \
195 clitk::SliceBySliceRelativePosition<MaskImageType>(m_Working_Support, STRUCTURE, 2, \
198 STRUCTURE->GetSpacing()[0], false, false);
200 // RP(BrachioCephalicVein);
201 RP(BrachioCephalicArtery);
202 RP(CommonCarotidArteryRight);
203 RP(CommonCarotidArteryLeft);
204 RP(SubclavianArteryRight);
205 RP(SubclavianArteryLeft);
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,
213 GetBackgroundValue());
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();
227 StopCurrentStep<MaskImageType>(m_Working_Support);
228 m_ListOfStations["3A"] = m_Working_Support;
230 //--------------------------------------------------------------------
233 //--------------------------------------------------------------------
234 template <class ImageType>
236 clitk::ExtractLymphStationsFilter<ImageType>::
237 ExtractStation_3A_Remove_Structures()
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"); ?
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,
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);
266 std::vector<typename MaskSliceType::PointType> centroids;
267 ComputeCentroids<MaskSliceType>(slices_BCV[i], GetBackgroundValue(), centroids);
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]) {
280 slices_BCV[i] = clitk::SetBackground<MaskSliceType, MaskSliceType>(slices_BCV[i],
283 GetBackgroundValue(),
287 // Remove from the support
288 clitk::AndNot<MaskSliceType>(slices[i], slices_BCV[i], GetBackgroundValue());
292 m_Working_Support = clitk::JoinSlices<MaskImageType>(slices, m_Working_Support, 2);
294 StopCurrentStep<MaskImageType>(m_Working_Support);
295 m_ListOfStations["3A"] = m_Working_Support;
297 //--------------------------------------------------------------------
300 //--------------------------------------------------------------------
301 template <class ImageType>
303 clitk::ExtractLymphStationsFilter<ImageType>::
304 ExtractStation_3A_PostToBones()
306 StartNewStep("[Station 3A] Post limits with bones");
309 MaskImagePointer Bones = GetAFDB()->template GetImage<MaskImageType>("Bones");
311 clitk::SliceBySliceRelativePosition<MaskImageType>(m_Working_Support, Bones, 2,
312 GetFuzzyThreshold("3A", "Bones"), "NotAntTo",
313 false, 3, true, false);
315 StopCurrentStep<MaskImageType>(m_Working_Support);
316 m_ListOfStations["3A"] = m_Working_Support;
318 //--------------------------------------------------------------------