X-Git-Url: https://git.creatis.insa-lyon.fr/pubgit/?a=blobdiff_plain;f=segmentation%2FclitkExtractLymphStationsFilter.txx;h=1823e998c40cf228444cb29439c5adc760d5cd0e;hb=34f45c6507a3605351e265f4d5eb5b4bb31a1fa6;hp=8fbf86dd98e4353a09f941417d166a1397d9de72;hpb=e0464c9f7bdde185755d60e9dead188291fc3550;p=clitk.git diff --git a/segmentation/clitkExtractLymphStationsFilter.txx b/segmentation/clitkExtractLymphStationsFilter.txx index 8fbf86d..1823e99 100644 --- a/segmentation/clitkExtractLymphStationsFilter.txx +++ b/segmentation/clitkExtractLymphStationsFilter.txx @@ -34,6 +34,7 @@ #include #include #include +#include #include // itk ENST @@ -44,16 +45,19 @@ template clitk::ExtractLymphStationsFilter:: ExtractLymphStationsFilter(): clitk::FilterBase(), - itk::ImageToImageFilter() + clitk::FilterWithAnatomicalFeatureDatabaseManagement(), + itk::ImageToImageFilter() { this->SetNumberOfRequiredInputs(1); - SetBackgroundValueMediastinum(0); - SetBackgroundValueTrachea(0); SetBackgroundValue(0); SetForegroundValue(1); - SetIntermediateSpacing(6); - SetFuzzyThreshold1(0.6); + // Default values + ExtractStation_8_SetDefaultValues(); + ExtractStation_3P_SetDefaultValues(); + ExtractStation_2RL_SetDefaultValues(); + ExtractStation_3A_SetDefaultValues(); + ExtractStation_7_SetDefaultValues(); } //-------------------------------------------------------------------- @@ -62,13 +66,49 @@ ExtractLymphStationsFilter(): template void clitk::ExtractLymphStationsFilter:: -SetInputMediastinumLabelImage(const TImageType * image, ImagePixelType bg) { - this->SetNthInput(0, const_cast(image)); - m_BackgroundValueMediastinum = bg; - SetCarenaZPositionInMM(image->GetOrigin()[2]+image->GetLargestPossibleRegion().GetSize()[2]*image->GetSpacing()[2]); - SetMiddleLobeBronchusZPositionInMM(image->GetOrigin()[2]); - // DD(m_CarenaZPositionInMM); -// DD(m_MiddleLobeBronchusZPositionInMM); +GenerateOutputInformation() { + // Get inputs + LoadAFDB(); + m_Input = dynamic_cast(itk::ProcessObject::GetInput(0)); + m_Mediastinum = GetAFDB()->template GetImage ("Mediastinum"); + + // Extract Station8 + StartNewStep("Station 8"); + StartSubStep(); + ExtractStation_8(); + StopSubStep(); + + // Extract Station3P + StartNewStep("Station 3P"); + StartSubStep(); + ExtractStation_3P(); + StopSubStep(); + + // Extract Station2RL + StartNewStep("Station 2RL"); + StartSubStep(); + ExtractStation_2RL(); + StopSubStep(); + + // Extract Station3A + StartNewStep("Station 3A"); + StartSubStep(); + ExtractStation_3A(); + StopSubStep(); + + // Extract Station7 + StartNewStep("Station 7"); + StartSubStep(); + ExtractStation_7(); + StopSubStep(); + + if (0) { // temporary suppress + // Extract Station4RL + StartNewStep("Station 4RL"); + StartSubStep(); + //ExtractStation_4RL(); + StopSubStep(); + } } //-------------------------------------------------------------------- @@ -77,29 +117,74 @@ SetInputMediastinumLabelImage(const TImageType * image, ImagePixelType bg) { template void clitk::ExtractLymphStationsFilter:: -SetInputTracheaLabelImage(const TImageType * image, ImagePixelType bg) { - this->SetNthInput(1, const_cast(image)); - m_BackgroundValueTrachea = bg; +GenerateInputRequestedRegion() { + //DD("GenerateInputRequestedRegion (nothing?)"); } //-------------------------------------------------------------------- //-------------------------------------------------------------------- template -template void clitk::ExtractLymphStationsFilter:: -SetArgsInfo(ArgsInfoType mArgsInfo) +GenerateData() { + // Final Step -> graft output (if SetNthOutput => redo) + this->GraftOutput(m_ListOfStations["8"]); +} +//-------------------------------------------------------------------- + + +//-------------------------------------------------------------------- +template +bool +clitk::ExtractLymphStationsFilter:: +CheckForStation(std::string station) +{ + // Compute Station name + std::string s = "Station"+station; + + + // Check if station already exist in DB + bool found = false; + if (GetAFDB()->TagExist(s)) { + m_ListOfStations[station] = GetAFDB()->template GetImage(s); + found = true; + } + + // Define the starting support + if (found && GetComputeStation(station)) { + std::cout << "Station " << station << " already exists, but re-computation forced." << std::endl; + } + if (!found || GetComputeStation(station)) { + m_Working_Support = m_Mediastinum = GetAFDB()->template GetImage("Mediastinum", true); + return true; + } + else { + std::cout << "Station " << station << " found. I used it" << std::endl; + return false; + } +} +//-------------------------------------------------------------------- + + +//-------------------------------------------------------------------- +template +bool +clitk::ExtractLymphStationsFilter:: +GetComputeStation(std::string station) { - SetVerboseOption_GGO(mArgsInfo); - SetVerboseStep_GGO(mArgsInfo); - SetWriteStep_GGO(mArgsInfo); - SetVerboseWarningOff_GGO(mArgsInfo); - SetCarenaZPositionInMM_GGO(mArgsInfo); - SetMiddleLobeBronchusZPositionInMM_GGO(mArgsInfo); - SetIntermediateSpacing_GGO(mArgsInfo); - SetFuzzyThreshold1_GGO(mArgsInfo); - //SetBackgroundValueMediastinum_GGO(mArgsInfo); + return (m_ComputeStationMap.find(station) != m_ComputeStationMap.end()); +} +//-------------------------------------------------------------------- + + +//-------------------------------------------------------------------- +template +void +clitk::ExtractLymphStationsFilter:: +AddComputeStation(std::string station) +{ + m_ComputeStationMap[station] = true; } //-------------------------------------------------------------------- @@ -108,162 +193,68 @@ SetArgsInfo(ArgsInfoType mArgsInfo) template void clitk::ExtractLymphStationsFilter:: -GenerateOutputInformation() { - // Superclass::GenerateOutputInformation(); - - // Get input - m_mediastinum = dynamic_cast(itk::ProcessObject::GetInput(0)); - m_trachea = dynamic_cast(itk::ProcessObject::GetInput(1)); - - // ---------------------------------------------------------------- - // ---------------------------------------------------------------- - // Superior limit = carena - // Inferior limit = origine middle lobe bronchus - StartNewStep("Inf/Sup mediastinum limits with carena/bronchus"); - ImageRegionType region = m_mediastinum->GetLargestPossibleRegion(); DD(region); - ImageSizeType size = region.GetSize(); - ImageIndexType index = region.GetIndex(); - DD(m_CarenaZPositionInMM); - DD(m_MiddleLobeBronchusZPositionInMM); - index[2] = floor((m_MiddleLobeBronchusZPositionInMM - m_mediastinum->GetOrigin()[2]) / m_mediastinum->GetSpacing()[2]); - size[2] = ceil((m_CarenaZPositionInMM-m_MiddleLobeBronchusZPositionInMM) / m_mediastinum->GetSpacing()[2]); - region.SetSize(size); - region.SetIndex(index); - DD(region); - typedef itk::RegionOfInterestImageFilter CropFilterType; - typename CropFilterType::Pointer cropFilter = CropFilterType::New(); - cropFilter->SetInput(m_mediastinum); - cropFilter->SetRegionOfInterest(region); - cropFilter->Update(); - m_working_image = cropFilter->GetOutput(); - // Auto Crop (because following rel pos is faster) - m_working_image = clitk::AutoCrop(m_working_image, 0); - StopCurrentStep(m_working_image); - m_output = m_working_image; - - // ---------------------------------------------------------------- - // ---------------------------------------------------------------- - // Separate trachea in two CCL - StartNewStep("Separate trachea under carena"); - // DD(region); - ImageRegionType trachea_region = m_trachea->GetLargestPossibleRegion(); - for(int i=0; i<3; i++) { - index[i] = floor(((index[i]*m_mediastinum->GetSpacing()[i])+m_mediastinum->GetOrigin()[i] - -m_trachea->GetOrigin()[i])/m_trachea->GetSpacing()[i]); - // DD(index[i]); - size[i] = ceil((size[i]*m_mediastinum->GetSpacing()[i])/m_trachea->GetSpacing()[i]); - // DD(size[i]); - if (index[i] < 0) { - size[i] += index[i]; - index[i] = 0; - } - if (size[i]+index[i] > (trachea_region.GetSize()[i] + trachea_region.GetIndex()[i])) { - size[i] = trachea_region.GetSize()[i] + trachea_region.GetIndex()[i] - index[i]; - } +ExtractStation_8() +{ + if (CheckForStation("8")) { + ExtractStation_8_SI_Limits(); + ExtractStation_8_Post_Limits(); + ExtractStation_8_Ant_Sup_Limits(); + ExtractStation_8_Ant_Inf_Limits(); + ExtractStation_8_LR_1_Limits(); + ExtractStation_8_LR_2_Limits(); + ExtractStation_8_LR_Limits(); + ExtractStation_8_Ant_Injected_Limits(); + ExtractStation_8_Single_CCL_Limits(); + ExtractStation_8_Remove_Structures(); + // Store image filenames into AFDB + writeImage(m_ListOfStations["8"], "seg/Station8.mhd"); + GetAFDB()->SetImageFilename("Station8", "seg/Station8.mhd"); + WriteAFDB(); } - // DD(index); - // DD(size); - region.SetIndex(index); - region.SetSize(size); - // typedef itk::RegionOfInterestImageFilter CropFilterType; - // typename CropFilterType::Pointer - cropFilter = CropFilterType::New(); - // m_trachea.Print(std::cout); - cropFilter->SetInput(m_trachea); - cropFilter->SetRegionOfInterest(region); - cropFilter->Update(); - m_working_trachea = cropFilter->GetOutput(); - - // Labelize and consider two main labels - m_working_trachea = Labelize(m_working_trachea, 0, true, 1); - - // Detect wich label is at Left - typedef itk::ImageSliceConstIteratorWithIndex SliceIteratorType; - SliceIteratorType iter(m_working_trachea, m_working_trachea->GetLargestPossibleRegion()); - iter.SetFirstDirection(0); - iter.SetSecondDirection(1); - iter.GoToBegin(); - bool stop = false; - ImagePixelType leftLabel; - ImagePixelType rightLabel; - while (!stop) { - if (iter.Get() != m_BackgroundValueTrachea) { - // DD(iter.GetIndex()); - // DD((int)iter.Get()); - leftLabel = iter.Get(); - stop = true; - } - ++iter; +} +//-------------------------------------------------------------------- + + +//-------------------------------------------------------------------- +template +void +clitk::ExtractLymphStationsFilter:: +ExtractStation_3P() +{ + if (CheckForStation("3P")) { + ExtractStation_3P_SI_Limits(); + ExtractStation_3P_Ant_Limits(); + ExtractStation_3P_Post_Limits(); + ExtractStation_3P_LR_sup_Limits(); + // ExtractStation_3P_LR_sup_Limits_2(); + ExtractStation_3P_LR_inf_Limits(); + ExtractStation_8_Single_CCL_Limits(); // YES 8 ! + ExtractStation_3P_Remove_Structures(); // after CCL + // Store image filenames into AFDB + writeImage(m_ListOfStations["3P"], "seg/Station3P.mhd"); + GetAFDB()->SetImageFilename("Station3P", "seg/Station3P.mhd"); + WriteAFDB(); } - if (leftLabel == 1) rightLabel = 2; - else rightLabel = 1; - DD((int)leftLabel); - DD((int)rightLabel); +} +//-------------------------------------------------------------------- - // End step - StopCurrentStep(m_working_trachea); - - //----------------------------------------------------- - /* DD("TEST Skeleton"); - typedef itk::BinaryThinningImageFilter SkeletonFilterType; - typename SkeletonFilterType::Pointer skeletonFilter = SkeletonFilterType::New(); - skeletonFilter->SetInput(m_working_trachea); - skeletonFilter->Update(); - writeImage(skeletonFilter->GetOutput(), "skel.mhd"); - writeImage(skeletonFilter->GetThinning(), "skel2.mhd"); - */ - - //----------------------------------------------------- - StartNewStep("Left limits with bronchus (slice by slice)"); - // Select LeftLabel (set right label to 0) - ImagePointer temp = SetBackground(m_working_trachea, m_working_trachea, rightLabel, 0); - writeImage(temp, "temp1.mhd"); - - typedef clitk::SliceBySliceRelativePositionFilter SliceRelPosFilterType; - typename SliceRelPosFilterType::Pointer sliceRelPosFilter = SliceRelPosFilterType::New(); - sliceRelPosFilter->SetCurrentStepBaseId(this->GetCurrentStepId()); - sliceRelPosFilter->VerboseStepOn(); - sliceRelPosFilter->WriteStepOn(); - sliceRelPosFilter->SetInput(m_working_image); - sliceRelPosFilter->SetInputObject(temp); - sliceRelPosFilter->SetDirection(2); - sliceRelPosFilter->SetFuzzyThreshold(0.6); - sliceRelPosFilter->SetOrientationType(SliceRelPosFilterType::RelPosFilterType::RightTo); - sliceRelPosFilter->Update(); - m_working_image = sliceRelPosFilter->GetOutput(); - writeImage(m_working_image, "afterslicebyslice.mhd"); - - - //----------------------------------------------------- - StartNewStep("Right limits with bronchus (slice by slice)"); - // Select LeftLabel (set right label to 0) - temp = SetBackground(m_working_trachea, m_working_trachea, leftLabel, 0); - writeImage(temp, "temp2.mhd"); - - sliceRelPosFilter = SliceRelPosFilterType::New(); - sliceRelPosFilter->SetCurrentStepBaseId(this->GetCurrentStepId()); - sliceRelPosFilter->VerboseStepOn(); - sliceRelPosFilter->WriteStepOn(); - sliceRelPosFilter->SetInput(m_working_image); - sliceRelPosFilter->SetInputObject(temp); - sliceRelPosFilter->SetDirection(2); - sliceRelPosFilter->SetFuzzyThreshold(0.6); - sliceRelPosFilter->SetOrientationType(SliceRelPosFilterType::RelPosFilterType::LeftTo); - sliceRelPosFilter->Update(); - m_working_image = sliceRelPosFilter->GetOutput(); - writeImage(m_working_image, "afterslicebyslice.mhd"); - - - DD("end"); - m_output = m_working_image; - StopCurrentStep(m_output); - - // Set output image information (required) - ImagePointer outputImage = this->GetOutput(0); - outputImage->SetRegions(m_working_image->GetLargestPossibleRegion()); - outputImage->SetOrigin(m_working_image->GetOrigin()); - outputImage->SetRequestedRegion(m_working_image->GetLargestPossibleRegion()); - DD("end2"); + +//-------------------------------------------------------------------- +template +void +clitk::ExtractLymphStationsFilter:: +ExtractStation_7() { + if (CheckForStation("7")) { + ExtractStation_7_SI_Limits(); + ExtractStation_7_RL_Limits(); + ExtractStation_7_Posterior_Limits(); + // ExtractStation_8_Single_CCL_Limits(); // Yes the same than 8 + ExtractStation_7_Remove_Structures(); + // Store image filenames into AFDB + writeImage(m_ListOfStations["7"], "seg/Station7.mhd"); + GetAFDB()->SetImageFilename("Station7", "seg/Station7.mhd"); + WriteAFDB(); + } } //-------------------------------------------------------------------- @@ -272,15 +263,17 @@ GenerateOutputInformation() { template void clitk::ExtractLymphStationsFilter:: -GenerateInputRequestedRegion() { - DD("GenerateInputRequestedRegion"); - // Call default - Superclass::GenerateInputRequestedRegion(); - // Following needed because output region can be greater than input (trachea) - ImagePointer mediastinum = dynamic_cast(itk::ProcessObject::GetInput(0)); - ImagePointer trachea = dynamic_cast(itk::ProcessObject::GetInput(1)); - mediastinum->SetRequestedRegion(mediastinum->GetLargestPossibleRegion()); - trachea->SetRequestedRegion(trachea->GetLargestPossibleRegion()); +ExtractStation_3A() +{ + if (CheckForStation("3A")) { + ExtractStation_3A_SI_Limits(); + ExtractStation_3A_Ant_Limits(); + ExtractStation_3A_Post_Limits(); + // Store image filenames into AFDB + writeImage(m_ListOfStations["3A"], "seg/Station3A.mhd"); + GetAFDB()->SetImageFilename("Station3A", "seg/Station3A.mhd"); + WriteAFDB(); + } } //-------------------------------------------------------------------- @@ -289,12 +282,95 @@ GenerateInputRequestedRegion() { template void clitk::ExtractLymphStationsFilter:: -GenerateData() { - DD("GenerateData"); - // Final Step -> graft output (if SetNthOutput => redo) - this->GraftOutput(m_output); +ExtractStation_2RL() +{ + if (CheckForStation("2RL")) { + ExtractStation_2RL_SI_Limits(); + ExtractStation_2RL_Post_Limits(); + ExtractStation_2RL_Ant_Limits2(); + ExtractStation_2RL_Ant_Limits(); + ExtractStation_2RL_LR_Limits(); + ExtractStation_2RL_Remove_Structures(); + ExtractStation_2RL_SeparateRL(); + + // Store image filenames into AFDB + writeImage(m_ListOfStations["2R"], "seg/Station2R.mhd"); + writeImage(m_ListOfStations["2L"], "seg/Station2L.mhd"); + GetAFDB()->SetImageFilename("Station2R", "seg/Station2R.mhd"); + GetAFDB()->SetImageFilename("Station2L", "seg/Station2L.mhd"); + WriteAFDB(); + } +} +//-------------------------------------------------------------------- + + +//-------------------------------------------------------------------- +template +void +clitk::ExtractLymphStationsFilter:: +ExtractStation_4RL() { + DD("TODO"); + exit(0); + /* + WARNING ONLY 4R FIRST !!! (not same inf limits) + */ + ExtractStation_4RL_SI_Limits(); + ExtractStation_4RL_LR_Limits(); + ExtractStation_4RL_AP_Limits(); +} +//-------------------------------------------------------------------- + + +//-------------------------------------------------------------------- +template +void +clitk::ExtractLymphStationsFilter:: +Remove_Structures(std::string station, std::string s) +{ + try { + StartNewStep("[Station"+station+"] Remove "+s); + MaskImagePointer Structure = GetAFDB()->template GetImage(s); + clitk::AndNot(m_Working_Support, Structure, GetBackgroundValue()); + } + catch(clitk::ExceptionObject e) { + std::cout << s << " not found, skip." << std::endl; + } } //-------------------------------------------------------------------- + + +//-------------------------------------------------------------------- +template +void +clitk::ExtractLymphStationsFilter:: +SetFuzzyThreshold(std::string station, std::string tag, double value) +{ + m_FuzzyThreshold[station][tag] = value; +} +//-------------------------------------------------------------------- + + +//-------------------------------------------------------------------- +template +double +clitk::ExtractLymphStationsFilter:: +GetFuzzyThreshold(std::string station, std::string tag) +{ + if (m_FuzzyThreshold.find(station) == m_FuzzyThreshold.end()) { + clitkExceptionMacro("Could not find options for station "+station+" in the list (while searching for tag "+tag+")."); + return 0.0; + } + + if (m_FuzzyThreshold[station].find(tag) == m_FuzzyThreshold[station].end()) { + clitkExceptionMacro("Could not find options "+tag+" in the list of FuzzyThreshold for station "+station+"."); + return 0.0; + } + return m_FuzzyThreshold[station][tag]; +} +//-------------------------------------------------------------------- + + + #endif //#define CLITKBOOLEANOPERATORLABELIMAGEFILTER_TXX