this->SetNumberOfRequiredInputs(1);
SetBackgroundValue(0); // Must be zero
SetForegroundValue(1);
+ SetPrimaryOpeningRadius(0);
// Step 1: Threshold + CC + sort (Find low density areas)
SetUpperThreshold(-300);
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<InputImageType, InputImageType> PadFilterType;
typename PadFilterType::Pointer padFilter = PadFilterType::New();
padFilter->SetInput(input);
bounds[Dim - 1] = 0;
padFilter->SetPadLowerBound(bounds);
padFilter->SetPadUpperBound(bounds);
-
+ padFilter->Update();
+
typedef itk::BinaryThresholdImageFilter<InputImageType, InternalImageType> BinarizeFilterType;
typename BinarizeFilterType::Pointer binarizeFilter=BinarizeFilterType::New();
binarizeFilter->SetInput(padFilter->GetOutput());
binarizeFilter->SetUpperThreshold(GetUpperThreshold());
binarizeFilter ->SetInsideValue(this->GetForegroundValue());
binarizeFilter ->SetOutsideValue(this->GetBackgroundValue());
+ padFilter->GetOutput()->ReleaseData();
+ working_image = binarizeFilter->GetOutput();
+
+ typedef itk::BinaryBallStructuringElement<InternalPixelType,Dim> 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<InternalImageType, InternalImageType , KernelType> 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<InternalImageType, InternalImageType> 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<InternalImageType, InternalImageType> RelabelFilterType;
typename RelabelFilterType::Pointer relabelFilter=RelabelFilterType::New();
relabelFilter->InPlaceOn();
relabelFilter->SetInput(connectFilter->GetOutput());
relabelFilter->Update();
+ working_image->ReleaseData();
working_image = relabelFilter->GetOutput();
// End
f->SetFullyConnected(true);
f->SetNumberOfNewLabels(GetNumberOfNewLabels1());
f->Update();
+ working_image->ReleaseData();
working_image = f->GetOutput();
StopCurrentStep<InternalImageType>(working_image);
}
//--------------------------------------------------------------------
//--------------------------------------------------------------------
+ if (this->GetVerboseOptionFlag()) std::cout << ("Remove the air (largest area)") << std::endl;
StartNewStep("Remove the air (largest area)");
typedef itk::BinaryThresholdImageFilter<InternalImageType, InternalImageType> iBinarizeFilterType;
typename iBinarizeFilterType::Pointer binarizeFilter2 = iBinarizeFilterType::New();
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
f->SetFullyConnected(true);
f->SetNumberOfNewLabels(GetNumberOfNewLabels2());
f->Update();
+ working_image->ReleaseData();
working_image = f->GetOutput();
StopCurrentStep<InternalImageType>(working_image);
}
if (GetFinalOpenClose()) {
StartNewStep("Final OpenClose");
// Open
- typedef itk::BinaryBallStructuringElement<InternalPixelType,Dim> KernelType;
KernelType structuringElement;
structuringElement.SetRadius(1);
structuringElement.CreateStructuringElement();
// closeFilter->SetBackgroundValue(SetBackgroundValue());
closeFilter->SetKernel(structuringElement);
closeFilter->Update();
+ working_image->ReleaseData();
working_image = closeFilter->GetOutput();
StopCurrentStep<InternalImageType>(working_image);
}
typename CastImageFilterType::Pointer caster= CastImageFilterType::New();
caster->SetInput(working_image);
caster->Update();
+ working_image->ReleaseData();
output = caster->GetOutput();
//--------------------------------------------------------------------
cropFilter->SetInput(output);
cropFilter->SetBackgroundValue(GetBackgroundValue());
cropFilter->Update();
+ output->ReleaseData();
output = cropFilter->GetOutput();
StopCurrentStep<MaskImageType>(output);
}
cropFilter->SetLowerBoundaryCropSize(bounds);
cropFilter->SetUpperBoundaryCropSize(bounds);
cropFilter->Update();
+ output->ReleaseData();
output = cropFilter->GetOutput();
}
}