X-Git-Url: https://git.creatis.insa-lyon.fr/pubgit/?a=blobdiff_plain;f=segmentation%2FclitkExtractLymphStation_7.txx;h=d6df42895faa021bd9298d4dc95cc11bdbc47402;hb=5a7da4aedae5c204bc55c187717193e5950f9a44;hp=7bb4643cfcae9fcd6dd11ddc1060cdfee07db359;hpb=a360b70353c02d20482d950c96ba7b289deca184;p=clitk.git diff --git a/segmentation/clitkExtractLymphStation_7.txx b/segmentation/clitkExtractLymphStation_7.txx index 7bb4643..d6df428 100644 --- a/segmentation/clitkExtractLymphStation_7.txx +++ b/segmentation/clitkExtractLymphStation_7.txx @@ -11,6 +11,28 @@ ExtractStation_7_SetDefaultValues() SetFuzzyThreshold("7", "RightPulmonaryArtery", 0.3); SetFuzzyThreshold("7", "LeftPulmonaryArtery", 0.5); SetFuzzyThreshold("7", "SVC", 0.2); + SetS7_UseMostInferiorPartOnlyFlag(false); +} +//-------------------------------------------------------------------- + + +//-------------------------------------------------------------------- +template +void +clitk::ExtractLymphStationsFilter:: +ExtractStation_7() { + if (CheckForStation("7")) { + ExtractStation_7_SI_Limits(); + ExtractStation_7_RL_Interior_Limits(); + + // ExtractStation_7_Posterior_Limits(); + ExtractStation_8_Single_CCL_Limits(); + ExtractStation_7_Remove_Structures(); + // Store image filenames into AFDB + writeImage(m_ListOfStations["7"], "seg/Station7.mhd"); + GetAFDB()->SetImageFilename("Station7", "seg/Station7.mhd"); + WriteAFDB(); + } } //-------------------------------------------------------------------- @@ -21,44 +43,212 @@ void clitk::ExtractLymphStationsFilter:: ExtractStation_7_SI_Limits() { - StartNewStep("[Station7] Inf/Sup mediastinum limits with carina/LLLBronchus"); + StartNewStep("[Station7] Inf/Sup mediastinum limits with carina/LLL-RMLBronchus"); // Get Inputs MaskImagePointer Trachea = GetAFDB()->template GetImage ("Trachea"); + + // Create line from A to B with + // A = upper border of LLL at left + // B = lower border of bronchus intermedius (BI) or RightMiddleLobeBronchus + ImagePointType A; + ImagePointType B; + FindLineForS7S8Separation(A, B); + + // // if option -> replace A[0] with B[0] + // if (GetS7_UseMostInferiorPartOnlyFlag()) { + // A[0] = B[0]; + // } + + // Use line to remove the inferior part + m_Working_Support = + SliceBySliceSetBackgroundFromSingleLine(m_Working_Support, GetBackgroundValue(), + A, B, 2, 0, false); + + // Get the CarinaZ position + double m_CarinaZ = FindCarina(); - // We suppoe that CarinaZ was already computed (S8) - double m_CarinaZ = GetAFDB()->GetDouble("CarinaZ"); + // Crop support + m_Working_Support = + clitk::CropImageAlongOneAxis(m_Working_Support, 2, + A[2], m_CarinaZ, true, + GetBackgroundValue()); + // Crop trachea + m_Working_Trachea = + clitk::CropImageAlongOneAxis(Trachea, 2, + A[2], m_CarinaZ, true, + GetBackgroundValue()); - // double m_OriginOfRightMiddleLobeBronchusZ = GetAFDB()->GetPoint3D("OriginOfRightMiddleLobeBronchus", 2); - // DD(m_OriginOfRightMiddleLobeBronchusZ); - MaskImagePointer UpperBorderOfLLLBronchus = GetAFDB()->template GetImage("UpperBorderOfLLLBronchus"); + StopCurrentStep(m_Working_Support); + m_ListOfStations["7"] = m_Working_Support; +} +//-------------------------------------------------------------------- - // Search most inf point (WHY ? IS IT THE RIGHT STRUCTURE ??) - MaskImagePointType ps = UpperBorderOfLLLBronchus->GetOrigin(); // initialise to avoid warning - clitk::FindExtremaPointInAGivenDirection(UpperBorderOfLLLBronchus, GetBackgroundValue(), 2, true, ps); - double m_UpperBorderOfLLLBronchusZ = ps[2]; +//-------------------------------------------------------------------- +template +void +clitk::ExtractLymphStationsFilter:: +ExtractStation_7_RL_Interior_Limits() +{ + // ---------------------------------------------------------------- + StartNewStep("[Station7] RL limits with bronchi"); + /* - std::vector centroids; - clitk::ComputeCentroids(UpperBorderOfLLLBronchus, GetBackgroundValue(), centroids); - double m_UpperBorderOfLLLBronchusZ = centroids[1][2]; - DD(m_UpperBorderOfLLLBronchusZ) + Slice by Slice, consider most Left point of the Right + bronchus. Remove the Ant/Right corner */ - /* Crop support */ + // First consider bronchi + FindLeftAndRightBronchi(); + m_RightBronchus = GetAFDB()->template GetImage ("RightBronchus"); + m_LeftBronchus = GetAFDB()->template GetImage ("LeftBronchus"); + + // Resize like m_Working_Support + m_LeftBronchus = + clitk::ResizeImageLike(m_LeftBronchus, m_Working_Support, GetBackgroundValue()); + m_RightBronchus = + clitk::ResizeImageLike(m_RightBronchus, m_Working_Support, GetBackgroundValue()); + + // Extract slices, Label, compute centroid, keep most central connected component + std::vector slices_leftbronchus; + std::vector slices_rightbronchus; + std::vector slices_support; + clitk::ExtractSlices(m_LeftBronchus, 2, slices_leftbronchus); + clitk::ExtractSlices(m_RightBronchus, 2, slices_rightbronchus); + clitk::ExtractSlices(m_Working_Support, 2, slices_support); + + // Keep only the CCL of the bronchus with the closest to the center + // Loop on slices for left bronchus + for(uint i=0; i(slices_leftbronchus[i], 0, false, 10); + std::vector c; + clitk::ComputeCentroids(slices_leftbronchus[i], GetBackgroundValue(), c); + if (c.size() > 1) { + double most_at_left = c[1][0]; + int most_at_left_index=1; + for(uint j=1; j(slices_leftbronchus[i], most_at_left_index, + most_at_left_index, GetBackgroundValue(), GetForegroundValue()); + } // end c.size + } + + // Loop on slices for right bronchus + for(uint i=0; i(slices_rightbronchus[i], 0, false, 10); + std::vector c; + clitk::ComputeCentroids(slices_rightbronchus[i], GetBackgroundValue(), c); + if (c.size() > 1) { + double most_at_right = c[1][0]; + int most_at_right_index=1; + for(uint j=1; j most_at_right) { + most_at_right = c[j][0]; + most_at_right_index = j; + } + } + // Put all other CCL to Background + slices_rightbronchus[i] = + clitk::Binarize(slices_rightbronchus[i], most_at_right_index, + most_at_right_index, GetBackgroundValue(), GetForegroundValue()); + } // end c.size + } + + // Joint slices + m_LeftBronchus = clitk::JoinSlices(slices_leftbronchus, m_LeftBronchus, 2); + m_RightBronchus = clitk::JoinSlices(slices_rightbronchus, m_RightBronchus, 2); + + // For Right bronchus, Find most Left point. Remove corner Ant/Right corner + for(uint i=0; i(slices_rightbronchus[i], GetBackgroundValue(), 0, false, p_left); + if (b) { + b = clitk::FindExtremaPointInAGivenDirection(slices_rightbronchus[i], GetBackgroundValue(), 1, false, p_post); + } + if (b) { + MaskSlicePointType p = p_left; + p[1] = p_post[1]; + MaskSliceIndexType pi; + slices_rightbronchus[i]->TransformPhysicalPointToIndex(p, pi); + + // Build region to remove + MaskSliceRegionType region = slices_rightbronchus[i]->GetLargestPossibleRegion(); + MaskSliceIndexType index = region.GetIndex(); + MaskSliceSizeType size = region.GetSize(); + size[0] = pi[0] - index[0]; + size[1] = pi[1] - index[1]; + region.SetSize(size); + + // Fill region with Background value + clitk::FillRegionWithValue(slices_support[i], GetBackgroundValue(), region); + } + } + + // For Left bronchus, Find most Right point. Remove corner Ant/Left corner + for(uint i=0; i(slices_leftbronchus[i], GetBackgroundValue(), 0, true, p_right); + if (b) { + b = clitk::FindExtremaPointInAGivenDirection(slices_rightbronchus[i], GetBackgroundValue(), 1, false, p_post); + } + if (b) { + MaskSlicePointType p = p_right; + p[1] = p_post[1]; + MaskSliceIndexType pi; + slices_leftbronchus[i]->TransformPhysicalPointToIndex(p, pi); + + /* typedef itk::ImageRegionIterator IteratorType; + IteratorType iter(input, region); + iter.GoToBegin(); + while (!iter.IsAtEnd()) { + MaskSliceIndexType index = iter.GetIndex(); + if (index[0] > pi[0]) && (index[1] > pi[1]) iter.Set(GetBackgroundValue()); + + ++iter; + } + */ + + + // Build region to remove + MaskSliceRegionType region = slices_leftbronchus[i]->GetLargestPossibleRegion(); + MaskSliceIndexType index = region.GetIndex(); + MaskSliceSizeType size = region.GetSize(); + index[0] = pi[0]; + size[0] = slices_leftbronchus[i]->GetLargestPossibleRegion().GetSize()[0] - pi[0]; + size[1] = pi[1] - index[1]; + region.SetSize(size); + region.SetIndex(index); + + // Fill region with Background value + clitk::FillRegionWithValue(slices_support[i], GetBackgroundValue(), region); + } + } + + m_Working_Support = clitk::JoinSlices(slices_support, m_Working_Support, 2); + + // Also remove what is at right of the Right bronchus (left respectively) m_Working_Support = - clitk::CropImageAlongOneAxis(m_Working_Support, 2, - m_UpperBorderOfLLLBronchusZ, - m_CarinaZ, true, - GetBackgroundValue()); - /* Crop trachea */ - m_Working_Trachea = - clitk::CropImageAlongOneAxis(Trachea, 2, - m_UpperBorderOfLLLBronchusZ, - m_CarinaZ, true, - GetBackgroundValue()); + clitk::SliceBySliceRelativePosition(m_Working_Support, m_LeftBronchus, 2, + GetFuzzyThreshold("7", "Bronchi"), "NotLeftTo", + false, 3, false); + m_Working_Support = + clitk::SliceBySliceRelativePosition(m_Working_Support, m_RightBronchus, 2, + GetFuzzyThreshold("7", "Bronchi"), "NotRightTo", + false, 3, false); + + // SECOND PART StopCurrentStep(m_Working_Support); - m_ListOfStations["7"] = m_Working_Support; } //-------------------------------------------------------------------- @@ -67,7 +257,7 @@ ExtractStation_7_SI_Limits() template void clitk::ExtractLymphStationsFilter:: -ExtractStation_7_RL_Limits() +ExtractStation_7_RL_Limits_OLD() { // ---------------------------------------------------------------- StartNewStep("[Station7] Limits with bronchus : RightTo the left bronchus"); @@ -82,6 +272,10 @@ ExtractStation_7_RL_Limits() clitk::ExtractSlices(m_LeftBronchus, 2, slices_leftbronchus); clitk::ExtractSlices(m_RightBronchus, 2, slices_rightbronchus); + // Version #1 with limit = centroid of the bronchus (OUTDATED) + // Step1 = keep only the CCL of the bronchus with the closest to the center + // Step2 = SliceBySlice Rel pos to both bronchi + // Loop on slices for(uint i=0; i(slices_leftbronchus[i], 0, false, 10); @@ -160,7 +354,7 @@ ExtractStation_7_RL_Limits() sliceRelPosFilter->AddOrientationTypeString("NotAntTo"); sliceRelPosFilter->SetIntermediateSpacingFlag(true); sliceRelPosFilter->SetIntermediateSpacing(3); - sliceRelPosFilter->SetUniqueConnectedComponentBySlice(false); + sliceRelPosFilter->SetUniqueConnectedComponentBySliceFlag(false); sliceRelPosFilter->SetAutoCropFlag(false); sliceRelPosFilter->IgnoreEmptySliceObjectFlagOn(); sliceRelPosFilter->Update(); @@ -186,7 +380,7 @@ ExtractStation_7_RL_Limits() sliceRelPosFilter->AddOrientationTypeString("NotPostTo"); sliceRelPosFilter->SetIntermediateSpacingFlag(true); sliceRelPosFilter->SetIntermediateSpacing(3); - sliceRelPosFilter->SetUniqueConnectedComponentBySlice(false); + sliceRelPosFilter->SetUniqueConnectedComponentBySliceFlag(false); sliceRelPosFilter->SetAutoCropFlag(false); sliceRelPosFilter->IgnoreEmptySliceObjectFlagOn(); sliceRelPosFilter->Update(); @@ -209,7 +403,7 @@ ExtractStation_7_RL_Limits() sliceRelPosFilter->AddOrientationTypeString("NotAntTo"); sliceRelPosFilter->SetIntermediateSpacingFlag(true); sliceRelPosFilter->SetIntermediateSpacing(3); - sliceRelPosFilter->SetUniqueConnectedComponentBySlice(false); + sliceRelPosFilter->SetUniqueConnectedComponentBySliceFlag(false); sliceRelPosFilter->SetAutoCropFlag(false); sliceRelPosFilter->IgnoreEmptySliceObjectFlagOn(); sliceRelPosFilter->Update(); @@ -227,7 +421,7 @@ ExtractStation_7_RL_Limits() sliceRelPosFilter->AddOrientationTypeString("NotAntTo"); sliceRelPosFilter->SetIntermediateSpacingFlag(true); sliceRelPosFilter->SetIntermediateSpacing(3); - sliceRelPosFilter->SetUniqueConnectedComponentBySlice(false); + sliceRelPosFilter->SetUniqueConnectedComponentBySliceFlag(false); sliceRelPosFilter->SetAutoCropFlag(false); sliceRelPosFilter->IgnoreEmptySliceObjectFlagOn(); sliceRelPosFilter->Update(); @@ -245,7 +439,7 @@ ExtractStation_7_RL_Limits() sliceRelPosFilter->AddOrientationTypeString("NotAntTo"); sliceRelPosFilter->SetIntermediateSpacingFlag(true); sliceRelPosFilter->SetIntermediateSpacing(3); - sliceRelPosFilter->SetUniqueConnectedComponentBySlice(false); + sliceRelPosFilter->SetUniqueConnectedComponentBySliceFlag(false); sliceRelPosFilter->SetAutoCropFlag(true); sliceRelPosFilter->IgnoreEmptySliceObjectFlagOn(); sliceRelPosFilter->Update(); @@ -345,13 +539,22 @@ ExtractStation_7_Remove_Structures() Remove_Structures("7", "AzygousVein"); Remove_Structures("7", "Aorta"); - Remove_Structures("7", "Esophagus"); Remove_Structures("7", "RightPulmonaryArtery"); Remove_Structures("7", "LeftPulmonaryArtery"); Remove_Structures("7", "LeftSuperiorPulmonaryVein"); Remove_Structures("7", "PulmonaryTrunk"); Remove_Structures("7", "VertebralBody"); + // Keep only one CCL by slice (before removing Esophagus) + // DD("SliceBySliceKeepMainCCL"); + + // TODO -> replace by keep the one that contains point at the middle of the line between the bronchus + // -> new function "keep/select" the ccl that contains this point (2D) + + //m_Working_Support = clitk::SliceBySliceKeepMainCCL(m_Working_Support, GetBackgroundValue(), GetForegroundValue()); + + Remove_Structures("7", "Esophagus"); + // END StopCurrentStep(m_Working_Support); m_ListOfStations["7"] = m_Working_Support;