2 #include <itkBinaryDilateImageFilter.h>
3 #include <itkMirrorPadImageFilter.h>
5 //--------------------------------------------------------------------
6 template <class ImageType>
8 clitk::ExtractLymphStationsFilter<ImageType>::
9 ExtractStationSupports()
11 // Get initial Mediastinum
12 m_Working_Support = m_Mediastinum = this->GetAFDB()->template GetImage<MaskImageType>("Mediastinum", true);
14 // Remove some computed structures
15 this->GetAFDB()->RemoveTag("CarinaZ");
16 this->GetAFDB()->RemoveTag("ApexOfTheChestZ");
18 // Superior and inferior limits.
19 Support_SI_Limit("inferior", "Sup_to_Carina", "inferior", "Carina", 0);
20 Support_SI_Limit("superior", "Inf_to_Carina", "inferior", "Carina", m_Working_Support->GetSpacing()[2]);
22 // Read all support limits in a file and apply them
23 ReadSupportLimits(GetSupportLimitsFilename());
24 for(unsigned int i=0; i<m_ListOfSupportLimits.size(); i++) {
25 SupportLimitsType s = m_ListOfSupportLimits[i];
26 Support_SI_Limit(s.station_limit, s.station, s.structure_limit,
27 s.structure, s.offset*m_Working_Support->GetSpacing()[2]);
31 Support_LeftRight_S1R_S1L();
34 Support_LeftRight_S2R_S2L();
37 Support_LeftRight_S4R_S4L();
39 // Post limits of S1,S2,S4
42 // S3P : "the anterior border is an imaginary horizontal line
43 // extending along the posterior wall of the trachea"
44 StartNewStep("[Support] Ant limits of S3P with trachea");
45 m_ListOfSupports["S3P"] = LimitsWithTrachea(m_ListOfSupports["S3P"], 1, 0, 10);
47 // S3A : "Posteriorly, the station is limited by station 2R and 2L,
48 // but excludes the great vessels. An imaginary line joins the
49 // midpoint of the vessel in the anterior to posterior plane. It is
50 // here that station 2 contacts station 3a" ===> here limit with
52 StartNewStep("[Support] Ant limits of S3A with trachea");
53 m_ListOfSupports["S3A"] = LimitsWithTrachea(m_ListOfSupports["S3A"], 1, 0, -10);
55 // S1RL - posterior limits when SI overlap with S3P
56 Support_Post_S1_S3P();
58 // S1RL - posterior limits with S2RL above sternal notch
59 Support_Post_S1_Ant_S2RL();
62 // Below Carina S7,8,9,10
63 m_ListOfSupports["S7"] = clitk::Clone<MaskImageType>(m_ListOfSupports["Inf_to_Carina"]);
64 m_ListOfSupports["S8"] = clitk::Clone<MaskImageType>(m_ListOfSupports["Inf_to_Carina"]);
65 m_ListOfSupports["S9"] = clitk::Clone<MaskImageType>(m_ListOfSupports["Inf_to_Carina"]);
66 m_ListOfSupports["S10"] = clitk::Clone<MaskImageType>(m_ListOfSupports["Inf_to_Carina"]);
67 m_ListOfSupports["S11"] = clitk::Clone<MaskImageType>(m_ListOfSupports["Inf_to_Carina"]);
69 // Store image filenames into AFDB
70 WriteImageSupport("S1R"); WriteImageSupport("S1L");
71 WriteImageSupport("S2R"); WriteImageSupport("S2L");
72 WriteImageSupport("S3A"); WriteImageSupport("S3P");
73 WriteImageSupport("S4R"); WriteImageSupport("S4L");
74 WriteImageSupport("S5");
75 WriteImageSupport("S6");
76 WriteImageSupport("S7");
77 WriteImageSupport("S8");
78 WriteImageSupport("S9");
79 WriteImageSupport("S10");
80 WriteImageSupport("S11");
83 //--------------------------------------------------------------------
86 //--------------------------------------------------------------------
87 template <class ImageType>
89 clitk::ExtractLymphStationsFilter<ImageType>::
90 Support_SI_Limit(const std::string station_limit, const std::string station,
91 const std::string structure_limit, const std::string structure,
94 if (!GetCheckSupportFlag())
95 StartNewStep("[Support] "+station_limit+" limit of "+station+" is "+structure_limit+" limit of "+structure);
98 if ((station_limit != "superior") && (station_limit != "inferior")) {
99 clitkExceptionMacro("Error station_limit must be 'inferior' or 'superior', not '"<< station_limit);
101 if ((structure_limit != "superior") && (structure_limit != "inferior")) {
102 clitkExceptionMacro("Error structure_limit must be 'inferior' or 'superior', not '"<< structure_limit);
105 // Get current support
106 if (m_ListOfSupports.find(station) == m_ListOfSupports.end()) {
107 // std::cerr << "Warning: support " << station << " not initialized" << std::endl;
108 m_ListOfSupports[station] = m_Mediastinum;
110 m_Working_Support = m_ListOfSupports[station];
112 // Get structure or structureZ
117 // Try to load structure and compute extrema point
118 if (this->GetAFDB()->TagExist(structure)) {
119 MaskImagePointer Structure = this->GetAFDB()->template GetImage <MaskImageType>(structure);
120 file = this->GetAFDB()->GetTagValue(structure);
121 MaskImagePointType p;
122 p[0] = p[1] = p[2] = 0.0; // to avoid warning
123 if (structure_limit == "superior")
124 clitk::FindExtremaPointInAGivenDirection<MaskImageType>(Structure, GetBackgroundValue(), 2, false, p);
126 clitk::FindExtremaPointInAGivenDirection<MaskImageType>(Structure, GetBackgroundValue(), 2, true, p);
131 // Try to load structureZ
132 if ((found==0) && (this->GetAFDB()->TagExist(structure+"Z"))) {
133 z = this->GetAFDB()->GetDouble(structure+"Z");
137 // Try to load structurePoint
138 if ((found==0) && (this->GetAFDB()->TagExist(structure+"Point"))) {
139 MaskImagePointType p;
140 this->GetAFDB()->GetPoint3D(structure+"Point", p);
145 // Try to see if it is an already computed support
147 if (m_ListOfSupports.find(structure) != m_ListOfSupports.end()) {
148 MaskImagePointer Structure = m_ListOfSupports[structure];
149 MaskImagePointType p;
150 if (structure_limit == "superior")
151 clitk::FindExtremaPointInAGivenDirection<MaskImageType>(Structure, GetBackgroundValue(), 2, false, p);
153 clitk::FindExtremaPointInAGivenDirection<MaskImageType>(Structure, GetBackgroundValue(), 2, true, p);
159 // Try special case : "FindApexOfTheChest"
160 if (structure == "FindApexOfTheChest") {
161 z = FindApexOfTheChest();
164 if (structure == "FindInferiorBorderOfAorticArch") {
165 z = FindInferiorBorderOfAorticArch();
168 if (structure == "FindSuperiorBorderOfAorticArch") {
169 z = FindSuperiorBorderOfAorticArch();
173 // If we find anything
175 std::cerr << "ERROR : I could not find " << structure << " nor " << structure << "Z nor "
176 << structure << "Point" << std::endl;
183 // Remove Lower or greater
184 if (station_limit == "inferior") {
186 clitk::CropImageRemoveLowerThan<MaskImageType>(m_Working_Support, 2, z, true, GetBackgroundValue());
190 clitk::CropImageRemoveGreaterThan<MaskImageType>(m_Working_Support, 2, z, true, GetBackgroundValue());
193 // Check: if reference station is given, display information
194 if (GetCheckSupportFlag()) {
196 MaskImagePointer Ref = this->GetAFDB()->template GetImage <MaskImageType>(station+"_Ref");
197 MaskImagePointType p_support;
198 MaskImagePointType p_ref;
199 if (station_limit == "superior") {
200 clitk::FindExtremaPointInAGivenDirection<MaskImageType>(Ref, GetBackgroundValue(), 2, false, p_ref);
201 clitk::FindExtremaPointInAGivenDirection<MaskImageType>(m_Working_Support, GetBackgroundValue(), 2, false, p_support);
204 clitk::FindExtremaPointInAGivenDirection<MaskImageType>(Ref, GetBackgroundValue(), 2, true, p_ref);
205 clitk::FindExtremaPointInAGivenDirection<MaskImageType>(m_Working_Support, GetBackgroundValue(), 2, true, p_support);
207 std::ostringstream os;
208 os << "[Support] \t" << station << "\t" << station_limit << " "
209 << "Z = " << z << std::setprecision(2) << std::fixed
210 << "\tSupport = " << p_support[2]
211 << "\tRef = " << p_ref[2]
212 << "\tdiff = " << p_support[2]-p_ref[2] << "\t"
213 << structure << " " << structure_limit;
214 if (found==1) os << " (S "+file+")";
215 if (found==2) os << " (Z)";
216 if (found==3) os << " (P)";
217 if (found==4) os << " (p)";
218 if (found==5) os << " (Apex)";
219 if (found==6) os << " (AorticArch)";
220 StartNewStep(os.str());
221 } catch(clitk::ExceptionObject e) { }
225 m_ListOfSupports[station] = m_Working_Support;
226 StopCurrentStep<MaskImageType>(m_Working_Support);
228 //--------------------------------------------------------------------
231 //--------------------------------------------------------------------
232 template <class ImageType>
234 clitk::ExtractLymphStationsFilter<ImageType>::
235 Support_LeftRight_S1R_S1L()
238 Medially, station 1R and 1L are separated by the midline of the
239 trachea, whilst excluding the thyroid gland.
242 // Step S1RL : Left-Right
243 StartNewStep("[Support] Left-Right S1R S1L");
244 std::vector<ImagePointType> A;
245 std::vector<ImagePointType> B;
246 // Search for centroid positions of trachea
247 MaskImagePointer Trachea = this->GetAFDB()->template GetImage <MaskImageType>("Trachea");
248 MaskImagePointer S1RL = m_ListOfSupports["S1R"];
249 Trachea = clitk::ResizeImageLike<MaskImageType>(Trachea, S1RL, GetBackgroundValue());
250 std::vector<MaskSlicePointer> slices;
251 clitk::ExtractSlices<MaskImageType>(Trachea, 2, slices);
252 for(uint i=0; i<slices.size(); i++) {
253 slices[i] = Labelize<MaskSliceType>(slices[i], 0, false, 10);
254 std::vector<typename MaskSliceType::PointType> c;
255 clitk::ComputeCentroids<MaskSliceType>(slices[i], GetBackgroundValue(), c);
257 clitk::PointsUtils<MaskImageType>::Convert2DTo3D(c[1], Trachea, i, a);
263 clitk::WriteListOfLandmarks<MaskImageType>(A, "S1LR_A.txt");
264 clitk::WriteListOfLandmarks<MaskImageType>(B, "S1LR_B.txt");
267 MaskImagePointer S1R = clitk::Clone<MaskImageType>(S1RL);
268 MaskImagePointer S1L = clitk::Clone<MaskImageType>(S1RL);
271 clitk::SliceBySliceSetBackgroundFromLineSeparation<MaskImageType>(S1R, A, B,
272 GetBackgroundValue(), 0, -10);
273 S1R = clitk::AutoCrop<MaskImageType>(S1R, GetBackgroundValue());
274 m_ListOfSupports["S1R"] = S1R;
277 clitk::SliceBySliceSetBackgroundFromLineSeparation<MaskImageType>(S1L, A, B,
278 GetBackgroundValue(), 0, 10);
279 S1L = clitk::AutoCrop<MaskImageType>(S1L, GetBackgroundValue());
280 m_ListOfSupports["S1L"] = S1L;
281 StopCurrentStep<MaskImageType>(m_ListOfSupports["S1L"]);
283 //--------------------------------------------------------------------
286 //--------------------------------------------------------------------
287 template <class ImageType>
289 clitk::ExtractLymphStationsFilter<ImageType>::
290 Support_LeftRight_S2R_S2L()
292 // ---------------------------------------------------------------------------
293 /* Step : S2RL LeftRight As for lymph node station 4R, 2R includes
294 nodes extending to the left lateral border of the trachea.
296 Rod says: "For station 2 there is a shift in the IASLC definition
297 dividing 2R from 2L, from the midline to the left lateral
298 tracheal border. This is represented in the atlas as a vertical
299 line passing tangentially along the left lateral tracheal border
302 StartNewStep("[Support] Separate 2R/2L according to Trachea");
303 MaskImagePointer S2R = m_ListOfSupports["S2R"];
304 MaskImagePointer S2L = m_ListOfSupports["S2L"];
305 S2R = LimitsWithTrachea(S2R, 0, 1, -10);
306 S2L = LimitsWithTrachea(S2L, 0, 1, 10);
307 S2R = clitk::AutoCrop<MaskImageType>(S2R, GetBackgroundValue());
308 S2L = clitk::AutoCrop<MaskImageType>(S2L, GetBackgroundValue());
309 m_ListOfSupports["S2R"] = S2R;
310 m_ListOfSupports["S2L"] = S2L;
311 this->GetAFDB()->template ReleaseImage<MaskImageType>("Trachea");
313 //--------------------------------------------------------------------
316 //--------------------------------------------------------------------
317 template <class ImageType>
319 clitk::ExtractLymphStationsFilter<ImageType>::
320 Support_LeftRight_S4R_S4L()
322 // ---------------------------------------------------------------------------
324 The medial border of station 4R is defined as an imaginary line
325 running vertically from the left lateral tracheal border. This is
326 the same medial border as was described for station 2R.
328 StartNewStep("[Support] Left Right separation of 4R/4L");
330 MaskImagePointer S4R = m_ListOfSupports["S4R"];
331 MaskImagePointer S4L = m_ListOfSupports["S4L"];
332 S4R = LimitsWithTrachea(S4R, 0, 1, -10);
333 S4L = LimitsWithTrachea(S4L, 0, 1, 10);
334 m_ListOfSupports["S4R"] = S4R;
335 m_ListOfSupports["S4L"] = S4L;
337 //--------------------------------------------------------------------
340 //--------------------------------------------------------------------
341 template <class ImageType>
342 typename clitk::ExtractLymphStationsFilter<ImageType>::MaskImagePointer
343 clitk::ExtractLymphStationsFilter<ImageType>::
344 LimitsWithTrachea(MaskImageType * input, int extremaDirection, int lineDirection,
347 MaskImagePointType min, max;
348 GetMinMaxBoundary<MaskImageType>(input, min, max);
349 return LimitsWithTrachea(input, extremaDirection, lineDirection, offset, max[2]);
351 template <class ImageType>
352 typename clitk::ExtractLymphStationsFilter<ImageType>::MaskImagePointer
353 clitk::ExtractLymphStationsFilter<ImageType>::
354 LimitsWithTrachea(MaskImageType * input, int extremaDirection, int lineDirection,
355 double offset, double maxSupPosition)
358 Take the input mask, consider the trachea and limit according to
359 Left border of the trachea. Keep at Left or at Right according to
363 MaskImagePointer Trachea = this->GetAFDB()->template GetImage<MaskImageType>("Trachea");
365 // Find extrema post positions
366 std::vector<MaskImagePointType> tracheaLeftPositionsA;
367 std::vector<MaskImagePointType> tracheaLeftPositionsB;
369 // Crop Trachea only on the Sup-Inf axes, without autocrop
370 // Trachea = clitk::ResizeImageLike<MaskImageType>(Trachea, input, GetBackgroundValue());
371 MaskImagePointType min, max;
372 GetMinMaxBoundary<MaskImageType>(input, min, max);
373 Trachea = clitk::CropImageAlongOneAxis<MaskImageType>(Trachea, 2, min[2], max[2],
374 false, GetBackgroundValue());
376 // Select the main CCL (because of bronchus)
377 Trachea = SliceBySliceKeepMainCCL<MaskImageType>(Trachea, GetBackgroundValue(), GetForegroundValue());
379 // Slice by slice, build the separation line
380 clitk::SliceBySliceBuildLineSegmentAccordingToExtremaPosition<MaskImageType>(Trachea,
381 GetBackgroundValue(), 2,
382 extremaDirection, false, // Left
383 lineDirection, // Vertical line
385 tracheaLeftPositionsA,
386 tracheaLeftPositionsB);
387 // Do not consider trachea above the limit
388 int indexMax=tracheaLeftPositionsA.size();
389 for(uint i=0; i<tracheaLeftPositionsA.size(); i++) {
390 if (tracheaLeftPositionsA[i][2] > maxSupPosition) {
392 i = tracheaLeftPositionsA.size(); // stop loop
395 tracheaLeftPositionsA.erase(tracheaLeftPositionsA.begin()+indexMax, tracheaLeftPositionsA.end());
396 tracheaLeftPositionsB.erase(tracheaLeftPositionsB.begin()+indexMax, tracheaLeftPositionsB.end());
398 // Cut post to this line
399 clitk::SliceBySliceSetBackgroundFromLineSeparation<MaskImageType>(input,
400 tracheaLeftPositionsA,
401 tracheaLeftPositionsB,
402 GetBackgroundValue(),
403 extremaDirection, offset);
404 MaskImagePointer output = clitk::AutoCrop<MaskImageType>(input, GetBackgroundValue());
407 //--------------------------------------------------------------------
410 //--------------------------------------------------------------------
411 template <class ImageType>
413 clitk::ExtractLymphStationsFilter<ImageType>::
416 StartNewStep("[Support] Post limits of S2RL, S4RL");
418 double m_ApexOfTheChest = FindApexOfTheChest();
420 // Post limits with Trachea
421 // MaskImagePointer S1R = m_ListOfSupports["S1R"];
422 // MaskImagePointer S1L = m_ListOfSupports["S1L"];
423 MaskImagePointer S2R = m_ListOfSupports["S2R"];
424 MaskImagePointer S2L = m_ListOfSupports["S2L"];
425 MaskImagePointer S4R = m_ListOfSupports["S4R"];
426 MaskImagePointer S4L = m_ListOfSupports["S4L"];
427 // m_ListOfSupports["S1R"] = LimitsWithTrachea(S1L, 1, 0, -10, m_ApexOfTheChest);
428 // m_ListOfSupports["S1L"] = LimitsWithTrachea(S1R, 1, 0, -10, m_ApexOfTheChest);
429 m_ListOfSupports["S2R"] = LimitsWithTrachea(S2R, 1, 0, -10, m_ApexOfTheChest);
430 m_ListOfSupports["S2L"] = LimitsWithTrachea(S2L, 1, 0, -10, m_ApexOfTheChest);
431 m_ListOfSupports["S4R"] = LimitsWithTrachea(S4R, 1, 0, -10, m_ApexOfTheChest);
432 m_ListOfSupports["S4L"] = LimitsWithTrachea(S4L, 1, 0, -10, m_ApexOfTheChest);
434 //--------------------------------------------------------------------
437 //--------------------------------------------------------------------
438 template <class ImageType>
440 clitk::ExtractLymphStationsFilter<ImageType>::
441 Support_Post_S1_S3P()
443 StartNewStep("[Support] If S1RL and S3P have Sup-Inf overlap, define S1RL posterior limits with S3P anterior limits (post wall trachea)");
445 // Get current supports
446 MaskImagePointer S1R = m_ListOfSupports["S1R"];
447 MaskImagePointer S1L = m_ListOfSupports["S1L"];
449 // Find extrema ant positions for 3P
450 std::vector<MaskImagePointType> A;
451 std::vector<MaskImagePointType> B;
454 MaskImagePointer S3P = clitk::Clone<MaskImageType>(m_ListOfSupports["S3P"]);
455 S3P = clitk::ResizeImageLike<MaskImageType>(S3P, S1R, GetBackgroundValue());
457 // Slice by slice, build the separation line
458 clitk::SliceBySliceBuildLineSegmentAccordingToExtremaPosition<MaskImageType>(S3P,
459 GetBackgroundValue(), 2,
461 0, // Horizontal line
465 // clitk::WriteListOfLandmarks<MaskImageType>(A, "A-S1S3P.txt");
466 // clitk::WriteListOfLandmarks<MaskImageType>(B, "B-S1S3P.txt");
468 // Cut post to this line
469 clitk::SliceBySliceSetBackgroundFromLineSeparation<MaskImageType>(S1R, A, B,
470 GetBackgroundValue(),
473 // Crop S3P like S1L (Redo for S1L)
474 S3P = clitk::Clone<MaskImageType>(m_ListOfSupports["S3P"]);
475 S3P = clitk::ResizeImageLike<MaskImageType>(S3P, S1L, GetBackgroundValue());
477 // Slice by slice, build the separation line
480 clitk::SliceBySliceBuildLineSegmentAccordingToExtremaPosition<MaskImageType>(S3P,
481 GetBackgroundValue(), 2,
483 0, // Horizontal line
486 // Cut post to this line
487 clitk::SliceBySliceSetBackgroundFromLineSeparation<MaskImageType>(S1L, A, B,
488 GetBackgroundValue(),
492 S1R = clitk::AutoCrop<MaskImageType>(S1R, GetBackgroundValue());
493 S1L = clitk::AutoCrop<MaskImageType>(S1L, GetBackgroundValue());
495 StopCurrentStep<MaskImageType>(S1R);
497 m_ListOfSupports["S1R"] = S1R;
498 m_ListOfSupports["S1L"] = S1L;
500 //--------------------------------------------------------------------
503 //--------------------------------------------------------------------
504 template <class ImageType>
506 clitk::ExtractLymphStationsFilter<ImageType>::
507 Support_Post_S1_Ant_S2RL()
509 StartNewStep("[Support] Define S1RL posterior limits with S2RL anterior limits when overlap");
512 MaskImagePointer RightLung = this->GetAFDB()->template GetImage<MaskImageType>("RightLung");
514 // Find common area between S1 and S2
515 MaskImagePointType p_min;
516 MaskImagePointType p_max;
517 clitk::FindExtremaPointInAGivenDirection<MaskImageType>(m_ListOfSupports["S2R"],
518 GetBackgroundValue(), 2, false, p_max);
519 clitk::FindExtremaPointInAGivenDirection<MaskImageType>(m_ListOfSupports["S1R"],
520 GetBackgroundValue(), 2, true, p_min);
521 p_min[2] -= RightLung->GetSpacing()[2]; // consider the slice below (remove lower or equal)
522 p_max[2] += RightLung->GetSpacing()[2]; // consider the slice abov (remove greater or equal)
524 if (p_min[2] > p_max[2]) {
527 RightLung = clitk::Clone<MaskImageType>(RightLung);
528 RightLung = clitk::ResizeImageLike<MaskImageType>(RightLung, m_ListOfSupports["S1R"], GetBackgroundValue());
529 RightLung = clitk::CropImageRemoveLowerThan<MaskImageType>(RightLung, 2, p_min[2], true, GetBackgroundValue());
530 RightLung = clitk::CropImageRemoveGreaterThan<MaskImageType>(RightLung, 2, p_max[2], true, GetBackgroundValue());
532 // Find extrema ant positions for RightLung
533 std::vector<MaskImagePointType> A;
534 std::vector<MaskImagePointType> B;
535 clitk::SliceBySliceBuildLineSegmentAccordingToExtremaPosition<MaskImageType>(RightLung,
536 GetBackgroundValue(), 2,
538 0, // Horizontal line
541 clitk::SliceBySliceSetBackgroundFromLineSeparation<MaskImageType>(m_ListOfSupports["S1R"],
543 GetBackgroundValue(),
545 // I add one pixel to abupt S2R to S1R
546 for(int i=0; i<A.size(); i++) {
547 A[i][1] -= RightLung->GetSpacing()[1];
548 B[i][1] -= RightLung->GetSpacing()[1];
550 clitk::SliceBySliceSetBackgroundFromLineSeparation<MaskImageType>(m_ListOfSupports["S2R"],
552 GetBackgroundValue(),
556 // Get LeftLung, crop
557 MaskImagePointer LeftLung = this->GetAFDB()->template GetImage<MaskImageType>("LeftLung");
558 clitk::FindExtremaPointInAGivenDirection<MaskImageType>(m_ListOfSupports["S2L"],
559 GetBackgroundValue(), 2, false, p_max);
560 clitk::FindExtremaPointInAGivenDirection<MaskImageType>(m_ListOfSupports["S1L"],
561 GetBackgroundValue(), 2, true, p_min);
562 p_min[2] -= LeftLung->GetSpacing()[2]; // consider the slice below (remove lower or equal)
563 p_max[2] += LeftLung->GetSpacing()[2]; // consider the slice abov (remove greater or equal)
565 if (p_min[2] > p_max[2]) {
566 LeftLung = clitk::ResizeImageLike<MaskImageType>(LeftLung, m_ListOfSupports["S1L"], GetBackgroundValue());
567 LeftLung = clitk::CropImageRemoveLowerThan<MaskImageType>(LeftLung, 2, p_min[2], true, GetBackgroundValue());
568 LeftLung = clitk::CropImageRemoveGreaterThan<MaskImageType>(LeftLung, 2, p_max[2], true, GetBackgroundValue());
570 // Find extrema ant positions for LeftLung
571 std::vector<MaskImagePointType> A;
572 std::vector<MaskImagePointType> B;
573 clitk::SliceBySliceBuildLineSegmentAccordingToExtremaPosition<MaskImageType>(LeftLung,
574 GetBackgroundValue(), 2,
576 0, // Horizontal line
579 clitk::SliceBySliceSetBackgroundFromLineSeparation<MaskImageType>(m_ListOfSupports["S1L"],
581 GetBackgroundValue(),
583 // I add one pixel to abupt S2R to S1R
584 for(int i=0; i<A.size(); i++) {
585 A[i][1] -= LeftLung->GetSpacing()[1];
586 B[i][1] -= LeftLung->GetSpacing()[1];
588 clitk::SliceBySliceSetBackgroundFromLineSeparation<MaskImageType>(m_ListOfSupports["S2L"],
590 GetBackgroundValue(),
594 //--------------------------------------------------------------------