X-Git-Url: https://git.creatis.insa-lyon.fr/pubgit/?a=blobdiff_plain;f=segmentation%2FclitkExtractLungFilter.txx;h=596604b61f44b1f6e1c8c39115f3888a4f069734;hb=HEAD;hp=41e79677bf88c69ebf1788418fc144695f34587b;hpb=20c4d89862ca9a9f4be92f312db7c6572e24075e;p=clitk.git diff --git a/segmentation/clitkExtractLungFilter.txx b/segmentation/clitkExtractLungFilter.txx index 41e7967..596604b 100644 --- a/segmentation/clitkExtractLungFilter.txx +++ b/segmentation/clitkExtractLungFilter.txx @@ -47,6 +47,8 @@ #include "itkOrientImageFilter.h" #include "itkSpatialOrientationAdapter.h" #include "itkImageDuplicator.h" +#include "itkRelabelComponentImageFilter.h" + #include //-------------------------------------------------------------------- @@ -67,6 +69,7 @@ ExtractLungFilter(): SetForegroundValue(1); SetMinimalComponentSize(100); VerboseRegionGrowingFlagOff(); + RemoveSmallLabelBeforeSeparationFlagOn(); // Step 1 default values SetUpperThreshold(-300); @@ -87,8 +90,7 @@ ExtractLungFilter(): TracheaVolumeMustBeCheckedFlagOn(); SetNumSlices(50); SetMaxElongation(0.5); - SetSeedPreProcessingThreshold(-400); - + SetSeedPreProcessingThreshold(-400); // Step 3 default values SetNumberOfHistogramBins(500); @@ -132,7 +134,19 @@ SetInput(const ImageType * image) template void clitk::ExtractLungFilter:: -AddSeed(InternalIndexType s) +//AddSeed(InternalIndexType s) +AddSeed(InputImagePointType s) +{ + m_SeedsInMM.push_back(s); +} +//-------------------------------------------------------------------- + + +//-------------------------------------------------------------------- +template +void +clitk::ExtractLungFilter:: +AddSeedInPixels(InternalIndexType s) { m_Seeds.push_back(s); } @@ -259,6 +273,9 @@ GenerateOutputInformation() StartNewStep("Search for the trachea"); SearchForTrachea(); PrintMemory(GetVerboseMemoryFlag(), "After SearchForTrachea"); + if (m_Seeds.empty()) { + clitkExceptionMacro("No seeds for trachea... Aborting."); + } //-------------------------------------------------------------------- //-------------------------------------------------------------------- @@ -433,7 +450,7 @@ GenerateOutputInformation() //-------------------------------------------------------------------- //-------------------------------------------------------------------- StartNewStep("Separate Left/Right lungs"); - PrintMemory(GetVerboseMemoryFlag(), "Before Separate"); + PrintMemory(GetVerboseMemoryFlag(), "Before Separate"); // Initial label working_mask = Labelize(working_mask, GetBackgroundValue(), @@ -448,9 +465,32 @@ GenerateOutputInformation() statisticsImageFilter->SetInput(working_mask); statisticsImageFilter->Update(); unsigned int initialNumberOfLabels = statisticsImageFilter->GetMaximum(); - working_mask = statisticsImageFilter->GetOutput(); - + working_mask = statisticsImageFilter->GetOutput(); PrintMemory(GetVerboseMemoryFlag(), "After count label"); + + // If already 2 labels, but a too big differences, remove the + // smalest one (sometimes appends with the stomach + if (initialNumberOfLabels >1) { + if (GetRemoveSmallLabelBeforeSeparationFlag()) { + typedef itk::RelabelComponentImageFilter RelabelFilterType; + typename RelabelFilterType::Pointer relabelFilter = RelabelFilterType::New(); + relabelFilter->SetInput(working_mask); + relabelFilter->SetMinimumObjectSize(10); + relabelFilter->Update(); + const std::vector & a = relabelFilter->GetSizeOfObjectsInPhysicalUnits(); + std::vector remove_label; + for(unsigned int i=1; i(working_mask, GetBackgroundValue(), remove_label); + statisticsImageFilter->SetInput(working_mask); + statisticsImageFilter->Update(); + initialNumberOfLabels = statisticsImageFilter->GetMaximum(); + } + } // Decompose the first label if (initialNumberOfLabels<2) { @@ -547,7 +587,7 @@ SearchForTracheaSeed(int skip) it.GoToBegin(); while (!it.IsAtEnd()) { if(it.Get() < GetUpperThresholdForTrachea() ) { - AddSeed(it.GetIndex()); + AddSeedInPixels(it.GetIndex()); // DD(it.GetIndex()); } ++it; @@ -628,6 +668,7 @@ SearchForTracheaSeed2(int numberOfSlices) opening->Update(); typename SlicerFilterType::Pointer slicer = SlicerFilterType::New(); + slicer->SetDirectionCollapseToIdentity(); slicer->SetInput(opening->GetOutput()); // label result @@ -709,11 +750,7 @@ SearchForTracheaSeed2(int numberOfSlices) for (unsigned int j = 0; j < nlables; j++) { shape = label_map->GetNthLabelObject(j); if (shape->Size() > 150 && shape->Size() <= max_size) { -#if ITK_VERSION_MAJOR < 4 - double e = 1 - 1/shape->GetBinaryElongation(); -#else double e = 1 - 1/shape->GetElongation(); -#endif //double area = 1 - r->Area() ; if (e < max_elongation) { nshapes++; @@ -766,6 +803,11 @@ SearchForTracheaSeed2(int numberOfSlices) prev_e_centre= max_e_centre; } + else { + if (GetVerboseRegionGrowingFlag()) { + cout << "No shapes found at slice " << index[2] << std::endl; + } + } } size_t longest = 0; @@ -778,9 +820,11 @@ SearchForTracheaSeed2(int numberOfSlices) } } - if (GetVerboseRegionGrowingFlag()) - std::cout << "seed at: " << trachea_centre << std::endl; - m_Seeds.push_back(trachea_centre); + if (longest > 0) { + if (GetVerboseRegionGrowingFlag()) + std::cout << "seed at: " << trachea_centre << std::endl; + m_Seeds.push_back(trachea_centre); + } } return (m_Seeds.size() != 0); @@ -802,7 +846,7 @@ TracheaRegionGrowing() f->SetUpper(GetUpperThresholdForTrachea()); f->SetMinimumLowerThreshold(-2000); // f->SetMaximumUpperThreshold(0); // MAYBE TO CHANGE ??? - f->SetMaximumUpperThreshold(-700); // MAYBE TO CHANGE ??? + f->SetMaximumUpperThreshold(-300); // MAYBE TO CHANGE ??? f->SetAdaptLowerBorder(false); f->SetAdaptUpperBorder(true); f->SetMinimumSize(5000); @@ -813,7 +857,7 @@ TracheaRegionGrowing() f->SetVerbose(GetVerboseRegionGrowingFlag()); for(unsigned int i=0; iAddSeed(m_Seeds[i]); - // DD(m_Seeds[i]); + //DD(m_Seeds[i]); } f->Update(); PrintMemory(GetVerboseMemoryFlag(), "After RG update"); @@ -867,6 +911,15 @@ SearchForTrachea() // compute trachea volume // if volume not plausible -> skip more slices and restart + // If initial seed, convert from mm to pixels + if (m_SeedsInMM.size() > 0) { + for(unsigned int i=0; iTransformPhysicalPointToIndex(m_SeedsInMM[i], index); + m_Seeds.push_back(index); + } + } + bool has_seed; bool stop = false; double volume = 0.0; @@ -892,16 +945,17 @@ SearchForTrachea() std::cout << "\t Found trachea with volume " << volume << " cc." << std::endl; } } - else { - if (GetVerboseStepFlag()) { - std::cout << "\t The volume of the trachea (" << volume - << " cc) seems not correct. I skip some slices (" << skip << ") and restart to find seeds." - << std::endl; - } - skip += 5; - stop = false; - // empty the list of seed - m_Seeds.clear(); + else + if (GetTracheaSeedAlgorithm() == 0) { + if (GetVerboseStepFlag()) { + std::cout << "\t The volume of the trachea (" << volume + << " cc) seems not correct. I skip some slices (" << skip << ") and restart to find seeds." + << std::endl; + } + skip += 5; + stop = false; + // empty the list of seed + m_Seeds.clear(); } if (skip > 0.5 * working_input->GetLargestPossibleRegion().GetSize()[2]) { // we want to skip more than a half of the image, it is probably a bug