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