]> Creatis software - clitk.git/blobdiff - segmentation/clitkExtractLymphStation_4RL.txx
Merge branch 'master' of git.creatis.insa-lyon.fr:clitk
[clitk.git] / segmentation / clitkExtractLymphStation_4RL.txx
index a4478a6c4621a1b69804e9e8a9ef4e732b520ef3..8eb1fbdd2c19e4940b8cf51456dd9600a48892ad 100644 (file)
@@ -1,38 +1,36 @@
+
+
+//--------------------------------------------------------------------
+template <class ImageType>
+void 
+clitk::ExtractLymphStationsFilter<ImageType>::
+ExtractStation_4RL_SetDefaultValues()
+{
+}
+//--------------------------------------------------------------------
+
+
 //--------------------------------------------------------------------
 template <class TImageType>
 void 
 clitk::ExtractLymphStationsFilter<TImageType>::
-ExtractStation_4RL_SI_Limits() 
-{
-  /* SupInf limits : 
-  - top of aortic arch
-  - ends at the upper lobe bronchus or where the right pulmonary artery crosses the midline of the mediastinum
-  */
-
-  // Local variables
-  double m_TopOfAorticArchInMM;
-  double m_UpperLobeBronchusZPositionInMM;
-  double m_RightPulmoArteyrCrossesMidMediastinumZPositionInMM;
-
-  // Get Inputs
-  m_TopOfAorticArchInMM = GetAFDB()->GetPoint3D("topOfAorticArch", 2);
-  DD(m_TopOfAorticArchInMM);
-  m_UpperLobeBronchusZPositionInMM = GetAFDB()->GetPoint3D("rightUpperLobeBronchus", 2);
-  DD(m_UpperLobeBronchusZPositionInMM);
-  m_RightPulmoArteyrCrossesMidMediastinumZPositionInMM = GetAFDB()->GetPoint3D("rightPulmoArteryCrossesMidMediastinum", 2);
-  DD(m_RightPulmoArteyrCrossesMidMediastinumZPositionInMM);
-
-  /* Crop support */
-  StartNewStep("Inf/Sup mediastinum limits with aortic arch/upperLBronchus");
-  double inf = std::max(m_UpperLobeBronchusZPositionInMM, m_RightPulmoArteyrCrossesMidMediastinumZPositionInMM);
-  m_Working_Support = 
-    clitk::CropImageAlongOneAxis<MaskImageType>(m_Support, 2, 
-                                                inf,
-                                                m_TopOfAorticArchInMM, true,
-                                                GetBackgroundValue());
-  StopCurrentStep<MaskImageType>(m_Working_Support);
+ExtractStation_4R() {
+  if (!CheckForStation("4R")) return;
+  StartNewStep("Stations 4R");
+  StartSubStep(); 
 
-  m_Station4RL = m_Working_Support;
+  // Get the current support 
+  StartNewStep("[Station 4R] Get the current 4RL suppport");
+  m_ListOfStations["4R"] = m_ListOfSupports["S4R"];
+  StopCurrentStep<MaskImageType>(m_ListOfStations["4R"]);
+    
+  // Generic RelativePosition processes
+  m_ListOfStations["4R"] = this->ApplyRelativePositionList("Station_4R", m_ListOfStations["4R"]);
+
+  // Store image filenames into AFDB 
+  WriteImageStation("4R");
+  StopSubStep();
+  ComputeOverlapWithRef("4R");
 }
 //--------------------------------------------------------------------
 
@@ -41,60 +39,119 @@ ExtractStation_4RL_SI_Limits()
 template <class TImageType>
 void 
 clitk::ExtractLymphStationsFilter<TImageType>::
-ExtractStation_4RL_LR_Limits() 
-{
-  // 4R first 
+ExtractStation_4L() {
+  if (!CheckForStation("4L")) return;
+  StartNewStep("Stations 4L");
+  StartSubStep(); 
 
-  // Left : midline of the trachea
-  // Right : "- upper part : contained within the pleural envelope
-  //- intermediate section : medial to the superior vena cava and the arch of the azygos vein
-  // - very caudal part : right upper lobe pulmonary vein"
-  // AAV ??
-  
-  // Constraint at right from the SVC
-  MaskImagePointer svc = GetAFDB()->template GetImage<MaskImageType>("SVC");
-  typedef clitk::AddRelativePositionConstraintToLabelImageFilter<MaskImageType> RelPosFilterType;
-  typename RelPosFilterType::Pointer relPosFilter = RelPosFilterType::New();
-  relPosFilter->SetCurrentStepBaseId(this->GetCurrentStepId());
-  relPosFilter->VerboseStepOff();
-  relPosFilter->WriteStepOff();
-  relPosFilter->SetInput(m_Working_Support); 
-  relPosFilter->SetInputObject(svc); 
-  relPosFilter->SetOrientationType(RelPosFilterType::RightTo);
-  relPosFilter->SetIntermediateSpacing(2);
-  relPosFilter->SetFuzzyThreshold(0.3);
-  relPosFilter->Update();
-  m_Working_Support = relPosFilter->GetOutput();
-  m_Station4RL = m_Working_Support;
-  
-  // Left -> midline of the trachea
-  // slice by slice, find X coord of 2D centroid (?)
-  // check with previous line in order to not move too fast
-  
-  // skeleton ? -> need path description ? follow from slice to slice
-  // OR CENTROID at each slice ?
+  // Get the current support 
+  StartNewStep("[Station 4L] Get the current 4RL suppport");
+  m_ListOfStations["4L"] = m_ListOfSupports["S4L"];
+  StopCurrentStep<MaskImageType>(m_ListOfStations["4L"]);
+    
+  // Generic RelativePosition processes
+  m_ListOfStations["4L"] = this->ApplyRelativePositionList("Station_4L", m_ListOfStations["4L"]);
+
+  // Separation Ant/Post
+  m_Working_Support = m_ListOfStations["4L"];
+  ExtractStation_S4L_S5_Limits_Aorta_LeftPulmonaryArtery(10);
+  m_ListOfStations["4L"] = m_Working_Support;
   
-  // Crop trachea
-  // Extract list of slice from trachea
-  // Loop slice -> Get centroid crop along line (BB limit) -> two supports
+  // Keep only one single CCL by slice
+  StartNewStep("[Station 4L] Keep only one CCL by slice");  
+  m_ListOfStations["4L"] = SliceBySliceKeepMainCCL<MaskImageType>(m_ListOfStations["4L"], 
+                                                                  GetBackgroundValue(), 
+                                                                  GetForegroundValue());
+  StopCurrentStep<MaskImageType>(m_ListOfStations["4L"]);
 
-  // Crop the trachea like the current support
-  MaskImagePointer crop_trachea = 
-    clitk::ResizeImageLike<MaskImageType>(m_Trachea, m_Working_Support, GetBackgroundValue());
-  writeImage<MaskImageType>(crop_trachea, "croptrachea.mhd");
+  // Store image filenames into AFDB 
+  WriteImageStation("4L");
+  StopSubStep();
+  ComputeOverlapWithRef("4L");
+}
+//--------------------------------------------------------------------
+
+
+//--------------------------------------------------------------------
+template <class TImageType>
+void 
+clitk::ExtractLymphStationsFilter<TImageType>::
+ExtractStation_S4L_S5_Limits_Aorta_LeftPulmonaryArtery(int KeepPoint) 
+{
+  // ----------------------------------------------------------
+  StartNewStep("[Station 4L] Limits between Asc and Desc Aorta, and with LeftPulmonaryArtery ");
+
+  // Separate Aorta into DescendingAorta AscendingAorta
+  MaskImagePointer AscendingAorta = GetAFDB()->template GetImage<MaskImageType>("AscendingAorta");
+  MaskImagePointer DescendingAorta = GetAFDB()->template GetImage<MaskImageType>("DescendingAorta");  
+
+  // Crop like support (inferiorly)
+  m_Working_Support = clitk::AutoCrop<MaskImageType>(m_Working_Support, GetBackgroundValue());
+  AscendingAorta = 
+    clitk::ResizeImageLike<MaskImageType>(AscendingAorta, m_Working_Support, GetBackgroundValue());
+  DescendingAorta = 
+    clitk::ResizeImageLike<MaskImageType>(DescendingAorta, m_Working_Support, GetBackgroundValue());
+
+  // Crop superior part (when AscendingAorta and DescendingAorta join)
+  MaskImagePointType p;
+  clitk::FindExtremaPointInAGivenDirection<MaskImageType>(AscendingAorta, 
+                                                          GetBackgroundValue(), 2, false, p);
+  double max = p[2]+AscendingAorta->GetSpacing()[2];
+  AscendingAorta = 
+    clitk::CropImageRemoveGreaterThan<MaskImageType>(AscendingAorta, 2, max, false, GetBackgroundValue());
+  DescendingAorta = 
+    clitk::CropImageRemoveGreaterThan<MaskImageType>(DescendingAorta, 2, max, false, GetBackgroundValue());
 
-  // Extract all the slices
-  typedef clitk::ExtractSliceFilter<MaskImageType> ExtractSliceFilterType;
-  typedef typename ExtractSliceFilterType::SliceType SliceType;
-  typename ExtractSliceFilterType::Pointer 
-    extractSliceFilter = ExtractSliceFilterType::New();
-  extractSliceFilter->SetInput(crop_trachea);
-  extractSliceFilter->SetDirection(2);
-  extractSliceFilter->Update();
-  std::vector<typename SliceType::Pointer> trachea_slices;
-  extractSliceFilter->GetOutputSlices(trachea_slices);
+  // Crop inferior part, where LeftPulmonaryArtery start
+  MaskImagePointer AscendingAortaCopy = clitk::Clone<MaskImageType>(AscendingAorta);
+  MaskImagePointer LeftPulmonaryArtery = GetAFDB()->template GetImage<MaskImageType>("LeftPulmonaryArtery");
+  clitk::FindExtremaPointInAGivenDirection<MaskImageType>(LeftPulmonaryArtery, 
+                                                          GetBackgroundValue(), 2, false, p);
+  max = p[2]+LeftPulmonaryArtery->GetSpacing()[2];
+  AscendingAorta = 
+    clitk::CropImageRemoveLowerThan<MaskImageType>(AscendingAorta, 2, max, false, GetBackgroundValue());
+  DescendingAorta = 
+    clitk::CropImageRemoveLowerThan<MaskImageType>(DescendingAorta, 2, max, false, GetBackgroundValue());
 
+  // Find closest points
+  std::vector<MaskImagePointType> A;
+  std::vector<MaskImagePointType> B;
+  clitk::SliceBySliceBuildLineSegmentAccordingToMinimalDistanceBetweenStructures<MaskImageType>(AscendingAorta, 
+                                                                                                DescendingAorta, 
+                                                                                                GetBackgroundValue(), 
+                                                                                                2, A, B);
+  // Separate according to AB lines
+  // clitk::WriteListOfLandmarks<MaskImageType>(A, "A.txt");
+  // clitk::WriteListOfLandmarks<MaskImageType>(B, "B.txt");
+  clitk::SliceBySliceSetBackgroundFromLineSeparation<MaskImageType>(m_Working_Support, A, B,
+                                                                    GetBackgroundValue(), 
+                                                                    1, KeepPoint); // Keep point along axis 1
 
+  // Now, same principle between AscendingAorta and LeftPulmonaryArtery
+  AscendingAorta = 
+    clitk::ResizeImageLike<MaskImageType>(AscendingAortaCopy, m_Working_Support, GetBackgroundValue());
+  LeftPulmonaryArtery = 
+    clitk::ResizeImageLike<MaskImageType>(LeftPulmonaryArtery, m_Working_Support, GetBackgroundValue());
+  AscendingAorta = 
+    clitk::CropImageRemoveGreaterThan<MaskImageType>(AscendingAorta, 2, max, false, GetBackgroundValue());
+  LeftPulmonaryArtery = 
+    clitk::CropImageRemoveGreaterThan<MaskImageType>(LeftPulmonaryArtery, 2, max, false, GetBackgroundValue());
+  A.clear();
+  B.clear();
+  clitk::SliceBySliceBuildLineSegmentAccordingToMinimalDistanceBetweenStructures<MaskImageType>(AscendingAorta, 
+                                                                                                LeftPulmonaryArtery, 
+                                                                                                GetBackgroundValue(), 
+                                                                                                2, A, B);
+  clitk::SliceBySliceSetBackgroundFromLineSeparation<MaskImageType>(m_Working_Support, A, B,
+                                                                    GetBackgroundValue(), 
+                                                                    1, KeepPoint); // Keep point along axis 1
 
+  // AutoCrop
+  m_Working_Support = clitk::AutoCrop<MaskImageType>(m_Working_Support, GetBackgroundValue());
+
+  // End
+  StopCurrentStep<MaskImageType>(m_Working_Support);
 }
 //--------------------------------------------------------------------
+
+