clitk::ExtractLymphStationsFilter<TImageType>::
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);
+ SetFuzzyThreshold("7", "Bronchi", 0.1);
+ SetFuzzyThreshold("7", "LeftSuperiorPulmonaryVein", 0.3);
+ SetFuzzyThreshold("7", "RightSuperiorPulmonaryVein", 0.2);
+ SetFuzzyThreshold("7", "RightPulmonaryArtery", 0.3);
+ SetFuzzyThreshold("7", "LeftPulmonaryArtery", 0.5);
+ SetFuzzyThreshold("7", "SVC", 0.2);
+ SetS7_UseMostInferiorPartOnlyFlag(false);
}
//--------------------------------------------------------------------
+
//--------------------------------------------------------------------
template <class TImageType>
void
clitk::ExtractLymphStationsFilter<TImageType>::
-SetFuzzyThresholdForS7(std::string tag, double value)
-{
- m_FuzzyThresholdForS7[tag] = value;
+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<MaskImageType>(m_ListOfStations["7"], "seg/Station7.mhd");
+ GetAFDB()->SetImageFilename("Station7", "seg/Station7.mhd");
+ WriteAFDB();
+ }
}
//--------------------------------------------------------------------
//--------------------------------------------------------------------
template <class TImageType>
-double
+void
clitk::ExtractLymphStationsFilter<TImageType>::
-GetFuzzyThresholdForS7(std::string tag)
+ExtractStation_7_SI_Limits()
{
- if (m_FuzzyThresholdForS7.find(tag) != m_FuzzyThresholdForS7.end()) {
- return m_FuzzyThresholdForS7[tag];
- }
- else {
- clitkExceptionMacro("Could not find options "+tag+" in the m_FuzzyThresholdForS7 list");
- }
+ StartNewStep("[Station7] Inf/Sup mediastinum limits with carina/LLL-RMLBronchus");
+ // Get Inputs
+ MaskImagePointer Trachea = GetAFDB()->template GetImage <MaskImageType>("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<MaskImageType>(m_Working_Support, GetBackgroundValue(),
+ A, B, 2, 0, false);
+
+ // Get the CarinaZ position
+ double m_CarinaZ = FindCarina();
+
+ // Crop support
+ m_Working_Support =
+ clitk::CropImageAlongOneAxis<MaskImageType>(m_Working_Support, 2,
+ A[2], m_CarinaZ, true,
+ GetBackgroundValue());
+ // Crop trachea
+ m_Working_Trachea =
+ clitk::CropImageAlongOneAxis<MaskImageType>(Trachea, 2,
+ A[2], m_CarinaZ, true,
+ GetBackgroundValue());
+
+ StopCurrentStep<MaskImageType>(m_Working_Support);
+ m_ListOfStations["7"] = m_Working_Support;
}
//--------------------------------------------------------------------
template <class TImageType>
void
clitk::ExtractLymphStationsFilter<TImageType>::
-ExtractStation_7_SI_Limits()
+ExtractStation_7_RL_Interior_Limits()
{
- StartNewStep("[Station7] Inf/Sup mediastinum limits with carina/LLLBronchus");
- // Get Inputs
- MaskImagePointer Trachea = GetAFDB()->template GetImage <MaskImageType>("Trachea");
+ // ----------------------------------------------------------------
+ StartNewStep("[Station7] RL limits with bronchi");
- // We suppoe that CarinaZ was already computed (S8)
- double m_CarinaZ = GetAFDB()->GetDouble("CarinaZ");
+ /*
+ Slice by Slice, consider most Left point of the Right
+ bronchus. Remove the Ant/Right corner
+ */
+
+ // First consider bronchi
+ FindLeftAndRightBronchi();
+ m_RightBronchus = GetAFDB()->template GetImage <MaskImageType>("RightBronchus");
+ m_LeftBronchus = GetAFDB()->template GetImage <MaskImageType>("LeftBronchus");
+
+ // Resize like m_Working_Support
+ m_LeftBronchus =
+ clitk::ResizeImageLike<MaskImageType>(m_LeftBronchus, m_Working_Support, GetBackgroundValue());
+ m_RightBronchus =
+ clitk::ResizeImageLike<MaskImageType>(m_RightBronchus, m_Working_Support, GetBackgroundValue());
+
+ // Extract slices, Label, compute centroid, keep most central connected component
+ std::vector<MaskSlicePointer> slices_leftbronchus;
+ std::vector<MaskSlicePointer> slices_rightbronchus;
+ std::vector<MaskSlicePointer> slices_support;
+ clitk::ExtractSlices<MaskImageType>(m_LeftBronchus, 2, slices_leftbronchus);
+ clitk::ExtractSlices<MaskImageType>(m_RightBronchus, 2, slices_rightbronchus);
+ clitk::ExtractSlices<MaskImageType>(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.size(); i++) {
+ slices_leftbronchus[i] = Labelize<MaskSliceType>(slices_leftbronchus[i], 0, false, 10);
+ std::vector<typename MaskSliceType::PointType> c;
+ clitk::ComputeCentroids<MaskSliceType>(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<c.size(); j++) {
+ if (c[j][0] < most_at_left) {
+ most_at_left = c[j][0];
+ most_at_left_index = j;
+ }
+ }
+ // Put all other CCL to Background
+ slices_leftbronchus[i] =
+ clitk::Binarize<MaskSliceType>(slices_leftbronchus[i], most_at_left_index,
+ most_at_left_index, GetBackgroundValue(), GetForegroundValue());
+ } // end c.size
+ }
- // double m_OriginOfRightMiddleLobeBronchusZ = GetAFDB()->GetPoint3D("OriginOfRightMiddleLobeBronchus", 2);
- // DD(m_OriginOfRightMiddleLobeBronchusZ);
- MaskImagePointer UpperBorderOfLLLBronchus = GetAFDB()->template GetImage<MaskImageType>("UpperBorderOfLLLBronchus");
+ // Loop on slices for right bronchus
+ for(uint i=0; i<slices_rightbronchus.size(); i++) {
+ slices_rightbronchus[i] = Labelize<MaskSliceType>(slices_rightbronchus[i], 0, false, 10);
+ std::vector<typename MaskSliceType::PointType> c;
+ clitk::ComputeCentroids<MaskSliceType>(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<c.size(); j++) {
+ if (c[j][0] > 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<MaskSliceType>(slices_rightbronchus[i], most_at_right_index,
+ most_at_right_index, GetBackgroundValue(), GetForegroundValue());
+ } // end c.size
+ }
+
+ // Joint slices
+ m_LeftBronchus = clitk::JoinSlices<MaskImageType>(slices_leftbronchus, m_LeftBronchus, 2);
+ m_RightBronchus = clitk::JoinSlices<MaskImageType>(slices_rightbronchus, m_RightBronchus, 2);
- // Search most inf point (WHY ? IS IT THE RIGHT STRUCTURE ??)
- MaskImagePointType ps = UpperBorderOfLLLBronchus->GetOrigin(); // initialise to avoid warning
- clitk::FindExtremaPointInAGivenDirection<MaskImageType>(UpperBorderOfLLLBronchus, GetBackgroundValue(), 2, true, ps);
- double m_UpperBorderOfLLLBronchusZ = ps[2];
+ // For Right bronchus, Find most Left point. Remove corner Ant/Right corner
+ for(uint i=0; i<slices_rightbronchus.size(); i++) {
+ // Find most point most at left
+ MaskSlicePointType p_left;
+ MaskSlicePointType p_post;
+ bool b = clitk::FindExtremaPointInAGivenDirection<MaskSliceType>(slices_rightbronchus[i], GetBackgroundValue(), 0, false, p_left);
+ if (b) {
+ b = clitk::FindExtremaPointInAGivenDirection<MaskSliceType>(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<MaskSliceType>(slices_support[i], GetBackgroundValue(), region);
+ }
+ }
- /*
- std::vector<MaskImagePointType> centroids;
- clitk::ComputeCentroids<MaskImageType>(UpperBorderOfLLLBronchus, GetBackgroundValue(), centroids);
- double m_UpperBorderOfLLLBronchusZ = centroids[1][2];
- DD(m_UpperBorderOfLLLBronchusZ)
- */
+ // For Left bronchus, Find most Right point. Remove corner Ant/Left corner
+ for(uint i=0; i<slices_leftbronchus.size(); i++) {
+ // Find most point most at right
+ MaskSlicePointType p_right;
+ MaskSlicePointType p_post;
+ bool b = clitk::FindExtremaPointInAGivenDirection<MaskSliceType>(slices_leftbronchus[i], GetBackgroundValue(), 0, true, p_right);
+ if (b) {
+ b = clitk::FindExtremaPointInAGivenDirection<MaskSliceType>(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<ImageType> 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<MaskSliceType>(slices_support[i], GetBackgroundValue(), region);
+ }
+ }
- /* Crop support */
+ m_Working_Support = clitk::JoinSlices<MaskImageType>(slices_support, m_Working_Support, 2);
+
+ // Also remove what is at right of the Right bronchus (left respectively)
m_Working_Support =
- clitk::CropImageAlongOneAxis<MaskImageType>(m_Working_Support, 2,
- m_UpperBorderOfLLLBronchusZ,
- m_CarinaZ, true,
- GetBackgroundValue());
- /* Crop trachea */
- m_Working_Trachea =
- clitk::CropImageAlongOneAxis<MaskImageType>(Trachea, 2,
- m_UpperBorderOfLLLBronchusZ,
- m_CarinaZ, true,
- GetBackgroundValue());
+ clitk::SliceBySliceRelativePosition<MaskImageType>(m_Working_Support, m_LeftBronchus, 2,
+ GetFuzzyThreshold("7", "Bronchi"), "NotLeftTo",
+ false, 3, false);
+ m_Working_Support =
+ clitk::SliceBySliceRelativePosition<MaskImageType>(m_Working_Support, m_RightBronchus, 2,
+ GetFuzzyThreshold("7", "Bronchi"), "NotRightTo",
+ false, 3, false);
+
+ // SECOND PART
StopCurrentStep<MaskImageType>(m_Working_Support);
- m_ListOfStations["7"] = m_Working_Support;
}
//--------------------------------------------------------------------
template <class TImageType>
void
clitk::ExtractLymphStationsFilter<TImageType>::
-ExtractStation_7_RL_Limits()
+ExtractStation_7_RL_Limits_OLD()
{
// ----------------------------------------------------------------
StartNewStep("[Station7] Limits with bronchus : RightTo the left bronchus");
clitk::ExtractSlices<MaskImageType>(m_LeftBronchus, 2, slices_leftbronchus);
clitk::ExtractSlices<MaskImageType>(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.size(); i++) {
slices_leftbronchus[i] = Labelize<MaskSliceType>(slices_leftbronchus[i], 0, false, 10);
m_Working_Support =
clitk::SliceBySliceRelativePosition<MaskImageType>(m_Working_Support, m_LeftBronchus, 2,
- GetFuzzyThresholdForS7("Bronchi"), "RightTo",
+ GetFuzzyThreshold("7", "Bronchi"), "RightTo",
false, 3, false);
StopCurrentStep<MaskImageType>(m_Working_Support);
StartNewStep("[Station7] Limits with bronchus : LeftTo the right bronchus");
m_Working_Support =
clitk::SliceBySliceRelativePosition<MaskImageType>(m_Working_Support, m_RightBronchus, 2,
- GetFuzzyThresholdForS7("Bronchi"), "LeftTo",
+ GetFuzzyThreshold("7", "Bronchi"), "LeftTo",
false, 3, false);
StopCurrentStep<MaskImageType>(m_Working_Support);
sliceRelPosFilter->SetInput(m_Working_Support);
sliceRelPosFilter->SetInputObject(LeftSuperiorPulmonaryVein);
sliceRelPosFilter->SetDirection(2);
- sliceRelPosFilter->SetFuzzyThreshold(GetFuzzyThresholdForS7("LeftSuperiorPulmonaryVein"));
+ sliceRelPosFilter->SetFuzzyThreshold(GetFuzzyThreshold("7", "LeftSuperiorPulmonaryVein"));
sliceRelPosFilter->AddOrientationTypeString("NotLeftTo");
sliceRelPosFilter->AddOrientationTypeString("NotAntTo");
sliceRelPosFilter->SetIntermediateSpacingFlag(true);
sliceRelPosFilter->SetIntermediateSpacing(3);
- sliceRelPosFilter->SetUniqueConnectedComponentBySlice(false);
+ sliceRelPosFilter->SetUniqueConnectedComponentBySliceFlag(false);
sliceRelPosFilter->SetAutoCropFlag(false);
sliceRelPosFilter->IgnoreEmptySliceObjectFlagOn();
sliceRelPosFilter->Update();
sliceRelPosFilter->SetInput(m_Working_Support);
sliceRelPosFilter->SetInputObject(RightSuperiorPulmonaryVein);
sliceRelPosFilter->SetDirection(2);
- sliceRelPosFilter->SetFuzzyThreshold(GetFuzzyThresholdForS7("RightSuperiorPulmonaryVein"));
+ sliceRelPosFilter->SetFuzzyThreshold(GetFuzzyThreshold("7", "RightSuperiorPulmonaryVein"));
sliceRelPosFilter->AddOrientationTypeString("NotRightTo");
sliceRelPosFilter->AddOrientationTypeString("NotAntTo");
sliceRelPosFilter->AddOrientationTypeString("NotPostTo");
sliceRelPosFilter->SetIntermediateSpacingFlag(true);
sliceRelPosFilter->SetIntermediateSpacing(3);
- sliceRelPosFilter->SetUniqueConnectedComponentBySlice(false);
+ sliceRelPosFilter->SetUniqueConnectedComponentBySliceFlag(false);
sliceRelPosFilter->SetAutoCropFlag(false);
sliceRelPosFilter->IgnoreEmptySliceObjectFlagOn();
sliceRelPosFilter->Update();
sliceRelPosFilter->SetInput(m_Working_Support);
sliceRelPosFilter->SetInputObject(RightPulmonaryArtery);
sliceRelPosFilter->SetDirection(2);
- sliceRelPosFilter->SetFuzzyThreshold(GetFuzzyThresholdForS7("RightPulmonaryArtery"));
+ sliceRelPosFilter->SetFuzzyThreshold(GetFuzzyThreshold("7", "RightPulmonaryArtery"));
sliceRelPosFilter->AddOrientationTypeString("NotAntTo");
sliceRelPosFilter->SetIntermediateSpacingFlag(true);
sliceRelPosFilter->SetIntermediateSpacing(3);
- sliceRelPosFilter->SetUniqueConnectedComponentBySlice(false);
+ sliceRelPosFilter->SetUniqueConnectedComponentBySliceFlag(false);
sliceRelPosFilter->SetAutoCropFlag(false);
sliceRelPosFilter->IgnoreEmptySliceObjectFlagOn();
sliceRelPosFilter->Update();
sliceRelPosFilter->SetInput(m_Working_Support);
sliceRelPosFilter->SetInputObject(LeftPulmonaryArtery);
sliceRelPosFilter->SetDirection(2);
- sliceRelPosFilter->SetFuzzyThreshold(GetFuzzyThresholdForS7("LeftPulmonaryArtery"));
+ sliceRelPosFilter->SetFuzzyThreshold(GetFuzzyThreshold("7", "LeftPulmonaryArtery"));
sliceRelPosFilter->AddOrientationTypeString("NotAntTo");
sliceRelPosFilter->SetIntermediateSpacingFlag(true);
sliceRelPosFilter->SetIntermediateSpacing(3);
- sliceRelPosFilter->SetUniqueConnectedComponentBySlice(false);
+ sliceRelPosFilter->SetUniqueConnectedComponentBySliceFlag(false);
sliceRelPosFilter->SetAutoCropFlag(false);
sliceRelPosFilter->IgnoreEmptySliceObjectFlagOn();
sliceRelPosFilter->Update();
sliceRelPosFilter->SetInput(m_Working_Support);
sliceRelPosFilter->SetInputObject(SVC);
sliceRelPosFilter->SetDirection(2);
- sliceRelPosFilter->SetFuzzyThreshold(GetFuzzyThresholdForS7("SVC"));
+ sliceRelPosFilter->SetFuzzyThreshold(GetFuzzyThreshold("7", "SVC"));
sliceRelPosFilter->AddOrientationTypeString("NotRightTo");
sliceRelPosFilter->AddOrientationTypeString("NotAntTo");
sliceRelPosFilter->SetIntermediateSpacingFlag(true);
sliceRelPosFilter->SetIntermediateSpacing(3);
- sliceRelPosFilter->SetUniqueConnectedComponentBySlice(false);
+ sliceRelPosFilter->SetUniqueConnectedComponentBySliceFlag(false);
sliceRelPosFilter->SetAutoCropFlag(true);
sliceRelPosFilter->IgnoreEmptySliceObjectFlagOn();
sliceRelPosFilter->Update();
//--------------------------------------------------------------------
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");
+ Remove_Structures("7", "AzygousVein");
+ Remove_Structures("7", "Aorta");
+ 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<MaskImageType>(m_Working_Support, GetBackgroundValue(), GetForegroundValue());
+
+ Remove_Structures("7", "Esophagus");
// END
StopCurrentStep<MaskImageType>(m_Working_Support);