]> Creatis software - clitk.git/blobdiff - segmentation/clitkExtractLymphStation_3P.txx
remove tools (now in tests_dav)
[clitk.git] / segmentation / clitkExtractLymphStation_3P.txx
index 7f1d5bf7d9eaef0b2fc15c72c1b0c18d4e4b199c..274fc867c740596227b8c2c92f84b31b4a5d5a02 100644 (file)
@@ -1,23 +1,3 @@
-/*=========================================================================
-  Program:   vv                     http://www.creatis.insa-lyon.fr/rio/vv
-
-  Authors belong to:
-  - University of LYON              http://www.universite-lyon.fr/
-  - Léon Bérard cancer center       http://www.centreleonberard.fr
-  - CREATIS CNRS laboratory         http://www.creatis.insa-lyon.fr
-
-  This software is distributed WITHOUT ANY WARRANTY; without even
-  the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
-  PURPOSE.  See the copyright notices for more information.
-
-  It is distributed under dual licence
-
-  - BSD        See included LICENSE.txt file
-  - CeCILL-B   http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html
-===========================================================================*/
-
-#include <itkBinaryDilateImageFilter.h>
-#include <itkMirrorPadImageFilter.h>
 
 //--------------------------------------------------------------------
 template <class ImageType>
@@ -30,136 +10,40 @@ ExtractStation_3P_SetDefaultValues()
 
 
 //--------------------------------------------------------------------
-template <class ImageType>
+template <class TImageType>
 void 
-clitk::ExtractLymphStationsFilter<ImageType>::
-ExtractStation_3P_SI_Limits() 
+clitk::ExtractLymphStationsFilter<TImageType>::
+ExtractStation_3P()
 {
-  /*
-    Apex of the chest & Carina.
-  */
-  StartNewStep("[Station 3P] Inf/Sup limits with apex of the chest and carina");
+  if (!CheckForStation("3P")) return;
 
-  // Get Carina position (has been determined in Station8)
-  m_CarinaZ = GetAFDB()->GetDouble("CarinaZ");
-  
-  // Get Apex of the Chest. The "lungs" structure is autocroped so we
-  // consider the most superior point.
-  MaskImagePointer Lungs = GetAFDB()->template GetImage<MaskImageType>("Lungs");
-  MaskImageIndexType index = Lungs->GetLargestPossibleRegion().GetIndex();
-  index += Lungs->GetLargestPossibleRegion().GetSize();
-  MaskImagePointType p;
-  Lungs->TransformIndexToPhysicalPoint(index, p);
-  p[2] -= 5; // 5 mm below because the autocrop is slightly above the apex
-  double m_ApexOfTheChest = p[2];
-
-  /* Crop support :
-     Superior limit = carina
-     Inferior limit = Apex of the chest */
-  m_Working_Support = 
-    clitk::CropImageAlongOneAxis<MaskImageType>(m_Working_Support, 2, 
-                                                m_CarinaZ,
-                                                m_ApexOfTheChest, true,
-                                                GetBackgroundValue());
+  StartNewStep("Station 3P");
+  StartSubStep();  
 
-  StopCurrentStep<MaskImageType>(m_Working_Support);
+  // Get the current support 
+  StartNewStep("[Station 3P] Get the current 3P suppport");
+  m_Working_Support = m_ListOfSupports["S3P"];
   m_ListOfStations["3P"] = m_Working_Support;
-}
-//--------------------------------------------------------------------
-
-
-//--------------------------------------------------------------------
-template <class ImageType>
-void 
-clitk::ExtractLymphStationsFilter<ImageType>::
-ExtractStation_3P_Remove_Structures() 
-{
-  /*
-    3 - (sup) remove Aorta, VB, subcl
-    not LR subcl ! -> a séparer LR ?
-    (inf) remove Eso, Aorta, Azygousvein
-  */
-
-  StartNewStep("[Station 3P] Remove some structures.");
-
-  Remove_Structures("Aorta");
-  Remove_Structures("VertebralBody");
-  Remove_Structures("SubclavianArtery");
-  Remove_Structures("Esophagus");
-  Remove_Structures("Azygousvein");
-  Remove_Structures("Thyroid");
-  Remove_Structures("VertebralArtery");
-
   StopCurrentStep<MaskImageType>(m_Working_Support);
-  m_ListOfStations["3P"] = m_Working_Support;
-}
-//--------------------------------------------------------------------
-
-
-//--------------------------------------------------------------------
-template <class ImageType>
-void 
-clitk::ExtractLymphStationsFilter<ImageType>::
-ExtractStation_3P_Ant_Limits() 
-{
-  /*
-    Ant Post limit : 
-
-    Anteriorly, it is in contact with the posterior aspect of Stations
-    1–2 superiorly (Fig. 2A–C) and with Stations 4R and 4L inferiorly
-    (Fig. 2D–I and 3A–C). The anterior limit of Station 3P is kept
-    posterior to the trachea, which is defined by an imaginary
-    horizontal line running along the posterior wall of the trachea
-    (Fig. 2B,E, red line). Posteriorly, it is delineated along the
-    anterior and lateral borders of the vertebral body until an
-    imaginary horizontal line running 1 cm posteriorly to the
-    anterior border of the vertebral body (Fig. 2D).
-
-    1 - post to the trachea : define an imaginary line just post the
-    Trachea and remove what is anterior. 
-
-  */
-  StartNewStep("[Station 3P] Ant limits with Trachea ");
 
-  // Load Trachea
-  MaskImagePointer Trachea = GetAFDB()->template GetImage<MaskImageType>("Trachea");
-  
-  // Crop like current support (need by SliceBySliceSetBackgroundFromLineSeparation after)
-  Trachea = 
-    clitk::ResizeImageLike<MaskImageType>(Trachea, m_Working_Support, GetBackgroundValue());
-  
-  // Slice by slice, determine the most post point of the trachea (A)
-  // and consider a second point on the same horizontal line (B)
-  std::vector<MaskImagePointType> p_A;
-  std::vector<MaskImagePointType> p_B;
-  std::vector<typename MaskSliceType::Pointer> slices;
-  clitk::ExtractSlices<MaskImageType>(Trachea, 2, slices);
-  MaskImagePointType p;
-  typename MaskSliceType::PointType sp;
-  for(uint i=0; i<slices.size(); i++) {
-    // First only consider the main CCL (trachea, not bronchus)
-    slices[i] = Labelize<MaskSliceType>(slices[i], 0, true, 100);
-    slices[i] = KeepLabels<MaskSliceType>(slices[i], GetBackgroundValue(), 
-                                          GetForegroundValue(), 1, 1, true);
-    // Find most posterior point
-    clitk::FindExtremaPointInAGivenDirection<MaskSliceType>(slices[i], GetBackgroundValue(), 
-                                                            1, false, sp);
-    clitk::PointsUtils<MaskImageType>::Convert2DTo3D(sp, Trachea, i, p);
-    p_A.push_back(p);
-    p[0] -= 20;
-    p_B.push_back(p);
-  }
-  clitk::WriteListOfLandmarks<MaskImageType>(p_A, "trachea-post.txt");
-
-  // Remove Ant part above those lines
-  clitk::SliceBySliceSetBackgroundFromLineSeparation<MaskImageType>(m_Working_Support, 
-                                                                    p_A, p_B,
-                                                                    GetBackgroundValue(), 
-                                                                    1, 10);
-  // End, release memory
-  GetAFDB()->template ReleaseImage<MaskImageType>("Trachea");
-  StopCurrentStep<MaskImageType>(m_Working_Support);
+  // Generic RelativePosition processes
+  m_ListOfStations["3P"] = this->ApplyRelativePositionList("Station_3P", m_ListOfStations["3P"]);
+  m_Working_Support = m_ListOfStations["3P"];
+  ExtractStation_8_Single_CCL_Limits(); // YES 8 !
+  ExtractStation_3P_Remove_Structures(); // after CCL
   m_ListOfStations["3P"] = m_Working_Support;
+
+  // Old stuff
+  // LR limits superiorly => not here for the moment because not clear in the def
+  // ExtractStation_3P_LR_sup_Limits_2(); //TODO
+  // ExtractStation_3P_LR_sup_Limits();   // old version to change
+  // ExtractStation_3P_LR_inf_Limits();  // <-- done in RelPosList 
+
+  // Store image filenames into AFDB 
+  writeImage<MaskImageType>(m_ListOfStations["3P"], "seg/Station3P.mhd");
+  GetAFDB()->SetImageFilename("Station3P", "seg/Station3P.mhd"); 
+  WriteAFDB();   
+  StopSubStep();
 }
 //--------------------------------------------------------------------
 
@@ -168,78 +52,12 @@ ExtractStation_3P_Ant_Limits()
 template <class ImageType>
 void 
 clitk::ExtractLymphStationsFilter<ImageType>::
-ExtractStation_3P_Post_Limits() 
+ExtractStation_3P_Remove_Structures() 
 {
-  /*
-    Ant Post limit : 
-
-    Anteriorly, it is in contact with the posterior aspect of Stations
-    1–2 superiorly (Fig. 2A–C) and with Stations 4R and 4L inferiorly
-    (Fig. 2D–I and 3A–C). The anterior limit of Station 3P is kept
-    posterior to the trachea, which is defined by an imaginary
-    horizontal line running along the posterior wall of the trachea
-    (Fig. 2B,E, red line). Posteriorly, it is delineated along the
-    anterior and lateral borders of the vertebral body until an
-    imaginary horizontal line running 1 cm posteriorly to the
-    anterior border of the vertebral body (Fig. 2D).
-
-    2 - post to the trachea : define an imaginary line just post the
-    Trachea and remove what is anterior. 
-
-  */
-  StartNewStep("[Station 3P] Post limits with VertebralBody ");
-
-  // Load VertebralBody
-  MaskImagePointer VertebralBody = GetAFDB()->template GetImage<MaskImageType>("VertebralBody");
-  
-  // Crop like current support (need by SliceBySliceSetBackgroundFromLineSeparation after)
-  VertebralBody = clitk::ResizeImageLike<MaskImageType>(VertebralBody, m_Working_Support, GetBackgroundValue());
-  
-  writeImage<MaskImageType>(VertebralBody, "vb.mhd");
-  
-  // Compute VertebralBody most Ant position (again because slices
-  // changes). Slice by slice, determine the most post point of the
-  // trachea (A) and consider a second point on the same horizontal
-  // line (B)
-  std::vector<MaskImagePointType> p_A;
-  std::vector<MaskImagePointType> p_B;
-  std::vector<typename MaskSliceType::Pointer> slices;
-  clitk::ExtractSlices<MaskImageType>(VertebralBody, 2, slices);
-  MaskImagePointType p;
-  typename MaskSliceType::PointType sp;
-  for(uint i=0; i<slices.size(); i++) {
-    // Find most anterior point
-    bool found = clitk::FindExtremaPointInAGivenDirection<MaskSliceType>(slices[i], GetBackgroundValue(), 
-                                                                         1, true, sp);
-    
-    // If the VertebralBody stop superiorly before the end of
-    // m_Working_Support, we consider the same previous point.
-    if (!found) {
-      p = p_A.back();
-      p[2] += VertebralBody->GetSpacing()[2];
-      p_A.push_back(p);
-      p = p_B.back();
-      p[2] += VertebralBody->GetSpacing()[2];
-      p_B.push_back(p);
-    }
-    else {
-      clitk::PointsUtils<MaskImageType>::Convert2DTo3D(sp, VertebralBody, i, p);
-      p[1] += 10; // Consider 10 mm more post
-      p_A.push_back(p);
-      p[0] -= 20;
-      p_B.push_back(p);
-    }
-  }
-  clitk::WriteListOfLandmarks<MaskImageType>(p_A, "vb-ant.txt");
-  
-
-  // Remove Ant part above those lines
-  clitk::SliceBySliceSetBackgroundFromLineSeparation<MaskImageType>(m_Working_Support, 
-                                                                    p_A, p_B,
-                                                                    GetBackgroundValue(), 
-                                                                    1, -10);
-  writeImage<MaskImageType>(m_Working_Support, "a.mhd");
-
+  StartNewStep("[Station 3P] Remove some structures.");
+  Remove_Structures("3P", "Esophagus");
+  Remove_Structures("3P", "Thyroid");
+  Remove_Structures("3P", "VertebralArtery"); // (inside the station)
   StopCurrentStep<MaskImageType>(m_Working_Support);
   m_ListOfStations["3P"] = m_Working_Support;
 }
@@ -275,8 +93,8 @@ ExtractStation_3P_LR_sup_Limits()
   Trachea = clitk::ResizeImageLike<MaskImageType>(Trachea, m_Working_Support, GetBackgroundValue());
   SubclavianArtery = clitk::ResizeImageLike<MaskImageType>(SubclavianArtery, m_Working_Support, GetBackgroundValue());
   
-  writeImage<MaskImageType>(Trachea, "tr.mhd");
-  writeImage<MaskImageType>(SubclavianArtery, "sca.mhd");
+  // writeImage<MaskImageType>(Trachea, "tr.mhd");
+  // writeImage<MaskImageType>(SubclavianArtery, "sca.mhd");
   
   // Get list of slices
   std::vector<MaskSlicePointer> slices_support;
@@ -347,7 +165,7 @@ ExtractStation_3P_LR_sup_Limits()
         relPosFilter->SetBackgroundValue(GetBackgroundValue());
         relPosFilter->SetInput(slices_support[i]); 
         relPosFilter->SetInputObject(object); 
-        relPosFilter->AddOrientationTypeString("R");
+        relPosFilter->AddOrientationTypeString("RightTo");
         relPosFilter->SetInverseOrientationFlag(true);
         //      relPosFilter->SetIntermediateSpacing(3);
         relPosFilter->SetIntermediateSpacingFlag(false);
@@ -363,7 +181,7 @@ ExtractStation_3P_LR_sup_Limits()
         relPosFilter->SetBackgroundValue(GetBackgroundValue());
         relPosFilter->SetInput(slices_support[i]); 
         relPosFilter->SetInputObject(object); 
-        relPosFilter->AddOrientationTypeString("A");
+        relPosFilter->AddOrientationTypeString("AntTo");
         relPosFilter->SetInverseOrientationFlag(true);
         //      relPosFilter->SetIntermediateSpacing(3);
         relPosFilter->SetIntermediateSpacingFlag(false);
@@ -442,29 +260,6 @@ template <class ImageType>
 void 
 clitk::ExtractLymphStationsFilter<ImageType>::
 ExtractStation_3P_LR_sup_Limits_2() 
-{
-  /*
-    Use VertebralArtery to limit.
-    
-
-  StartNewStep("[Station 3P] Left/Right limits with VertebralArtery");
-
-  // Load structures
-  MaskImagePointer VertebralArtery = GetAFDB()->template GetImage<MaskImageType>("VertebralArtery");
-
-  clitk::AndNot<MaskImageType>(m_Working_Support, VertebralArtery);
-
-  StopCurrentStep<MaskImageType>(m_Working_Support);
-  m_ListOfStations["3P"] = m_Working_Support;
-  */
-}
-//--------------------------------------------------------------------
-
-//--------------------------------------------------------------------
-template <class ImageType>
-void 
-clitk::ExtractLymphStationsFilter<ImageType>::
-ExtractStation_3P_LR_inf_Limits() 
 {
   /*
     "On the right side, the limit is defined by the air–soft-tissue
@@ -472,44 +267,16 @@ ExtractStation_3P_LR_inf_Limits()
     interface superiorly (Fig. 2A–C) and the aorta inferiorly
     (Figs. 2D–I and 3A–C)."
 
-    inf : not Right to Azygousvein    
+    sup : 
+    Resizelike support : Trachea, SubclavianArtery
+    Trachea, slice by slice, get centroid trachea
+    SubclavianArtery, slice by slice, CCL
+    prendre la 1ère à L et R, not at Left
+    
   */
-  StartNewStep("[Station 3P] Left/Right limits (inferior part) with Azygousvein and Aorta");
-
-  // Load structures
-  MaskImagePointer AzygousVein = GetAFDB()->template GetImage<MaskImageType>("AzygousVein");
-  MaskImagePointer Aorta = GetAFDB()->template GetImage<MaskImageType>("Aorta");
-
-  typedef clitk::AddRelativePositionConstraintToLabelImageFilter<MaskImageType> RelPosFilterType;
-  typename RelPosFilterType::Pointer relPosFilter = RelPosFilterType::New();
-  relPosFilter->VerboseStepFlagOff();
-  relPosFilter->WriteStepFlagOff();
-  relPosFilter->SetBackgroundValue(GetBackgroundValue());
-  relPosFilter->SetInput(m_Working_Support); 
-  relPosFilter->SetInputObject(AzygousVein); 
-  relPosFilter->AddOrientationTypeString("R");
-  relPosFilter->SetInverseOrientationFlag(true);
-  //      relPosFilter->SetIntermediateSpacing(3);
-  relPosFilter->SetIntermediateSpacingFlag(false);
-  relPosFilter->SetFuzzyThreshold(0.7);
-  relPosFilter->AutoCropFlagOn();
-  relPosFilter->Update();
-  m_Working_Support = relPosFilter->GetOutput();
-
-  writeImage<MaskImageType>(m_Working_Support, "before-L-aorta.mhd");
-  relPosFilter->SetInput(m_Working_Support); 
-  relPosFilter->SetInputObject(Aorta); 
-  relPosFilter->AddOrientationTypeString("L");
-  relPosFilter->SetInverseOrientationFlag(true);
-  //      relPosFilter->SetIntermediateSpacing(3);
-  relPosFilter->SetIntermediateSpacingFlag(false);
-  relPosFilter->SetFuzzyThreshold(0.7);
-  relPosFilter->AutoCropFlagOn();
-  relPosFilter->Update();
-  m_Working_Support = relPosFilter->GetOutput();
-  writeImage<MaskImageType>(m_Working_Support, "after-L-aorta.mhd");
+  //  StartNewStep("[Station 3P] Left/Right limits (superior part) ");
+  
 
-  StopCurrentStep<MaskImageType>(m_Working_Support);
-  m_ListOfStations["3P"] = m_Working_Support;
 }
 //--------------------------------------------------------------------
+