X-Git-Url: https://git.creatis.insa-lyon.fr/pubgit/?a=blobdiff_plain;f=segmentation%2FclitkExtractLymphStation_3P.txx;h=274fc867c740596227b8c2c92f84b31b4a5d5a02;hb=b2fd61648c05339dd302e102361c22c4b11d48ff;hp=effcd4fd6f51a88a6d407bd81faf0895c50b47c7;hpb=bf4928c59a1d39f53fe03deb4b73ecb7e1cf214b;p=clitk.git diff --git a/segmentation/clitkExtractLymphStation_3P.txx b/segmentation/clitkExtractLymphStation_3P.txx index effcd4f..274fc86 100644 --- a/segmentation/clitkExtractLymphStation_3P.txx +++ b/segmentation/clitkExtractLymphStation_3P.txx @@ -1,7 +1,4 @@ -#include -#include - //-------------------------------------------------------------------- template void @@ -11,45 +8,275 @@ ExtractStation_3P_SetDefaultValues() } //-------------------------------------------------------------------- + +//-------------------------------------------------------------------- +template +void +clitk::ExtractLymphStationsFilter:: +ExtractStation_3P() +{ + if (!CheckForStation("3P")) return; + + StartNewStep("Station 3P"); + StartSubStep(); + + // Get the current support + StartNewStep("[Station 3P] Get the current 3P suppport"); + m_Working_Support = m_ListOfSupports["S3P"]; + m_ListOfStations["3P"] = m_Working_Support; + 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 + // ExtractStation_3P_LR_inf_Limits(); // <-- done in RelPosList + + // Store image filenames into AFDB + writeImage(m_ListOfStations["3P"], "seg/Station3P.mhd"); + GetAFDB()->SetImageFilename("Station3P", "seg/Station3P.mhd"); + WriteAFDB(); + StopSubStep(); +} +//-------------------------------------------------------------------- + + +//-------------------------------------------------------------------- +template +void +clitk::ExtractLymphStationsFilter:: +ExtractStation_3P_Remove_Structures() +{ + 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; +} +//-------------------------------------------------------------------- + + //-------------------------------------------------------------------- template void clitk::ExtractLymphStationsFilter:: -ExtractStation_3P_SI_Limits() +ExtractStation_3P_LR_sup_Limits() { /* - Apex of the chest & Carina. - */ - StartNewStep("[Station 3P] Inf/Sup limits with apex of the chest and carina"); + "On the right side, the limit is defined by the air–soft-tissue + interface. On the left side, it is defined by the air–tissue + interface superiorly (Fig. 2A–C) and the aorta inferiorly + (Figs. 2D–I and 3A–C)." - writeImage(m_Working_Support, "support.mhd"); + 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 (superior part) "); - // Get Carina position (has been determined in Station8) - m_CarinaZ = GetAFDB()->GetDouble("CarinaZ"); - DD(m_CarinaZ); + // Load structures + MaskImagePointer Trachea = GetAFDB()->template GetImage("Trachea"); + MaskImagePointer SubclavianArtery = GetAFDB()->template GetImage("SubclavianArtery"); + + // Crop like current support + Trachea = clitk::ResizeImageLike(Trachea, m_Working_Support, GetBackgroundValue()); + SubclavianArtery = clitk::ResizeImageLike(SubclavianArtery, m_Working_Support, GetBackgroundValue()); + + // writeImage(Trachea, "tr.mhd"); + // writeImage(SubclavianArtery, "sca.mhd"); - // Get Apex of the Chest - MaskImagePointer Lungs = GetAFDB()->template GetImage("Lungs"); - DD("lung ok"); + // Get list of slices + std::vector slices_support; + std::vector slices_trachea; + std::vector slices_subclavianartery; + clitk::ExtractSlices(m_Working_Support, 2, slices_support); + clitk::ExtractSlices(Trachea, 2, slices_trachea); + clitk::ExtractSlices(SubclavianArtery, 2, slices_subclavianartery); + + // Loop on slices + std::vector points; MaskImagePointType p; - bool found = clitk::FindExtremaPointInAGivenDirection(Lungs, - GetBackgroundValue(), - 1, true, p); - DD(found); - DD(p); - double m_ApexOfTheChest = p[2]; - DD(m_ApexOfTheChest); - - /* Crop support : - Superior limit = carina - Inferior limit = Apex of the chest */ - m_Working_Support = - clitk::CropImageAlongOneAxis(m_Working_Support, 2, - m_ApexOfTheChest, - m_CarinaZ, true, - GetBackgroundValue()); + for(uint i=0; i centroids; + typename MaskSliceType::PointType c; + ComputeCentroids(slices_trachea[i], GetBackgroundValue(), centroids); + c = centroids[1]; + + // [debug] Store point + clitk::PointsUtils::Convert2DTo3D(centroids[1], Trachea, i, p); + points.push_back(p); + + // Get Right and Left CCL in SubclavianArtery + slices_subclavianartery[i] = Labelize(slices_subclavianartery[i], 0, true, 10); + ComputeCentroids(slices_subclavianartery[i], GetBackgroundValue(), centroids); + + if (centroids.size() > 1) { + // Determine the one at Right/Left -> first after Trachea + // centroid + typename MaskSliceType::PointType right; + typename MaskSliceType::PointType left; + int label_right=-1; + int label_left=-1; + right[0] = c[0]-100; + left[0] = c[0]+100; + for(uint j=1; j= right[0]) { + right = centroids[j]; + label_right = j; + } + } + if (centroids[j][0] > c[0]) { // At Left of Trachea centroid + if (centroids[j][0] <= left[0]) { + left = centroids[j]; + label_left = j; + } + } + } + + if (label_right != -1) { + + // Debug points + clitk::PointsUtils::Convert2DTo3D(centroids[label_right], SubclavianArtery, i, p); + points.push_back(p); + + // Set Background and ForegroundValue according to label_right + MaskSlicePointer object = + clitk::Binarize(slices_subclavianartery[i], label_right, label_right, + GetBackgroundValue(), GetForegroundValue()); + + // Relative Position : not at Right + typedef clitk::AddRelativePositionConstraintToLabelImageFilter RelPosFilterType; + typename RelPosFilterType::Pointer relPosFilter = RelPosFilterType::New(); + relPosFilter->VerboseStepFlagOff(); + relPosFilter->WriteStepFlagOff(); + relPosFilter->SetBackgroundValue(GetBackgroundValue()); + relPosFilter->SetInput(slices_support[i]); + relPosFilter->SetInputObject(object); + relPosFilter->AddOrientationTypeString("RightTo"); + relPosFilter->SetInverseOrientationFlag(true); + // relPosFilter->SetIntermediateSpacing(3); + relPosFilter->SetIntermediateSpacingFlag(false); + relPosFilter->SetFuzzyThreshold(0.7); + relPosFilter->AutoCropFlagOff(); // important ! because we join the slices after this loop + relPosFilter->Update(); + slices_support[i] = relPosFilter->GetOutput(); + + // Relative Position : not Anterior + relPosFilter = RelPosFilterType::New(); + relPosFilter->VerboseStepFlagOff(); + relPosFilter->WriteStepFlagOff(); + relPosFilter->SetBackgroundValue(GetBackgroundValue()); + relPosFilter->SetInput(slices_support[i]); + relPosFilter->SetInputObject(object); + relPosFilter->AddOrientationTypeString("AntTo"); + relPosFilter->SetInverseOrientationFlag(true); + // relPosFilter->SetIntermediateSpacing(3); + relPosFilter->SetIntermediateSpacingFlag(false); + relPosFilter->SetFuzzyThreshold(0.7); + relPosFilter->AutoCropFlagOff(); // important ! because we join the slices after this loop + relPosFilter->Update(); + slices_support[i] = relPosFilter->GetOutput(); + + } // End RelativePosition for Right + + + if (label_left != -1) { + + // Debug points + clitk::PointsUtils::Convert2DTo3D(centroids[label_left], SubclavianArtery, i, p); + points.push_back(p); + + // Set Background and ForegroundValue according to label_right + MaskSlicePointer object = + clitk::Binarize(slices_subclavianartery[i], label_left, label_left, + GetBackgroundValue(), GetForegroundValue()); + + // Relative Position : not at Right + typedef clitk::AddRelativePositionConstraintToLabelImageFilter RelPosFilterType; + typename RelPosFilterType::Pointer relPosFilter = RelPosFilterType::New(); + relPosFilter->VerboseStepFlagOff(); + relPosFilter->WriteStepFlagOff(); + relPosFilter->SetBackgroundValue(GetBackgroundValue()); + relPosFilter->SetInput(slices_support[i]); + relPosFilter->SetInputObject(object); + relPosFilter->AddOrientationTypeString("L"); + relPosFilter->SetInverseOrientationFlag(true); + // relPosFilter->SetIntermediateSpacing(3); + relPosFilter->SetIntermediateSpacingFlag(false); + relPosFilter->SetFuzzyThreshold(0.7); + relPosFilter->AutoCropFlagOff(); // important ! because we join the slices after this loop + relPosFilter->Update(); + slices_support[i] = relPosFilter->GetOutput(); + + // Relative Position : not Anterior + relPosFilter = RelPosFilterType::New(); + relPosFilter->VerboseStepFlagOff(); + relPosFilter->WriteStepFlagOff(); + relPosFilter->SetBackgroundValue(GetBackgroundValue()); + relPosFilter->SetInput(slices_support[i]); + relPosFilter->SetInputObject(object); + relPosFilter->AddOrientationTypeString("A"); + relPosFilter->SetInverseOrientationFlag(true); + // relPosFilter->SetIntermediateSpacing(3); + relPosFilter->SetIntermediateSpacingFlag(false); + relPosFilter->SetFuzzyThreshold(0.7); + relPosFilter->AutoCropFlagOff(); // important ! because we join the slices after this loop + relPosFilter->Update(); + slices_support[i] = relPosFilter->GetOutput(); + + } + + + } // if centroids.size > 1 + } // End loop slices + + // Joint slices + m_Working_Support = clitk::JoinSlices(slices_support, m_Working_Support, 2); + + // Save list points + clitk::WriteListOfLandmarks(points, "subcl-lr.txt"); + StopCurrentStep(m_Working_Support); m_ListOfStations["3P"] = m_Working_Support; } //-------------------------------------------------------------------- + +//-------------------------------------------------------------------- +template +void +clitk::ExtractLymphStationsFilter:: +ExtractStation_3P_LR_sup_Limits_2() +{ + /* + "On the right side, the limit is defined by the air–soft-tissue + interface. On the left side, it is defined by the air–tissue + interface superiorly (Fig. 2A–C) and the aorta inferiorly + (Figs. 2D–I and 3A–C)." + + 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 (superior part) "); + + +} +//-------------------------------------------------------------------- +