X-Git-Url: https://git.creatis.insa-lyon.fr/pubgit/?a=blobdiff_plain;ds=sidebyside;f=segmentation%2FclitkExtractPatientFilter.txx;h=97f79c5e9050bdcf1b5b4d2275ad0a32e73c60f8;hb=aa424793243b9b210a0d009f5cb8031db985549a;hp=00e31653afce00e5ea32c5a91a1218fbe39251fa;hpb=5d07c6f09eee2f55347c6722c16c1f81de28e747;p=clitk.git diff --git a/segmentation/clitkExtractPatientFilter.txx b/segmentation/clitkExtractPatientFilter.txx index 00e3165..97f79c5 100644 --- a/segmentation/clitkExtractPatientFilter.txx +++ b/segmentation/clitkExtractPatientFilter.txx @@ -48,6 +48,7 @@ ExtractPatientFilter(): this->SetNumberOfRequiredInputs(1); SetBackgroundValue(0); // Must be zero SetForegroundValue(1); + SetPrimaryOpeningRadius(0); // Step 1: Threshold + CC + sort (Find low density areas) SetUpperThreshold(-300); @@ -116,6 +117,7 @@ GenerateOutputInformation() { StartNewStep("Find low densities areas"); // Pad images with air to prevent patient touching the image border + // But the lungs can touch the outside air. In such case, use primaryOpeningRadius with 1 kernel typedef itk::ConstantPadImageFilter PadFilterType; typename PadFilterType::Pointer padFilter = PadFilterType::New(); padFilter->SetInput(input); @@ -126,7 +128,8 @@ GenerateOutputInformation() { bounds[Dim - 1] = 0; padFilter->SetPadLowerBound(bounds); padFilter->SetPadUpperBound(bounds); - + padFilter->Update(); + typedef itk::BinaryThresholdImageFilter BinarizeFilterType; typename BinarizeFilterType::Pointer binarizeFilter=BinarizeFilterType::New(); binarizeFilter->SetInput(padFilter->GetOutput()); @@ -134,20 +137,47 @@ GenerateOutputInformation() { binarizeFilter->SetUpperThreshold(GetUpperThreshold()); binarizeFilter ->SetInsideValue(this->GetForegroundValue()); binarizeFilter ->SetOutsideValue(this->GetBackgroundValue()); + padFilter->GetOutput()->ReleaseData(); + working_image = binarizeFilter->GetOutput(); + + typedef itk::BinaryBallStructuringElement KernelType; + unsigned int radius = this->GetPrimaryOpeningRadius(); + if (radius > 0) + { + if (this->GetVerboseOptionFlag()) std::cout << ("Opening after threshold; R = ") << radius << std::endl; + KernelType kernel; + kernel.SetRadius(radius); + + typedef itk::BinaryMorphologicalOpeningImageFilter OpenFilterType2; + typename OpenFilterType2::Pointer openFilter2 = OpenFilterType2::New(); + openFilter2->SetInput(working_image); + openFilter2->SetBackgroundValue(0); + openFilter2->SetForegroundValue(1); + openFilter2->SetKernel(kernel); + openFilter2->Update(); + working_image->ReleaseData(); + working_image = openFilter2->GetOutput(); + } + if (this->GetVerboseOptionFlag()) std::cout << ("Labelling") << std::endl; // Connected component labeling typedef itk::ConnectedComponentImageFilter ConnectFilterType; typename ConnectFilterType::Pointer connectFilter=ConnectFilterType::New(); - connectFilter->SetInput(binarizeFilter->GetOutput()); + connectFilter->SetInput(working_image); connectFilter->SetBackgroundValue(this->GetBackgroundValue()); connectFilter->SetFullyConnected(false); + connectFilter->Update(); + working_image->ReleaseData(); + working_image = connectFilter->GetOutput(); + if (this->GetVerboseOptionFlag()) std::cout << ("RelabelComponentImageFilter") << std::endl; // Sort labels according to size typedef itk::RelabelComponentImageFilter RelabelFilterType; typename RelabelFilterType::Pointer relabelFilter=RelabelFilterType::New(); relabelFilter->InPlaceOn(); relabelFilter->SetInput(connectFilter->GetOutput()); relabelFilter->Update(); + working_image->ReleaseData(); working_image = relabelFilter->GetOutput(); // End @@ -169,12 +199,14 @@ GenerateOutputInformation() { f->SetFullyConnected(true); f->SetNumberOfNewLabels(GetNumberOfNewLabels1()); f->Update(); + working_image->ReleaseData(); working_image = f->GetOutput(); StopCurrentStep(working_image); } //-------------------------------------------------------------------- //-------------------------------------------------------------------- + if (this->GetVerboseOptionFlag()) std::cout << ("Remove the air (largest area)") << std::endl; StartNewStep("Remove the air (largest area)"); typedef itk::BinaryThresholdImageFilter iBinarizeFilterType; typename iBinarizeFilterType::Pointer binarizeFilter2 = iBinarizeFilterType::New(); @@ -183,16 +215,22 @@ GenerateOutputInformation() { binarizeFilter2->SetUpperThreshold(GetLastKeep()); binarizeFilter2 ->SetInsideValue(0); binarizeFilter2 ->SetOutsideValue(1); - // binarizeFilter2 ->Update(); // NEEDED ? + binarizeFilter2 ->Update(); + working_image->ReleaseData(); + working_image = binarizeFilter2->GetOutput(); typename ConnectFilterType::Pointer connectFilter2 = ConnectFilterType::New(); - connectFilter2->SetInput(binarizeFilter2->GetOutput()); + connectFilter2->SetInput(working_image); connectFilter2->SetBackgroundValue(this->GetBackgroundValue()); connectFilter2->SetFullyConnected(false); + connectFilter2->Update(); + working_image->ReleaseData(); + working_image = connectFilter2->GetOutput(); typename RelabelFilterType::Pointer relabelFilter2 = RelabelFilterType::New(); - relabelFilter2->SetInput(connectFilter2->GetOutput()); + relabelFilter2->SetInput(working_image); relabelFilter2->Update(); + working_image->ReleaseData(); working_image = relabelFilter2->GetOutput(); // Keep main label @@ -216,6 +254,7 @@ GenerateOutputInformation() { f->SetFullyConnected(true); f->SetNumberOfNewLabels(GetNumberOfNewLabels2()); f->Update(); + working_image->ReleaseData(); working_image = f->GetOutput(); StopCurrentStep(working_image); } @@ -226,7 +265,6 @@ GenerateOutputInformation() { if (GetFinalOpenClose()) { StartNewStep("Final OpenClose"); // Open - typedef itk::BinaryBallStructuringElement KernelType; KernelType structuringElement; structuringElement.SetRadius(1); structuringElement.CreateStructuringElement(); @@ -245,6 +283,7 @@ GenerateOutputInformation() { // closeFilter->SetBackgroundValue(SetBackgroundValue()); closeFilter->SetKernel(structuringElement); closeFilter->Update(); + working_image->ReleaseData(); working_image = closeFilter->GetOutput(); StopCurrentStep(working_image); } @@ -256,6 +295,7 @@ GenerateOutputInformation() { typename CastImageFilterType::Pointer caster= CastImageFilterType::New(); caster->SetInput(working_image); caster->Update(); + working_image->ReleaseData(); output = caster->GetOutput(); //-------------------------------------------------------------------- @@ -268,6 +308,7 @@ GenerateOutputInformation() { cropFilter->SetInput(output); cropFilter->SetBackgroundValue(GetBackgroundValue()); cropFilter->Update(); + output->ReleaseData(); output = cropFilter->GetOutput(); StopCurrentStep(output); } @@ -280,6 +321,7 @@ GenerateOutputInformation() { cropFilter->SetLowerBoundaryCropSize(bounds); cropFilter->SetUpperBoundaryCropSize(bounds); cropFilter->Update(); + output->ReleaseData(); output = cropFilter->GetOutput(); } }