X-Git-Url: https://git.creatis.insa-lyon.fr/pubgit/?a=blobdiff_plain;f=segmentation%2FclitkExtractLymphStation_3A.txx;h=50e394852123e6fec950275934f2de39978a84ec;hb=b2fd61648c05339dd302e102361c22c4b11d48ff;hp=3e7005906131aafe6eb42fa1ca6aa2436a5fc20e;hpb=907b0bad00cbf772fbf362879c74d673253f97bb;p=clitk.git diff --git a/segmentation/clitkExtractLymphStation_3A.txx b/segmentation/clitkExtractLymphStation_3A.txx index 3e70059..50e3948 100644 --- a/segmentation/clitkExtractLymphStation_3A.txx +++ b/segmentation/clitkExtractLymphStation_3A.txx @@ -1,7 +1,4 @@ -#include -#include - //-------------------------------------------------------------------- template void @@ -12,31 +9,148 @@ ExtractStation_3A_SetDefaultValues() //-------------------------------------------------------------------- +//-------------------------------------------------------------------- +template +void +clitk::ExtractLymphStationsFilter:: +ExtractStation_3A() +{ + if (!CheckForStation("3A")) return; + + StartNewStep("Station 3A"); + StartSubStep(); + + // Get the current support + StartNewStep("[Station 3A] Get the current 3A suppport"); + m_Working_Support = m_ListOfSupports["S3A"]; + m_ListOfStations["3A"] = m_Working_Support; + StopCurrentStep(m_Working_Support); + + ExtractStation_3A_Post_Left_Limits_With_Aorta_S5_Support(); + ExtractStation_3A_Post_Limits_With_Dilated_Aorta_S6_Support(); + ExtractStation_3A_AntPost_Superiorly(); + ExtractStation_3A_Remove_Structures(); + + // Generic RelativePosition processes + m_ListOfStations["3A"] = this->ApplyRelativePositionList("Station_3A", m_ListOfStations["3A"]); + + // Keep a single CCL + m_ListOfStations["3A"] = + clitk::SliceBySliceKeepMainCCL(m_ListOfStations["3A"], + GetBackgroundValue(), + GetForegroundValue()); + + // Store image filenames into AFDB + writeImage(m_ListOfStations["3A"], "seg/Station3A.mhd"); + GetAFDB()->SetImageFilename("Station3A", "seg/Station3A.mhd"); + WriteAFDB(); + StopSubStep(); +} +//-------------------------------------------------------------------- + + + //-------------------------------------------------------------------- template void clitk::ExtractLymphStationsFilter:: -ExtractStation_3A_SI_Limits() +ExtractStation_3A_Post_Left_Limits_With_Aorta_S5_Support() { - // Apex of the chest or Sternum & Carina. - StartNewStep("[Station 3A] Inf/Sup limits with Sternum and Carina"); + StartNewStep("[Station 3A] Post limits in S5 support according to Aorta"); - // Get Carina position (has been determined in Station8) - m_CarinaZ = GetAFDB()->GetDouble("CarinaZ"); + // Consider Aorta, remove Left/Post part ; only around S5 + // Get S5 support and Aorta + MaskImagePointer S5 = m_ListOfSupports["S5"]; + MaskImagePointer Aorta = GetAFDB()->template GetImage ("Aorta"); + Aorta = clitk::ResizeImageLike(Aorta, S5, GetBackgroundValue()); - // Get Sternum and search for the upper position - MaskImagePointer Sternum = GetAFDB()->template GetImage("Sternum"); + // Inferiorly, Aorta has two CCL that merge into a single one when + // S6 appears. Loop on Aorta slices, select the most ant one, detect + // the most ant point. + + + + // ====> TO BE CHANGED USING AscendingAorta and DescendingAorta + + - // Search most sup point - MaskImagePointType ps = Sternum->GetOrigin(); // initialise to avoid warning - clitk::FindExtremaPointInAGivenDirection(Sternum, GetBackgroundValue(), 2, false, ps); - double m_SternumZ = ps[2]+Sternum->GetSpacing()[2]; // One more slice, because it is below this point + std::vector slices; + clitk::ExtractSlices(Aorta, 2, slices); + std::vector points; + for(uint i=0; i(slices[i], GetBackgroundValue(), false, 1); + std::vector c; + clitk::ComputeCentroids(slices[i], GetBackgroundValue(), c); + assert(c.size() == 3); // only 2 CCL + typename MaskSliceType::PixelType l; + if (c[1][1] > c[2][1]) { // We will remove the label=1 + l = 1; + } + else { + l = 2;// We will remove the label=2 + } + slices[i] = clitk::SetBackground(slices[i], slices[i], l, + GetBackgroundValue(), true); + + // Detect the most ant point + MaskSlicePointType p; + MaskImagePointType pA; + clitk::FindExtremaPointInAGivenDirection(slices[i], GetBackgroundValue(), 1, true, p); + // Set the X coordinate to the X coordinate of the centroid + if (l==1) p[0] = c[2][0]; + else p[0] = c[1][0]; + + // Convert in 3D and store + clitk::PointsUtils::Convert2DTo3D(p, Aorta, i, pA); + points.push_back(pA); + } + + // DEBUG + // MaskImagePointer o = clitk::JoinSlices(slices, Aorta, 2); + // writeImage(o, "o.mhd"); + // clitk::WriteListOfLandmarks(points, "Ant-Aorta.txt"); - //* Crop support : + // Remove Post/Left to this point m_Working_Support = - clitk::CropImageAlongOneAxis(m_Working_Support, 2, - m_CarinaZ, m_SternumZ, true, - GetBackgroundValue()); + clitk::SliceBySliceSetBackgroundFromPoints(m_Working_Support, + GetBackgroundValue(), 2, + points, + true, // Set BG if X greater than point[x], and + true); // if Y greater than point[y] + + StopCurrentStep(m_Working_Support); + m_ListOfStations["3A"] = m_Working_Support; +} +//-------------------------------------------------------------------- + + +//-------------------------------------------------------------------- +template +void +clitk::ExtractLymphStationsFilter:: +ExtractStation_3A_Post_Limits_With_Dilated_Aorta_S6_Support() +{ + StartNewStep("[Station 3A] Post limits with dilated Aorta"); + + // Consider Aorta + MaskImagePointer Aorta = GetAFDB()->template GetImage ("Aorta"); + + // Limits the support to S6 + MaskImagePointer S6 = m_ListOfSupports["S6"]; + Aorta = clitk::ResizeImageLike(Aorta, S6, GetBackgroundValue()); + + // Extend 1cm anteriorly + MaskImagePointType radius; // in mm + radius[0] = 10; + radius[1] = 10; + radius[2] = 0; // required + Aorta = clitk::Dilate(Aorta, radius, GetBackgroundValue(), GetForegroundValue(), false); + + // Now, insert this image in the AFDB (but do not store on disk) + GetAFDB()->template SetImage("Aorta_Dilated_Anteriorly", "seg/Aorta_Dilated_Anteriorly.mha", Aorta, false); + writeImage(Aorta, "seg/Aorta_Dilated_Anteriorly.mha"); + GetAFDB()->Write(); StopCurrentStep(m_Working_Support); m_ListOfStations["3A"] = m_Working_Support; @@ -48,16 +162,97 @@ ExtractStation_3A_SI_Limits() template void clitk::ExtractLymphStationsFilter:: -ExtractStation_3A_Ant_Limits() +ExtractStation_3A_AntPost_Superiorly() { - StartNewStep("[Station 3A] Ant limits with Sternum"); + StartNewStep("[Station 3A] Post limits superiorly"); + + // Get or compute the binary mask that separate Ant/Post part + // according to vessels + MaskImagePointer binarizedContour = FindAntPostVessels2(); + binarizedContour = clitk::ResizeImageLike(binarizedContour, + m_Working_Support, + GetBackgroundValue()); + + // remove from support + typedef clitk::BooleanOperatorLabelImageFilter BoolFilterType; + typename BoolFilterType::Pointer boolFilter = BoolFilterType::New(); + boolFilter->InPlaceOn(); + boolFilter->SetInput1(m_Working_Support); + boolFilter->SetInput2(binarizedContour); + boolFilter->SetBackgroundValue1(GetBackgroundValue()); + boolFilter->SetBackgroundValue2(GetBackgroundValue()); + boolFilter->SetOperationType(BoolFilterType::AndNot); + boolFilter->Update(); + m_Working_Support = boolFilter->GetOutput(); + + StopCurrentStep(m_Working_Support); + m_ListOfStations["3A"] = m_Working_Support; +} +//-------------------------------------------------------------------- + + +//-------------------------------------------------------------------- +template +void +clitk::ExtractLymphStationsFilter:: +ExtractStation_3A_Remove_Structures() +{ + Remove_Structures(" 3A", "Aorta"); + Remove_Structures(" 3A", "LeftSubclavianArtery"); + Remove_Structures(" 3A", "RightSubclavianArtery"); + Remove_Structures(" 3A", "Thyroid"); + Remove_Structures(" 3A", "LeftCommonCarotidArtery"); + Remove_Structures(" 3A", "RightCommonCarotidArtery"); + Remove_Structures(" 3A", "BrachioCephalicArtery"); + // Remove_Structures("3A", "Bones"); --> should be in extractmediastinum + // Remove_Structures("3A", "BrachioCephalicVein"); ? + + StartNewStep("[Station 3A] Remove part of BrachioCephalicVein"); + // resize like support, extract slices + // while single CCL -> remove + // when two remove only the most post + MaskImagePointer BrachioCephalicVein = + GetAFDB()->template GetImage ("BrachioCephalicVein"); + BrachioCephalicVein = clitk::ResizeImageLike(BrachioCephalicVein, + m_Working_Support, + GetBackgroundValue()); + std::vector slices; + std::vector slices_BCV; + clitk::ExtractSlices(m_Working_Support, 2, slices); + clitk::ExtractSlices(BrachioCephalicVein, 2, slices_BCV); + for(uint i=0; i(slices_BCV[i], 0, true, 1); + + // Compute centroids + std::vector centroids; + ComputeCentroids(slices_BCV[i], GetBackgroundValue(), centroids); + + // If several centroid, select the one most anterior + if (centroids.size() > 2) { + // Only keep the one most post + typename MaskSliceType::PixelType label; + if (centroids[1][1] > centroids[2][1]) { + label = 2; + } + else { + label = 1; + } + // "remove" the CCL + slices_BCV[i] = clitk::SetBackground(slices_BCV[i], + slices_BCV[i], + label, + GetBackgroundValue(), + true); + } + + // Remove from the support + clitk::AndNot(slices[i], slices_BCV[i], GetBackgroundValue()); + } + + // Joint + m_Working_Support = clitk::JoinSlices(slices, m_Working_Support, 2); - // Get Sternum, keep posterior part. - MaskImagePointer Sternum = GetAFDB()->template GetImage("Sternum"); - m_Working_Support = - clitk::SliceBySliceRelativePosition(m_Working_Support, Sternum, 2, - 0.5, "PostTo", - false, 3, true, false); StopCurrentStep(m_Working_Support); m_ListOfStations["3A"] = m_Working_Support; }