//-------------------------------------------------------------------- template void clitk::ExtractLymphStationsFilter:: ExtractStation_7_SetDefaultValues() { SetFuzzyThresholdForS7("Bronchi", 0.1); SetFuzzyThresholdForS7("LeftSuperiorPulmonaryVein", 0.3); SetFuzzyThresholdForS7("RightSuperiorPulmonaryVein", 0.2); SetFuzzyThresholdForS7("RightPulmonaryArtery", 0.3); SetFuzzyThresholdForS7("LeftPulmonaryArtery", 0.5); SetFuzzyThresholdForS7("SVC", 0.2); } //-------------------------------------------------------------------- //-------------------------------------------------------------------- template void clitk::ExtractLymphStationsFilter:: SetFuzzyThresholdForS7(std::string tag, double value) { m_FuzzyThresholdForS7[tag] = value; } //-------------------------------------------------------------------- //-------------------------------------------------------------------- template double clitk::ExtractLymphStationsFilter:: GetFuzzyThresholdForS7(std::string tag) { if (m_FuzzyThresholdForS7.find(tag) != m_FuzzyThresholdForS7.end()) { return m_FuzzyThresholdForS7[tag]; } else { clitkExceptionMacro("Could not find options "+tag+" in the m_FuzzyThresholdForS7 list"); } } //-------------------------------------------------------------------- //-------------------------------------------------------------------- template void clitk::ExtractLymphStationsFilter:: ExtractStation_7_SI_Limits() { StartNewStep("[Station7] Inf/Sup mediastinum limits with carina/LLLBronchus"); // Get Inputs MaskImagePointer Trachea = GetAFDB()->template GetImage ("Trachea"); // We suppoe that CarinaZ was already computed (S8) double m_CarinaZ = GetAFDB()->GetDouble("CarinaZ"); // double m_OriginOfRightMiddleLobeBronchusZ = GetAFDB()->GetPoint3D("OriginOfRightMiddleLobeBronchus", 2); // DD(m_OriginOfRightMiddleLobeBronchusZ); MaskImagePointer UpperBorderOfLLLBronchus = GetAFDB()->template GetImage("UpperBorderOfLLLBronchus"); // 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]; /* std::vector centroids; clitk::ComputeCentroids(UpperBorderOfLLLBronchus, GetBackgroundValue(), centroids); double m_UpperBorderOfLLLBronchusZ = centroids[1][2]; DD(m_UpperBorderOfLLLBronchusZ) */ /* Crop support */ 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()); StopCurrentStep(m_Working_Support); m_ListOfStations["7"] = m_Working_Support; } //-------------------------------------------------------------------- //-------------------------------------------------------------------- template void clitk::ExtractLymphStationsFilter:: ExtractStation_7_RL_Limits() { // ---------------------------------------------------------------- StartNewStep("[Station7] Limits with bronchus : RightTo the left bronchus"); // First consider bronchus and keep the main CCL by slice m_RightBronchus = GetAFDB()->template GetImage ("RightBronchus"); m_LeftBronchus = GetAFDB()->template GetImage ("LeftBronchus"); // Extract slices, Label, compute centroid, keep most central connected component std::vector slices_leftbronchus; std::vector slices_rightbronchus; clitk::ExtractSlices(m_LeftBronchus, 2, slices_leftbronchus); clitk::ExtractSlices(m_RightBronchus, 2, slices_rightbronchus); // Loop on slices 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 } 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); writeImage(m_LeftBronchus, "step-left.mhd"); writeImage(m_RightBronchus, "step-right.mhd"); m_Working_Support = clitk::SliceBySliceRelativePosition(m_Working_Support, m_LeftBronchus, 2, GetFuzzyThresholdForS7("Bronchi"), "RightTo", false, 3, false); StopCurrentStep(m_Working_Support); // ---------------------------------------------------------------- StartNewStep("[Station7] Limits with bronchus : LeftTo the right bronchus"); m_Working_Support = clitk::SliceBySliceRelativePosition(m_Working_Support, m_RightBronchus, 2, GetFuzzyThresholdForS7("Bronchi"), "LeftTo", false, 3, false); StopCurrentStep(m_Working_Support); // ---------------------------------------------------------------- StartNewStep("[Station7] Limits with LeftSuperiorPulmonaryVein"); try { MaskImagePointer LeftSuperiorPulmonaryVein = GetAFDB()->template GetImage("LeftSuperiorPulmonaryVein"); typedef SliceBySliceRelativePositionFilter SliceRelPosFilterType; typename SliceRelPosFilterType::Pointer sliceRelPosFilter = SliceRelPosFilterType::New(); sliceRelPosFilter->SetInput(m_Working_Support); sliceRelPosFilter->SetInputObject(LeftSuperiorPulmonaryVein); sliceRelPosFilter->SetDirection(2); sliceRelPosFilter->SetFuzzyThreshold(GetFuzzyThresholdForS7("LeftSuperiorPulmonaryVein")); sliceRelPosFilter->AddOrientationTypeString("NotLeftTo"); sliceRelPosFilter->AddOrientationTypeString("NotAntTo"); sliceRelPosFilter->SetIntermediateSpacingFlag(true); sliceRelPosFilter->SetIntermediateSpacing(3); sliceRelPosFilter->SetUniqueConnectedComponentBySlice(false); sliceRelPosFilter->SetAutoCropFlag(false); sliceRelPosFilter->IgnoreEmptySliceObjectFlagOn(); sliceRelPosFilter->Update(); m_Working_Support = sliceRelPosFilter->GetOutput(); StopCurrentStep(m_Working_Support); } catch (clitk::ExceptionObject e) { std::cout << "Not LeftSuperiorPulmonaryVein, skip" << std::endl; } // ---------------------------------------------------------------- StartNewStep("[Station7] Limits with RightSuperiorPulmonaryVein"); try { MaskImagePointer RightSuperiorPulmonaryVein = GetAFDB()->template GetImage("RightSuperiorPulmonaryVein"); typedef SliceBySliceRelativePositionFilter SliceRelPosFilterType; typename SliceRelPosFilterType::Pointer sliceRelPosFilter = SliceRelPosFilterType::New(); sliceRelPosFilter->SetInput(m_Working_Support); sliceRelPosFilter->SetInputObject(RightSuperiorPulmonaryVein); sliceRelPosFilter->SetDirection(2); sliceRelPosFilter->SetFuzzyThreshold(GetFuzzyThresholdForS7("RightSuperiorPulmonaryVein")); sliceRelPosFilter->AddOrientationTypeString("NotRightTo"); sliceRelPosFilter->AddOrientationTypeString("NotAntTo"); sliceRelPosFilter->AddOrientationTypeString("NotPostTo"); sliceRelPosFilter->SetIntermediateSpacingFlag(true); sliceRelPosFilter->SetIntermediateSpacing(3); sliceRelPosFilter->SetUniqueConnectedComponentBySlice(false); sliceRelPosFilter->SetAutoCropFlag(false); sliceRelPosFilter->IgnoreEmptySliceObjectFlagOn(); sliceRelPosFilter->Update(); m_Working_Support = sliceRelPosFilter->GetOutput(); StopCurrentStep(m_Working_Support); } catch (clitk::ExceptionObject e) { std::cout << "Not RightSuperiorPulmonaryVein, skip" << std::endl; } // ---------------------------------------------------------------- StartNewStep("[Station7] Limits with RightPulmonaryArtery"); MaskImagePointer RightPulmonaryArtery = GetAFDB()->template GetImage("RightPulmonaryArtery"); typedef SliceBySliceRelativePositionFilter SliceRelPosFilterType; typename SliceRelPosFilterType::Pointer sliceRelPosFilter = SliceRelPosFilterType::New(); sliceRelPosFilter->SetInput(m_Working_Support); sliceRelPosFilter->SetInputObject(RightPulmonaryArtery); sliceRelPosFilter->SetDirection(2); sliceRelPosFilter->SetFuzzyThreshold(GetFuzzyThresholdForS7("RightPulmonaryArtery")); sliceRelPosFilter->AddOrientationTypeString("NotAntTo"); sliceRelPosFilter->SetIntermediateSpacingFlag(true); sliceRelPosFilter->SetIntermediateSpacing(3); sliceRelPosFilter->SetUniqueConnectedComponentBySlice(false); sliceRelPosFilter->SetAutoCropFlag(false); sliceRelPosFilter->IgnoreEmptySliceObjectFlagOn(); sliceRelPosFilter->Update(); m_Working_Support = sliceRelPosFilter->GetOutput(); StopCurrentStep(m_Working_Support); // ---------------------------------------------------------------- StartNewStep("[Station7] Limits with LeftPulmonaryArtery"); MaskImagePointer LeftPulmonaryArtery = GetAFDB()->template GetImage("LeftPulmonaryArtery"); sliceRelPosFilter = SliceRelPosFilterType::New(); sliceRelPosFilter->SetInput(m_Working_Support); sliceRelPosFilter->SetInputObject(LeftPulmonaryArtery); sliceRelPosFilter->SetDirection(2); sliceRelPosFilter->SetFuzzyThreshold(GetFuzzyThresholdForS7("LeftPulmonaryArtery")); sliceRelPosFilter->AddOrientationTypeString("NotAntTo"); sliceRelPosFilter->SetIntermediateSpacingFlag(true); sliceRelPosFilter->SetIntermediateSpacing(3); sliceRelPosFilter->SetUniqueConnectedComponentBySlice(false); sliceRelPosFilter->SetAutoCropFlag(false); sliceRelPosFilter->IgnoreEmptySliceObjectFlagOn(); sliceRelPosFilter->Update(); m_Working_Support = sliceRelPosFilter->GetOutput(); StopCurrentStep(m_Working_Support); StartNewStep("[Station7] Limits with SVC"); MaskImagePointer SVC = GetAFDB()->template GetImage("SVC"); sliceRelPosFilter = SliceRelPosFilterType::New(); sliceRelPosFilter->SetInput(m_Working_Support); sliceRelPosFilter->SetInputObject(SVC); sliceRelPosFilter->SetDirection(2); sliceRelPosFilter->SetFuzzyThreshold(GetFuzzyThresholdForS7("SVC")); sliceRelPosFilter->AddOrientationTypeString("NotRightTo"); sliceRelPosFilter->AddOrientationTypeString("NotAntTo"); sliceRelPosFilter->SetIntermediateSpacingFlag(true); sliceRelPosFilter->SetIntermediateSpacing(3); sliceRelPosFilter->SetUniqueConnectedComponentBySlice(false); sliceRelPosFilter->SetAutoCropFlag(true); sliceRelPosFilter->IgnoreEmptySliceObjectFlagOn(); sliceRelPosFilter->Update(); m_Working_Support = sliceRelPosFilter->GetOutput(); StopCurrentStep(m_Working_Support); // End m_ListOfStations["7"] = m_Working_Support; } //-------------------------------------------------------------------- //-------------------------------------------------------------------- template void clitk::ExtractLymphStationsFilter:: ExtractStation_7_Posterior_Limits() { StartNewStep("[Station7] Posterior limits -> must be AntTo post wall of the bronchi (OLD CLASSIF)"); // Search for points that are the most left/post/ant and most // right/post/ant of the left and right bronchus // extract, loop slices, label/keep, find extrema x 3 /* FindExtremaPointsInBronchus(m_LeftBronchus, 0, 15, m_RightMostInLeftBronchus, m_AntMostInLeftBronchus, m_PostMostInLeftBronchus); FindExtremaPointsInBronchus(m_RightBronchus, 1, 15, m_LeftMostInRightBronchus, m_AntMostInRightBronchus, m_PostMostInRightBronchus); */ // First cut bronchus to the correct sup/inf support MaskImagePointer RightBronchus = clitk::ResizeImageLike(m_RightBronchus, m_Working_Support, GetBackgroundValue()); MaskImagePointer LeftBronchus = clitk::ResizeImageLike(m_LeftBronchus, m_Working_Support, GetBackgroundValue()); // Find extrema points FindExtremaPointsInBronchus(RightBronchus, 0, 10, m_LeftMostInRightBronchus, m_AntMostInRightBronchus, m_PostMostInRightBronchus); FindExtremaPointsInBronchus(LeftBronchus, 1, 10, m_RightMostInLeftBronchus, m_AntMostInLeftBronchus, m_PostMostInLeftBronchus); // DEBUG std::ofstream osrl; openFileForWriting(osrl, "osrl.txt"); osrl << "LANDMARKS1" << std::endl; std::ofstream osal; openFileForWriting(osal, "osal.txt"); osal << "LANDMARKS1" << std::endl; std::ofstream ospl; openFileForWriting(ospl, "ospl.txt"); ospl << "LANDMARKS1" << std::endl; std::ofstream osrr; openFileForWriting(osrr, "osrr.txt"); osrr << "LANDMARKS1" << std::endl; std::ofstream osar; openFileForWriting(osar, "osar.txt"); osar << "LANDMARKS1" << std::endl; std::ofstream ospr; openFileForWriting(ospr, "ospr.txt"); ospr << "LANDMARKS1" << std::endl; for(uint i=0; i(m_Working_Support, m_PostMostInRightBronchus, m_PostMostInLeftBronchus, GetBackgroundValue(), 1, -10); // If needed -> can do the same with AntMost. // End StopCurrentStep(m_Working_Support); m_ListOfStations["7"] = m_Working_Support; } //-------------------------------------------------------------------- //-------------------------------------------------------------------- template void clitk::ExtractLymphStationsFilter:: ExtractStation_7_Remove_Structures() { //-------------------------------------------------------------------- StartNewStep("[Station7] remove some structures"); Remove_Structures("AzygousVein"); Remove_Structures("Aorta"); Remove_Structures("Esophagus"); Remove_Structures("RightPulmonaryArtery"); Remove_Structures("LeftPulmonaryArtery"); Remove_Structures("LeftSuperiorPulmonaryVein"); Remove_Structures("PulmonaryTrunk"); Remove_Structures("VertebralBody"); // END StopCurrentStep(m_Working_Support); m_ListOfStations["7"] = m_Working_Support; return; } //--------------------------------------------------------------------