Authors belong to:
- University of LYON http://www.universite-lyon.fr/
- - Léon Bérard cancer center http://oncora1.lyon.fnclcc.fr
+ - Léon Bérard cancer center http://www.centreleonberard.fr
- CREATIS CNRS laboratory http://www.creatis.insa-lyon.fr
This software is distributed WITHOUT ANY WARRANTY; without even
- BSD See included LICENSE.txt file
- CeCILL-B http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html
- ======================================================================-====*/
+ ===========================================================================**/
#ifndef CLITKEXTRACTBONESSFILTER_TXX
#define CLITKEXTRACTBONESSFILTER_TXX
#include "clitkSetBackgroundImageFilter.h"
#include "clitkSegmentationUtils.h"
#include "clitkAutoCropFilter.h"
+#include "clitkFillMaskFilter.h"
// itk
#include "itkBinaryThresholdImageFilter.h"
#include "itkConnectedComponentImageFilter.h"
#include "itkRelabelComponentImageFilter.h"
#include "itkNeighborhoodConnectedImageFilter.h"
+#include "itkCurvatureAnisotropicDiffusionImageFilter.h"
//--------------------------------------------------------------------
-template <class TInputImageType, class TOutputImageType>
-clitk::ExtractBonesFilter<TInputImageType, TOutputImageType>::
+template <class TInputImageType>
+clitk::ExtractBonesFilter<TInputImageType>::
ExtractBonesFilter():
clitk::FilterBase(),
- itk::ImageToImageFilter<TInputImageType, TOutputImageType>()
+ clitk::FilterWithAnatomicalFeatureDatabaseManagement(),
+ itk::ImageToImageFilter<TInputImageType, MaskImageType>()
{
// Default global options
this->SetNumberOfRequiredInputs(1);
SetBackgroundValue(0); // Must be zero
SetForegroundValue(1);
+ SetInitialSmoothing(false);
+
+ SetSmoothingConductanceParameter(3.0);
+ SetSmoothingNumberOfIterations(5);
+ SetSmoothingTimeStep(0.0625);
+ SetSmoothingUseImageSpacing(false);
SetMinimalComponentSize(100);
SetUpperThreshold1(1500);
s.Fill(1);
SetRadius2(s);
SetSampleRate2(0);
- AutoCropOff();
+ AutoCropOn();
+ FillHolesOn();
}
//--------------------------------------------------------------------
//--------------------------------------------------------------------
-template <class TInputImageType, class TOutputImageType>
+template <class TInputImageType>
void
-clitk::ExtractBonesFilter<TInputImageType, TOutputImageType>::
+clitk::ExtractBonesFilter<TInputImageType>::
SetInput(const TInputImageType * image)
{
this->SetNthInput(0, const_cast<TInputImageType *>(image));
//--------------------------------------------------------------------
-//--------------------------------------------------------------------
-template <class TInputImageType, class TOutputImageType>
-template<class ArgsInfoType>
-void
-clitk::ExtractBonesFilter<TInputImageType, TOutputImageType>::
-SetArgsInfo(ArgsInfoType mArgsInfo)
-{
- SetVerboseOption_GGO(mArgsInfo);
- SetVerboseStep_GGO(mArgsInfo);
- SetWriteStep_GGO(mArgsInfo);
- SetVerboseWarningOff_GGO(mArgsInfo);
-
- SetMinimalComponentSize_GGO(mArgsInfo);
- SetUpperThreshold1_GGO(mArgsInfo);
- SetLowerThreshold1_GGO(mArgsInfo);
- SetFullConnectivity_GGO(mArgsInfo);
-
- SetUpperThreshold2_GGO(mArgsInfo);
- SetLowerThreshold2_GGO(mArgsInfo);
- SetRadius2_GGO(mArgsInfo);
- SetSampleRate2_GGO(mArgsInfo);
- SetAutoCrop_GGO(mArgsInfo);
-}
-//--------------------------------------------------------------------
-
//--------------------------------------------------------------------
-template <class TInputImageType, class TOutputImageType>
+template <class TInputImageType>
void
-clitk::ExtractBonesFilter<TInputImageType, TOutputImageType>::
+clitk::ExtractBonesFilter<TInputImageType>::
GenerateOutputInformation() {
+
// Get input pointers
InputImagePointer input = dynamic_cast<TInputImageType*>(itk::ProcessObject::GetInput(0));
- // InputImagePointer input = dynamic_cast<TInputImageType*>(itk::ProcessObject::GetInput(0));
Superclass::GenerateOutputInformation();
- OutputImagePointer outputImage = this->GetOutput(0);
+ MaskImagePointer outputImage = this->GetOutput(0);
outputImage->SetRegions(input->GetLargestPossibleRegion());
+ // Read DB
+ LoadAFDB();
+
// typedefs
typedef itk::BinaryThresholdImageFilter<InputImageType, InternalImageType> InputBinarizeFilterType;
typedef itk::BinaryThresholdImageFilter<InternalImageType, InternalImageType> BinarizeFilterType;
typedef itk::ConnectedComponentImageFilter<InternalImageType, InternalImageType> ConnectFilterType;
typedef itk::RelabelComponentImageFilter<InternalImageType, InternalImageType> RelabelFilterType;
typedef clitk::SetBackgroundImageFilter<InternalImageType,InternalImageType, InternalImageType> SetBackgroundFilterType;
- typedef itk::CastImageFilter<InternalImageType,OutputImageType> CastImageFilterType;
- typedef itk::ImageFileWriter<OutputImageType> WriterType;
+ typedef itk::CastImageFilter<InternalImageType,MaskImageType> CastImageFilterType;
+ typedef itk::ImageFileWriter<MaskImageType> WriterType;
+
+ //---------------------------------
+ // Smoothing [Optional]
+ //---------------------------------
+ if (GetInitialSmoothing()) {
+ StartNewStep("Initial Smoothing");
+ typedef itk::CurvatureAnisotropicDiffusionImageFilter<InputImageType, InputImageType> FilterType;
+ typename FilterType::Pointer df = FilterType::New();
+ df->SetConductanceParameter(GetSmoothingConductanceParameter());
+ df->SetNumberOfIterations(GetSmoothingNumberOfIterations());
+ df->SetTimeStep(GetSmoothingTimeStep());
+ df->SetUseImageSpacing(GetSmoothingUseImageSpacing());
+ df->SetInput(input);
+ df->Update();
+ filtered_input = df->GetOutput();
+ StopCurrentStep<InputImageType>(filtered_input);
+ }
+ else {
+ filtered_input = input;
+ }
//--------------------------------------------------------------------
//--------------------------------------------------------------------
StartNewStep("Initial Labeling");
-
typename InternalImageType::Pointer firstLabelImage;
//---------------------------------
// Binarize the image
//---------------------------------
typename InputBinarizeFilterType::Pointer binarizeFilter=InputBinarizeFilterType::New();
- binarizeFilter->SetInput(input);
+ binarizeFilter->SetInput(filtered_input);
binarizeFilter->SetLowerThreshold(GetLowerThreshold1());
binarizeFilter->SetUpperThreshold(GetUpperThreshold1());
binarizeFilter->SetInsideValue(this->GetForegroundValue());
binarizeFilter2->Update();
firstLabelImage = binarizeFilter2->GetOutput();
+ StopCurrentStep<InternalImageType>(firstLabelImage);
//--------------------------------------------------------------------
//--------------------------------------------------------------------
neighborhoodConnectedImageFilter->SetUpper(GetUpperThreshold2());
neighborhoodConnectedImageFilter->SetReplaceValue(this->GetForegroundValue());
neighborhoodConnectedImageFilter->SetRadius(GetRadius2());
- neighborhoodConnectedImageFilter->SetInput(input);
+ neighborhoodConnectedImageFilter->SetInput(filtered_input);
// Seeds from label image
typedef itk::ImageRegionIteratorWithIndex<InternalImageType> IteratorType;
//--------------------------------------------------------------------
//--------------------------------------------------------------------
- StartNewStep("Combine de images");
+ StartNewStep("Combine the images");
typedef clitk::SetBackgroundImageFilter<InternalImageType, InternalImageType, InternalImageType>
SetBackgroundImageFilterType;
typename SetBackgroundImageFilterType::Pointer setBackgroundFilter=SetBackgroundImageFilterType::New();
output = setBackgroundFilter->GetOutput();
+ //--------------------------------------------------------------------
+ //--------------------------------------------------------------------
+ // Fill Bones
+ if (GetFillHoles()) {
+ StartNewStep("Fill Holes");
+ typedef clitk::FillMaskFilter<InternalImageType> FillMaskFilterType;
+ typename FillMaskFilterType::Pointer fillMaskFilter = FillMaskFilterType::New();
+ fillMaskFilter->SetInput(output);
+ fillMaskFilter->AddDirection(2);
+ fillMaskFilter->Update();
+ output = fillMaskFilter->GetOutput();
+ StopCurrentStep<InternalImageType>(output);
+ }
+
//--------------------------------------------------------------------
//--------------------------------------------------------------------
// [Optional]
//--------------------------------------------------------------------
-template <class TInputImageType, class TOutputImageType>
+template <class TInputImageType>
void
-clitk::ExtractBonesFilter<TInputImageType, TOutputImageType>::
+clitk::ExtractBonesFilter<TInputImageType>::
GenerateData() {
//--------------------------------------------------------------------
//--------------------------------------------------------------------
// Final Cast
- typedef itk::CastImageFilter<InternalImageType, OutputImageType> CastImageFilterType;
+ typedef itk::CastImageFilter<InternalImageType, MaskImageType> CastImageFilterType;
typename CastImageFilterType::Pointer caster= CastImageFilterType::New();
caster->SetInput(output);
caster->Update();
- //this->SetNthOutput(0, caster->GetOutput());
this->GraftOutput(caster->GetOutput());
+
+ // Store image filenames into AFDB
+ GetAFDB()->SetImageFilename("Bones", this->GetOutputBonesFilename());
+ WriteAFDB();
return;
}
//--------------------------------------------------------------------