]> Creatis software - clitk.git/blob - segmentation/clitkExtractLymphStation_7.txx
725c852d4aee2b2588e3987559063edec4929ad8
[clitk.git] / segmentation / clitkExtractLymphStation_7.txx
1
2 //--------------------------------------------------------------------
3 template <class TImageType>
4 void 
5 clitk::ExtractLymphStationsFilter<TImageType>::
6 ExtractStation_7_SetDefaultValues()
7 {
8   SetFuzzyThresholdForS7("Bronchi", 0.1);
9   SetFuzzyThresholdForS7("LeftSuperiorPulmonaryVein", 0.3);
10   SetFuzzyThresholdForS7("RightSuperiorPulmonaryVein", 0.2);
11   SetFuzzyThresholdForS7("RightPulmonaryArtery", 0.3);
12   SetFuzzyThresholdForS7("LeftPulmonaryArtery", 0.5);
13   SetFuzzyThresholdForS7("SVC", 0.2);
14 }
15 //--------------------------------------------------------------------
16
17 //--------------------------------------------------------------------
18 template <class TImageType>
19 void 
20 clitk::ExtractLymphStationsFilter<TImageType>::
21 SetFuzzyThresholdForS7(std::string tag, double value)
22 {
23   m_FuzzyThresholdForS7[tag] = value;
24 }
25 //--------------------------------------------------------------------
26
27
28 //--------------------------------------------------------------------
29 template <class TImageType>
30 double 
31 clitk::ExtractLymphStationsFilter<TImageType>::
32 GetFuzzyThresholdForS7(std::string tag)
33 {
34   if (m_FuzzyThresholdForS7.find(tag) != m_FuzzyThresholdForS7.end()) {
35     return m_FuzzyThresholdForS7[tag]; 
36   }
37   else {
38     clitkExceptionMacro("Could not find options "+tag+" in the m_FuzzyThresholdForS7 list");
39   }
40 }
41 //--------------------------------------------------------------------
42
43
44 //--------------------------------------------------------------------
45 template <class TImageType>
46 void 
47 clitk::ExtractLymphStationsFilter<TImageType>::
48 ExtractStation_7_SI_Limits() 
49 {
50   StartNewStep("[Station7] Inf/Sup mediastinum limits with carina/LLLBronchus");
51   // Get Inputs
52   MaskImagePointer Trachea = GetAFDB()->template GetImage <MaskImageType>("Trachea");  
53   
54   // We suppoe that CarinaZ was already computed (S8)
55   double m_CarinaZ = GetAFDB()->GetDouble("CarinaZ");
56   
57   //  double m_OriginOfRightMiddleLobeBronchusZ = GetAFDB()->GetPoint3D("OriginOfRightMiddleLobeBronchus", 2);
58   // DD(m_OriginOfRightMiddleLobeBronchusZ);
59   MaskImagePointer UpperBorderOfLLLBronchus = GetAFDB()->template GetImage<MaskImageType>("UpperBorderOfLLLBronchus");
60
61   // Search most inf point (WHY ? IS IT THE RIGHT STRUCTURE ??)
62   MaskImagePointType ps = UpperBorderOfLLLBronchus->GetOrigin(); // initialise to avoid warning 
63   clitk::FindExtremaPointInAGivenDirection<MaskImageType>(UpperBorderOfLLLBronchus, GetBackgroundValue(), 2, true, ps);
64   double m_UpperBorderOfLLLBronchusZ = ps[2];
65
66   /*
67   std::vector<MaskImagePointType> centroids;
68   clitk::ComputeCentroids<MaskImageType>(UpperBorderOfLLLBronchus, GetBackgroundValue(), centroids);
69   double m_UpperBorderOfLLLBronchusZ = centroids[1][2];
70   DD(m_UpperBorderOfLLLBronchusZ)
71   */
72
73   /* Crop support */
74   m_Working_Support = 
75     clitk::CropImageAlongOneAxis<MaskImageType>(m_Working_Support, 2, 
76                                                 m_UpperBorderOfLLLBronchusZ, 
77                                                 m_CarinaZ, true,
78                                                 GetBackgroundValue());
79   /* Crop trachea */
80   m_Working_Trachea = 
81     clitk::CropImageAlongOneAxis<MaskImageType>(Trachea, 2, 
82                                                 m_UpperBorderOfLLLBronchusZ, 
83                                                 m_CarinaZ, true,
84                                                 GetBackgroundValue());
85
86   StopCurrentStep<MaskImageType>(m_Working_Support);
87   m_ListOfStations["7"] = m_Working_Support;
88 }
89 //--------------------------------------------------------------------
90
91
92 //--------------------------------------------------------------------
93 template <class TImageType>
94 void 
95 clitk::ExtractLymphStationsFilter<TImageType>::
96 ExtractStation_7_RL_Limits() 
97 {
98   // ----------------------------------------------------------------
99   StartNewStep("[Station7] Limits with bronchus : RightTo the left bronchus");  
100
101   // First consider bronchus and keep the main CCL by slice
102   m_RightBronchus = GetAFDB()->template GetImage <MaskImageType>("RightBronchus");
103   m_LeftBronchus = GetAFDB()->template GetImage <MaskImageType>("LeftBronchus");
104
105   // Extract slices, Label, compute centroid, keep most central connected component
106   std::vector<MaskSlicePointer> slices_leftbronchus;
107   std::vector<MaskSlicePointer> slices_rightbronchus;
108   clitk::ExtractSlices<MaskImageType>(m_LeftBronchus, 2, slices_leftbronchus);
109   clitk::ExtractSlices<MaskImageType>(m_RightBronchus, 2, slices_rightbronchus);
110   
111   // Loop on slices
112   for(uint i=0; i<slices_leftbronchus.size(); i++) {
113     slices_leftbronchus[i] = Labelize<MaskSliceType>(slices_leftbronchus[i], 0, false, 10);
114     std::vector<typename MaskSliceType::PointType> c;
115     clitk::ComputeCentroids<MaskSliceType>(slices_leftbronchus[i], GetBackgroundValue(), c);
116     if (c.size() > 1) {
117       double most_at_left = c[1][0];
118       int most_at_left_index=1;
119       for(uint j=1; j<c.size(); j++) {
120         if (c[j][0] < most_at_left) {
121           most_at_left = c[j][0];
122           most_at_left_index = j;
123         }
124       }
125       // Put all other CCL to Background
126       slices_leftbronchus[i] = 
127         clitk::Binarize<MaskSliceType>(slices_leftbronchus[i], most_at_left_index, 
128                                        most_at_left_index, GetBackgroundValue(), GetForegroundValue());
129     } // end c.size
130   }
131   
132   for(uint i=0; i<slices_rightbronchus.size(); i++) {
133     slices_rightbronchus[i] = Labelize<MaskSliceType>(slices_rightbronchus[i], 0, false, 10);
134     std::vector<typename MaskSliceType::PointType> c;
135     clitk::ComputeCentroids<MaskSliceType>(slices_rightbronchus[i], GetBackgroundValue(), c);
136     if (c.size() > 1) {
137       double most_at_right = c[1][0];
138       int most_at_right_index=1;
139       for(uint j=1; j<c.size(); j++) {
140         if (c[j][0] > most_at_right) {
141           most_at_right = c[j][0];
142           most_at_right_index = j;
143         }
144       }
145       // Put all other CCL to Background
146       slices_rightbronchus[i] = 
147         clitk::Binarize<MaskSliceType>(slices_rightbronchus[i], most_at_right_index, 
148                                        most_at_right_index, GetBackgroundValue(), GetForegroundValue());
149     } // end c.size
150   }
151   
152   // Joint slices
153   m_LeftBronchus = clitk::JoinSlices<MaskImageType>(slices_leftbronchus, m_LeftBronchus, 2);
154   m_RightBronchus = clitk::JoinSlices<MaskImageType>(slices_rightbronchus, m_RightBronchus, 2);
155
156   writeImage<MaskImageType>(m_LeftBronchus, "step-left.mhd");
157   writeImage<MaskImageType>(m_RightBronchus, "step-right.mhd");
158
159   m_Working_Support = 
160     clitk::SliceBySliceRelativePosition<MaskImageType>(m_Working_Support, m_LeftBronchus, 2, 
161                                                        GetFuzzyThresholdForS7("Bronchi"), "RightTo", 
162                                                        false, 3, false);
163   StopCurrentStep<MaskImageType>(m_Working_Support);
164
165
166   // ----------------------------------------------------------------
167   StartNewStep("[Station7] Limits with bronchus : LeftTo the right bronchus");
168   m_Working_Support = 
169     clitk::SliceBySliceRelativePosition<MaskImageType>(m_Working_Support, m_RightBronchus, 2, 
170                                                        GetFuzzyThresholdForS7("Bronchi"), "LeftTo", 
171                                                        false, 3, false); 
172   StopCurrentStep<MaskImageType>(m_Working_Support);
173
174
175   // ----------------------------------------------------------------
176   StartNewStep("[Station7] Limits with LeftSuperiorPulmonaryVein");
177   try {
178     MaskImagePointer LeftSuperiorPulmonaryVein = GetAFDB()->template GetImage<MaskImageType>("LeftSuperiorPulmonaryVein");
179     typedef SliceBySliceRelativePositionFilter<MaskImageType> SliceRelPosFilterType;
180     typename SliceRelPosFilterType::Pointer sliceRelPosFilter = SliceRelPosFilterType::New();
181     sliceRelPosFilter->SetInput(m_Working_Support);
182     sliceRelPosFilter->SetInputObject(LeftSuperiorPulmonaryVein);
183     sliceRelPosFilter->SetDirection(2);
184     sliceRelPosFilter->SetFuzzyThreshold(GetFuzzyThresholdForS7("LeftSuperiorPulmonaryVein"));
185     sliceRelPosFilter->AddOrientationTypeString("NotLeftTo");
186     sliceRelPosFilter->AddOrientationTypeString("NotAntTo");
187     sliceRelPosFilter->SetIntermediateSpacingFlag(true);
188     sliceRelPosFilter->SetIntermediateSpacing(3);
189     sliceRelPosFilter->SetUniqueConnectedComponentBySlice(false);
190     sliceRelPosFilter->SetAutoCropFlag(false); 
191     sliceRelPosFilter->IgnoreEmptySliceObjectFlagOn();
192     sliceRelPosFilter->Update();
193     m_Working_Support = sliceRelPosFilter->GetOutput();
194     StopCurrentStep<MaskImageType>(m_Working_Support);
195   }
196   catch (clitk::ExceptionObject e) {
197     std::cout << "Not LeftSuperiorPulmonaryVein, skip" << std::endl;
198   }
199
200   // ----------------------------------------------------------------
201   StartNewStep("[Station7] Limits with RightSuperiorPulmonaryVein");
202   try {
203     MaskImagePointer RightSuperiorPulmonaryVein = GetAFDB()->template GetImage<MaskImageType>("RightSuperiorPulmonaryVein");
204     typedef SliceBySliceRelativePositionFilter<MaskImageType> SliceRelPosFilterType;
205     typename SliceRelPosFilterType::Pointer sliceRelPosFilter = SliceRelPosFilterType::New();
206     sliceRelPosFilter->SetInput(m_Working_Support);
207     sliceRelPosFilter->SetInputObject(RightSuperiorPulmonaryVein);
208     sliceRelPosFilter->SetDirection(2);
209     sliceRelPosFilter->SetFuzzyThreshold(GetFuzzyThresholdForS7("RightSuperiorPulmonaryVein"));
210     sliceRelPosFilter->AddOrientationTypeString("NotRightTo");
211     sliceRelPosFilter->AddOrientationTypeString("NotAntTo");
212     sliceRelPosFilter->AddOrientationTypeString("NotPostTo");
213     sliceRelPosFilter->SetIntermediateSpacingFlag(true);
214     sliceRelPosFilter->SetIntermediateSpacing(3);
215     sliceRelPosFilter->SetUniqueConnectedComponentBySlice(false);
216     sliceRelPosFilter->SetAutoCropFlag(false); 
217     sliceRelPosFilter->IgnoreEmptySliceObjectFlagOn();
218     sliceRelPosFilter->Update();
219     m_Working_Support = sliceRelPosFilter->GetOutput();
220     StopCurrentStep<MaskImageType>(m_Working_Support);
221   }
222   catch (clitk::ExceptionObject e) {
223     std::cout << "Not RightSuperiorPulmonaryVein, skip" << std::endl;
224   }
225
226   // ----------------------------------------------------------------
227   StartNewStep("[Station7] Limits with RightPulmonaryArtery");
228   MaskImagePointer RightPulmonaryArtery = GetAFDB()->template GetImage<MaskImageType>("RightPulmonaryArtery");
229   typedef SliceBySliceRelativePositionFilter<MaskImageType> SliceRelPosFilterType;
230   typename SliceRelPosFilterType::Pointer sliceRelPosFilter = SliceRelPosFilterType::New();
231   sliceRelPosFilter->SetInput(m_Working_Support);
232   sliceRelPosFilter->SetInputObject(RightPulmonaryArtery);
233   sliceRelPosFilter->SetDirection(2);
234   sliceRelPosFilter->SetFuzzyThreshold(GetFuzzyThresholdForS7("RightPulmonaryArtery"));
235   sliceRelPosFilter->AddOrientationTypeString("NotAntTo");
236   sliceRelPosFilter->SetIntermediateSpacingFlag(true);
237   sliceRelPosFilter->SetIntermediateSpacing(3);
238   sliceRelPosFilter->SetUniqueConnectedComponentBySlice(false);
239   sliceRelPosFilter->SetAutoCropFlag(false); 
240   sliceRelPosFilter->IgnoreEmptySliceObjectFlagOn();
241   sliceRelPosFilter->Update();
242   m_Working_Support = sliceRelPosFilter->GetOutput();
243   StopCurrentStep<MaskImageType>(m_Working_Support);
244
245   // ----------------------------------------------------------------
246   StartNewStep("[Station7] Limits with LeftPulmonaryArtery");
247   MaskImagePointer LeftPulmonaryArtery = GetAFDB()->template GetImage<MaskImageType>("LeftPulmonaryArtery");
248   sliceRelPosFilter = SliceRelPosFilterType::New();
249   sliceRelPosFilter->SetInput(m_Working_Support);
250   sliceRelPosFilter->SetInputObject(LeftPulmonaryArtery);
251   sliceRelPosFilter->SetDirection(2);
252   sliceRelPosFilter->SetFuzzyThreshold(GetFuzzyThresholdForS7("LeftPulmonaryArtery"));
253   sliceRelPosFilter->AddOrientationTypeString("NotAntTo");
254   sliceRelPosFilter->SetIntermediateSpacingFlag(true);
255   sliceRelPosFilter->SetIntermediateSpacing(3);
256   sliceRelPosFilter->SetUniqueConnectedComponentBySlice(false);
257   sliceRelPosFilter->SetAutoCropFlag(false); 
258   sliceRelPosFilter->IgnoreEmptySliceObjectFlagOn();
259   sliceRelPosFilter->Update();
260   m_Working_Support = sliceRelPosFilter->GetOutput();
261   StopCurrentStep<MaskImageType>(m_Working_Support);
262
263   StartNewStep("[Station7] Limits with SVC");
264   MaskImagePointer SVC = GetAFDB()->template GetImage<MaskImageType>("SVC");
265   sliceRelPosFilter = SliceRelPosFilterType::New();
266   sliceRelPosFilter->SetInput(m_Working_Support);
267   sliceRelPosFilter->SetInputObject(SVC);
268   sliceRelPosFilter->SetDirection(2);
269   sliceRelPosFilter->SetFuzzyThreshold(GetFuzzyThresholdForS7("SVC"));
270   sliceRelPosFilter->AddOrientationTypeString("NotRightTo");
271   sliceRelPosFilter->AddOrientationTypeString("NotAntTo");
272   sliceRelPosFilter->SetIntermediateSpacingFlag(true);
273   sliceRelPosFilter->SetIntermediateSpacing(3);
274   sliceRelPosFilter->SetUniqueConnectedComponentBySlice(false);
275   sliceRelPosFilter->SetAutoCropFlag(true); 
276   sliceRelPosFilter->IgnoreEmptySliceObjectFlagOn();
277   sliceRelPosFilter->Update();
278   m_Working_Support = sliceRelPosFilter->GetOutput();
279   StopCurrentStep<MaskImageType>(m_Working_Support);
280   
281   // End
282   m_ListOfStations["7"] = m_Working_Support;
283 }
284 //--------------------------------------------------------------------
285
286
287 //--------------------------------------------------------------------
288 template <class TImageType>
289 void 
290 clitk::ExtractLymphStationsFilter<TImageType>::
291 ExtractStation_7_Posterior_Limits() 
292 {
293   StartNewStep("[Station7] Posterior limits -> must be AntTo post wall of the bronchi (OLD CLASSIF)");  
294
295   // Search for points that are the most left/post/ant and most
296   // right/post/ant of the left and right bronchus
297
298   // extract, loop slices, label/keep, find extrema x 3
299   /*  FindExtremaPointsInBronchus(m_LeftBronchus, 0, 15, m_RightMostInLeftBronchus, 
300                               m_AntMostInLeftBronchus, m_PostMostInLeftBronchus);
301   FindExtremaPointsInBronchus(m_RightBronchus, 1, 15, m_LeftMostInRightBronchus, 
302                               m_AntMostInRightBronchus, m_PostMostInRightBronchus);
303   */
304   
305   // First cut bronchus to the correct sup/inf support 
306   MaskImagePointer RightBronchus = clitk::ResizeImageLike<MaskImageType>(m_RightBronchus, m_Working_Support, GetBackgroundValue());
307   MaskImagePointer LeftBronchus = clitk::ResizeImageLike<MaskImageType>(m_LeftBronchus, m_Working_Support, GetBackgroundValue());
308
309   // Find extrema points
310   FindExtremaPointsInBronchus(RightBronchus, 0, 10, m_LeftMostInRightBronchus, 
311                               m_AntMostInRightBronchus, m_PostMostInRightBronchus);
312
313   FindExtremaPointsInBronchus(LeftBronchus, 1, 10, m_RightMostInLeftBronchus, 
314                               m_AntMostInLeftBronchus, m_PostMostInLeftBronchus);
315
316
317
318   // DEBUG
319   std::ofstream osrl; openFileForWriting(osrl, "osrl.txt"); osrl << "LANDMARKS1" << std::endl;
320   std::ofstream osal; openFileForWriting(osal, "osal.txt"); osal << "LANDMARKS1" << std::endl;
321   std::ofstream ospl; openFileForWriting(ospl, "ospl.txt"); ospl << "LANDMARKS1" << std::endl;
322   std::ofstream osrr; openFileForWriting(osrr, "osrr.txt"); osrr << "LANDMARKS1" << std::endl;
323   std::ofstream osar; openFileForWriting(osar, "osar.txt"); osar << "LANDMARKS1" << std::endl;
324   std::ofstream ospr; openFileForWriting(ospr, "ospr.txt"); ospr << "LANDMARKS1" << std::endl;
325
326   for(uint i=0; i<m_RightMostInLeftBronchus.size(); i++) {
327     osrl << i << " " << m_RightMostInLeftBronchus[i][0] << " " << m_RightMostInLeftBronchus[i][1] 
328          << " " << m_RightMostInLeftBronchus[i][2] << " 0 0 " << std::endl;
329     osal << i << " " << m_AntMostInLeftBronchus[i][0] << " " << m_AntMostInLeftBronchus[i][1] 
330          << " " << m_AntMostInLeftBronchus[i][2] << " 0 0 " << std::endl;
331     ospl << i << " " << m_PostMostInLeftBronchus[i][0] << " " << m_PostMostInLeftBronchus[i][1] 
332          << " " << m_PostMostInLeftBronchus[i][2] << " 0 0 " << std::endl;
333   }
334
335   for(uint i=0; i<m_LeftMostInRightBronchus.size(); i++) {
336     osrr << i << " " << m_LeftMostInRightBronchus[i][0] << " " << m_LeftMostInRightBronchus[i][1] 
337          << " " << m_LeftMostInRightBronchus[i][2] << " 0 0 " << std::endl;
338     osar << i << " " << m_AntMostInRightBronchus[i][0] << " " << m_AntMostInRightBronchus[i][1] 
339          << " " << m_AntMostInRightBronchus[i][2] << " 0 0 " << std::endl;
340     ospr << i << " " << m_PostMostInRightBronchus[i][0] << " " << m_PostMostInRightBronchus[i][1] 
341          << " " << m_PostMostInRightBronchus[i][2] << " 0 0 " << std::endl;
342   }
343   osrl.close();
344   osal.close();
345   ospl.close();
346   osrr.close();
347   osar.close();
348   ospr.close();
349
350   clitk::SliceBySliceSetBackgroundFromLineSeparation<MaskImageType>(m_Working_Support, 
351                                                                     m_PostMostInRightBronchus,
352                                                                     m_PostMostInLeftBronchus,
353                                                                     GetBackgroundValue(), 1, -10);
354   // If needed -> can do the same with AntMost.
355
356   // End
357   StopCurrentStep<MaskImageType>(m_Working_Support);
358   m_ListOfStations["7"] = m_Working_Support;
359 }
360 //--------------------------------------------------------------------
361
362 //--------------------------------------------------------------------
363 template <class ImageType>
364 void 
365 clitk::ExtractLymphStationsFilter<ImageType>::
366 ExtractStation_7_Remove_Structures()
367 {
368
369   //--------------------------------------------------------------------
370   StartNewStep("[Station7] remove some structures");
371
372   Remove_Structures("AzygousVein");
373   Remove_Structures("Aorta");
374   Remove_Structures("Esophagus");
375   Remove_Structures("RightPulmonaryArtery");
376   Remove_Structures("LeftPulmonaryArtery");
377   Remove_Structures("LeftSuperiorPulmonaryVein");
378   Remove_Structures("PulmonaryTrunk");
379   Remove_Structures("VertebralBody");
380
381   // END
382   StopCurrentStep<MaskImageType>(m_Working_Support);
383   m_ListOfStations["7"] = m_Working_Support;
384   return;
385 }
386 //--------------------------------------------------------------------
387
388
389