X-Git-Url: https://git.creatis.insa-lyon.fr/pubgit/?a=blobdiff_plain;f=segmentation%2FclitkExtractLymphStation_3P.txx;h=712049809f464fc84c7f9db448c6669cfc59f03f;hb=338030186d56f371ab17cf99660bf92ab0dc07fb;hp=7f1d5bf7d9eaef0b2fc15c72c1b0c18d4e4b199c;hpb=573d80d0f7a17607d2ee883c21c940c0ba020282;p=clitk.git diff --git a/segmentation/clitkExtractLymphStation_3P.txx b/segmentation/clitkExtractLymphStation_3P.txx index 7f1d5bf..7120498 100644 --- a/segmentation/clitkExtractLymphStation_3P.txx +++ b/segmentation/clitkExtractLymphStation_3P.txx @@ -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 -#include //-------------------------------------------------------------------- template @@ -30,136 +10,41 @@ ExtractStation_3P_SetDefaultValues() //-------------------------------------------------------------------- -template +template void -clitk::ExtractLymphStationsFilter:: -ExtractStation_3P_SI_Limits() +clitk::ExtractLymphStationsFilter:: +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("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(m_Working_Support, 2, - m_CarinaZ, - m_ApexOfTheChest, true, - GetBackgroundValue()); + StartNewStep("Station 3P"); + StartSubStep(); - StopCurrentStep(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 -void -clitk::ExtractLymphStationsFilter:: -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(m_Working_Support); - m_ListOfStations["3P"] = m_Working_Support; -} -//-------------------------------------------------------------------- - - -//-------------------------------------------------------------------- -template -void -clitk::ExtractLymphStationsFilter:: -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("Trachea"); - - // Crop like current support (need by SliceBySliceSetBackgroundFromLineSeparation after) - Trachea = - clitk::ResizeImageLike(Trachea, m_Working_Support, GetBackgroundValue()); + // ExtractStation_3P_LR_inf_Limits(); // <-- done in RelPosList - // 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 p_A; - std::vector p_B; - std::vector slices; - clitk::ExtractSlices(Trachea, 2, slices); - MaskImagePointType p; - typename MaskSliceType::PointType sp; - for(uint i=0; i(slices[i], 0, true, 100); - slices[i] = KeepLabels(slices[i], GetBackgroundValue(), - GetForegroundValue(), 1, 1, true); - // Find most posterior point - clitk::FindExtremaPointInAGivenDirection(slices[i], GetBackgroundValue(), - 1, false, sp); - clitk::PointsUtils::Convert2DTo3D(sp, Trachea, i, p); - p_A.push_back(p); - p[0] -= 20; - p_B.push_back(p); - } - clitk::WriteListOfLandmarks(p_A, "trachea-post.txt"); - - // Remove Ant part above those lines - clitk::SliceBySliceSetBackgroundFromLineSeparation(m_Working_Support, - p_A, p_B, - GetBackgroundValue(), - 1, 10); - // End, release memory - GetAFDB()->template ReleaseImage("Trachea"); - StopCurrentStep(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 + + // Store image filenames into AFDB + writeImage(m_ListOfStations["3P"], "seg/Station3P.mhd"); + GetAFDB()->SetImageFilename("Station3P", "seg/Station3P.mhd"); + WriteAFDB(); + StopSubStep(); } //-------------------------------------------------------------------- @@ -168,78 +53,12 @@ ExtractStation_3P_Ant_Limits() template void clitk::ExtractLymphStationsFilter:: -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("VertebralBody"); - - // Crop like current support (need by SliceBySliceSetBackgroundFromLineSeparation after) - VertebralBody = clitk::ResizeImageLike(VertebralBody, m_Working_Support, GetBackgroundValue()); - - writeImage(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 p_A; - std::vector p_B; - std::vector slices; - clitk::ExtractSlices(VertebralBody, 2, slices); - MaskImagePointType p; - typename MaskSliceType::PointType sp; - for(uint i=0; i(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::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(p_A, "vb-ant.txt"); - - - // Remove Ant part above those lines - clitk::SliceBySliceSetBackgroundFromLineSeparation(m_Working_Support, - p_A, p_B, - GetBackgroundValue(), - 1, -10); - writeImage(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(m_Working_Support); m_ListOfStations["3P"] = m_Working_Support; } @@ -347,7 +166,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 +182,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 +261,6 @@ template void clitk::ExtractLymphStationsFilter:: 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("VertebralArtery"); - - clitk::AndNot(m_Working_Support, VertebralArtery); - - StopCurrentStep(m_Working_Support); - m_ListOfStations["3P"] = m_Working_Support; - */ -} -//-------------------------------------------------------------------- - -//-------------------------------------------------------------------- -template -void -clitk::ExtractLymphStationsFilter:: -ExtractStation_3P_LR_inf_Limits() { /* "On the right side, the limit is defined by the air–soft-tissue @@ -472,44 +268,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("AzygousVein"); - MaskImagePointer Aorta = GetAFDB()->template GetImage("Aorta"); - - typedef clitk::AddRelativePositionConstraintToLabelImageFilter 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(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(m_Working_Support, "after-L-aorta.mhd"); + // StartNewStep("[Station 3P] Left/Right limits (superior part) "); + - StopCurrentStep(m_Working_Support); - m_ListOfStations["3P"] = m_Working_Support; } //-------------------------------------------------------------------- +