//--------------------------------------------------------------------
+//--------------------------------------------------------------------
+//http://stackoverflow.com/questions/216823/whats-the-best-way-to-trim-stdstring
+// trim from start
+static inline std::string <rim(std::string &s) {
+ s.erase(s.begin(), std::find_if(s.begin(), s.end(), std::not1(std::ptr_fun<int, int>(std::isspace))));
+ return s;
+}
+// trim from end
+static inline std::string &rtrim(std::string &s) {
+ s.erase(std::find_if(s.rbegin(), s.rend(), std::not1(std::ptr_fun<int, int>(std::isspace))).base(), s.end());
+ return s;
+}
+// trim from both ends
+static inline std::string &trim(std::string &s) {
+ return ltrim(rtrim(s));
+}
+//--------------------------------------------------------------------
+
+
//--------------------------------------------------------------------
void clitk::AnatomicalFeatureDatabase::Load()
{
is >> tag;
std::string value;
std::getline(is,value,'\n');
+ ltrim(value); // remove leading space
m_MapOfTag[tag] = value;
}
}
// parse the string into 3 doubles
for(int i=0; i<3; i++) {
- DD(results[i]);
p[i] = atof(results[i].c_str());
- DD(p[i]);
}
/*
boost::tokenizer<boost::char_separator<char> > tokens(s, sep);
int i=0;
BOOST_FOREACH(std::string t, tokens) {
- std::cout << t << "." << std::endl;
- p[i] = atof(t.c_str());
- i++;
+ std::cout << t << "." << std::endl;
+ p[i] = atof(t.c_str());
+ i++;
}
*/
}
}
//--------------------------------------------------------------------
+
+//--------------------------------------------------------------------
+void clitk::AnatomicalFeatureDatabase::SetImageFilename(std::string tag, std::string f)
+{
+ m_MapOfTag[tag] = f;
+}
+//--------------------------------------------------------------------
+
// clitk
#include "clitkCommon.h"
+#include "clitkImageCommon.h"
namespace clitk {
+
//--------------------------------------------------------------------
/*
Class to store and retreive anatomical feature such as 3D
public:
AnatomicalFeatureDatabase();
+ typedef std::string TagType;
+
// Set/Get filename
itkSetMacro(Filename, std::string);
itkGetConstMacro(Filename, std::string);
void Write();
void Load();
- // Get landmarks
+ // Set Get landmarks
typedef itk::Point<double,3> PointType3D;
- void SetPoint3D(std::string tag, PointType3D & p);
- void GetPoint3D(std::string tag, PointType3D & p);
+ void SetPoint3D(TagType tag, PointType3D & p);
+ void GetPoint3D(TagType tag, PointType3D & p);
+
+ // Set Get image
+ void SetImageFilename(TagType tag, std::string f);
+ template<class ImageType>
+ typename ImageType::Pointer GetImage(TagType tag);
+ // Set Get Double
+ void SetDouble(TagType tag, double d);
+ double GetDouble(TagType tag);
+
protected:
std::string m_Filename;
- typedef std::map<std::string, std::string> MapTagType;
+ typedef std::map<TagType, std::string> MapTagType;
MapTagType m_MapOfTag;
}; // end class
//--------------------------------------------------------------------
+ #include "clitkAnatomicalFeatureDatabase.txx"
+
} // end namespace clitk
//--------------------------------------------------------------------
extractSliceFilter->GetOutputSlices(mInputSlices);
DD(mInputSlices.size());
+
+ DD("REDO !!!!!!!!!!!!");
+ /**
+ => chercher la bif qui a les plus important sous-arbres
+ **/
+
bool stop = false;
int slice_index = listOfBifurcations[0].index[2]; // first slice from carina in skeleton
int i=0;
TreeIterator firstIter = m_SkeletonTree.child(listOfBifurcations[0].treeIter, 0);
TreeIterator secondIter = m_SkeletonTree.child(listOfBifurcations[0].treeIter, 1);
+ DD(firstIter.number_of_children());
+ DD(secondIter.number_of_children());
typename SliceType::IndexType in1;
typename SliceType::IndexType in2;
while (!stop) {
GetBackgroundValue(),
true,
0); // min component size=0
+ DD(*firstIter);
+ DD(*secondIter);
// Check the value of the two skeleton points;
in1[0] = (*firstIter)[0];
in1[1] = (*firstIter)[1];
if (listOfTrackedPoint.size() == 2) {
// m_SkeletonTree->Add(listOfTrackedPoint[0], index); // the parent is 'index'
// m_SkeletonTree->Add(listOfTrackedPoint[1], index); // the parent is 'index'
+ DD("BifurcationType");
+ DD(listOfTrackedPoint[0]);
+ DD(listOfTrackedPoint[1]);
BifurcationType bif(index, label, label+1, label+2);
bif.treeIter = currentNode;
listOfBifurcations.push_back(bif);
option "input" i "Input image filename" string yes
option "output" o "Output image filename" string yes
-#option "like" l "Resample like this image" string no
+option "afdb" a "Output Anatomical Feature DB (Carina position)" string no
section "Smoothing (curvature anistropic diffusion)"
option "radius2" - "Neighborhood radius" int no multiple default="1"
option "sampleRate2" - "Sample rate of label image for RG: number of voxels to skip between seeds" int no default="0"
-option "autoCrop" - "Crop final mask to BoundingBox" flag off
+option "noAutoCrop" - "If set : do no crop final mask to BoundingBox" flag on
#include "clitkDecomposeAndReconstructImageFilter.h"
#include "clitkExplosionControlledThresholdConnectedImageFilter.h"
#include "clitkSegmentationUtils.h"
+#include "clitkFilterWithAnatomicalFeatureDatabaseManagement.h"
// itk
#include "itkStatisticsImageFilter.h"
*/
//--------------------------------------------------------------------
- template <class TInputImageType, class TOutputImageType>
+ template <class TInputImageType>
class ITK_EXPORT ExtractBonesFilter:
- public clitk::FilterBase,
- public itk::ImageToImageFilter<TInputImageType, TOutputImageType>
+ public virtual clitk::FilterBase,
+ public clitk::FilterWithAnatomicalFeatureDatabaseManagement,
+ public itk::ImageToImageFilter<TInputImageType,
+ itk::Image<uchar, TInputImageType::ImageDimension> >
{
public:
/** Standard class typedefs. */
- typedef ExtractBonesFilter Self;
- typedef itk::ImageToImageFilter<TInputImageType, TOutputImageType> Superclass;
- typedef itk::SmartPointer<Self> Pointer;
- typedef itk::SmartPointer<const Self> ConstPointer;
+ typedef itk::Image<uchar, TInputImageType::ImageDimension> MaskImageType;
+ typedef ExtractBonesFilter Self;
+ typedef itk::ImageToImageFilter<TInputImageType, MaskImageType> Superclass;
+ typedef itk::SmartPointer<Self> Pointer;
+ typedef itk::SmartPointer<const Self> ConstPointer;
/** Method for creation through the object factory. */
itkNewMacro(Self);
typedef typename InputImageType::SizeType InputImageSizeType;
typedef typename InputImageType::IndexType InputImageIndexType;
- typedef TOutputImageType OutputImageType;
- typedef typename OutputImageType::ConstPointer OutputImageConstPointer;
- typedef typename OutputImageType::Pointer OutputImagePointer;
- typedef typename OutputImageType::RegionType OutputImageRegionType;
- typedef typename OutputImageType::PixelType OutputImagePixelType;
- typedef typename OutputImageType::SizeType OutputImageSizeType;
- typedef typename OutputImageType::IndexType OutputImageIndexType;
+ typedef typename MaskImageType::ConstPointer MaskImageConstPointer;
+ typedef typename MaskImageType::Pointer MaskImagePointer;
+ typedef typename MaskImageType::RegionType MaskImageRegionType;
+ typedef typename MaskImageType::PixelType MaskImagePixelType;
+ typedef typename MaskImageType::SizeType MaskImageSizeType;
+ typedef typename MaskImageType::IndexType MaskImageIndexType;
itkStaticConstMacro(ImageDimension, unsigned int, InputImageType::ImageDimension);
typedef int InternalPixelType;
void SetArgsInfo(ArgsInfoType arg);
// Background / Foreground
- itkGetConstMacro(BackgroundValue, OutputImagePixelType);
- itkGetConstMacro(ForegroundValue, OutputImagePixelType);
+ itkGetConstMacro(BackgroundValue, MaskImagePixelType);
+ itkGetConstMacro(ForegroundValue, MaskImagePixelType);
itkSetMacro(MinimalComponentSize, int);
itkGetConstMacro(MinimalComponentSize, int);
GGO_DefineOption(minSize, SetMinimalComponentSize, int);
+
+ // Output filename (for AFBD)
+ itkSetMacro(OutputBonesFilename, std::string);
+ itkGetMacro(OutputBonesFilename, std::string);
+ GGO_DefineOption(output, SetOutputBonesFilename, std::string);
// Step 0
itkBooleanMacro(InitialSmoothing);
itkSetMacro(AutoCrop, bool);
itkGetConstMacro(AutoCrop, bool);
itkBooleanMacro(AutoCrop);
- GGO_DefineOption_Flag(autoCrop, SetAutoCrop);
+ GGO_DefineOption_Flag(noAutoCrop, SetAutoCrop);
protected:
ExtractBonesFilter();
virtual ~ExtractBonesFilter() {}
// Global options
- itkSetMacro(BackgroundValue, OutputImagePixelType);
- itkSetMacro(ForegroundValue, OutputImagePixelType);
- OutputImagePixelType m_BackgroundValue;
- OutputImagePixelType m_ForegroundValue;
+ itkSetMacro(BackgroundValue, MaskImagePixelType);
+ itkSetMacro(ForegroundValue, MaskImagePixelType);
+ MaskImagePixelType m_BackgroundValue;
+ MaskImagePixelType m_ForegroundValue;
bool m_AutoCrop;
// Step 0 : Initial Filtering
void ExtractBones();
void RemoveTrachea();
void BonesSeparation();
+ std::string m_OutputBonesFilename;
InputImageConstPointer input;
InputImagePointer filtered_input;
- OutputImageConstPointer patient;
+ MaskImageConstPointer patient;
InputImagePointer working_input;
typename InternalImageType::Pointer working_image;
typename InternalImageType::Pointer trachea;
#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);
s.Fill(1);
SetRadius2(s);
SetSampleRate2(0);
- AutoCropOff();
+ AutoCropOn();
}
//--------------------------------------------------------------------
//--------------------------------------------------------------------
-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 TInputImageType>
template<class ArgsInfoType>
void
-clitk::ExtractBonesFilter<TInputImageType, TOutputImageType>::
+clitk::ExtractBonesFilter<TInputImageType>::
SetArgsInfo(ArgsInfoType mArgsInfo)
{
SetVerboseOption_GGO(mArgsInfo);
SetWriteStep_GGO(mArgsInfo);
SetVerboseWarningOff_GGO(mArgsInfo);
+ SetOutputBonesFilename_GGO(mArgsInfo);
+
SetInitialSmoothing_GGO(mArgsInfo);
SetSmoothingConductanceParameter_GGO(mArgsInfo);
SetSmoothingNumberOfIterations_GGO(mArgsInfo);
SetRadius2_GGO(mArgsInfo);
SetSampleRate2_GGO(mArgsInfo);
SetAutoCrop_GGO(mArgsInfo);
+
+ SetAFDBFilename_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]
//--------------------------------------------------------------------
-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;
}
//--------------------------------------------------------------------
void clitk::ExtractBonesGenericFilter<ArgsInfoType>::UpdateWithInputImageType()
{
// Mask & output image type
- typedef itk::Image<uchar, ImageType::ImageDimension> OutputImageType;
+ typedef itk::Image<uchar, ImageType::ImageDimension> MaskImageType;
// Reading input
typename ImageType::Pointer input = this->template GetInput<ImageType>(0);
// Create filter
- typedef clitk::ExtractBonesFilter<ImageType, OutputImageType> FilterType;
+ typedef clitk::ExtractBonesFilter<ImageType> FilterType;
typename FilterType::Pointer filter = FilterType::New();
// Set global Options
filter->Update();
// Write/Save results
- typename OutputImageType::Pointer output = filter->GetOutput();
- this->template SetNextOutput<OutputImageType>(output);
+ typename MaskImageType::Pointer output = filter->GetOutput();
+ this->template SetNextOutput<MaskImageType>(output);
}
//--------------------------------------------------------------------
section "I/O"
option "input" i "Input CT image filename" string yes
-option "patient" p "Input patient mask filename" string yes
-option "patientBG" - "Patient Background" int default="0" no
+option "afdb" a "Output Anatomical Feature DB (Carina position)" string no
option "output" o "Output lungs mask filename" string yes
option "outputTrachea" t "Output trachea mask filename" string no
option "firstKeep3" - "First label to keep" int no default="1"
option "lastKeep3" - "Last label to keep" int no default="2"
-section "Step 5 : openclose"
-option "openclose" - "Final OpenClose" flag off
-option "opencloseRadius" - "Final OpenClose radius" int no default="1"
+section "Step 5 : [optional] openclose"
+option "openclose" - "Perform an OpenClose operation" flag off
+option "opencloseRadius" - "OpenClose radius" int no default="1"
+
+section "Step 6 : fill holes"
+option "doNotFillHoles" - "Do not fill holes if set" flag on
+option "dir" d "Directions (axes) to perform filling (defaults to 2,1,0)" int multiple no
+
#include "clitkDecomposeAndReconstructImageFilter.h"
#include "clitkExplosionControlledThresholdConnectedImageFilter.h"
#include "clitkSegmentationUtils.h"
+#include "clitkFilterWithAnatomicalFeatureDatabaseManagement.h"
// itk
#include "itkStatisticsImageFilter.h"
//--------------------------------------------------------------------
//--------------------------------------------------------------------
- template <class TImageType, class TMaskImageType>
+ template <class TImageType>
class ITK_EXPORT ExtractLungFilter:
public virtual clitk::FilterBase,
- public itk::ImageToImageFilter<TImageType, TMaskImageType>
+ public clitk::FilterWithAnatomicalFeatureDatabaseManagement,
+ public itk::ImageToImageFilter<TImageType, itk::Image<uchar, TImageType::ImageDimension> >
{
public:
/** Standard class typedefs. */
- typedef itk::ImageToImageFilter<TImageType, TMaskImageType> Superclass;
+ typedef itk::Image<uchar, TImageType::ImageDimension> MaskImageType;
+ typedef itk::ImageToImageFilter<TImageType, MaskImageType> Superclass;
typedef ExtractLungFilter Self;
typedef itk::SmartPointer<Self> Pointer;
typedef itk::SmartPointer<const Self> ConstPointer;
typedef typename ImageType::IndexType InputImageIndexType;
typedef typename ImageType::PointType InputImagePointType;
- typedef TMaskImageType MaskImageType;
typedef typename MaskImageType::ConstPointer MaskImageConstPointer;
typedef typename MaskImageType::Pointer MaskImagePointer;
typedef typename MaskImageType::RegionType MaskImageRegionType;
/** Connect inputs */
void SetInput(const ImageType * image);
- void SetInputPatientMask(MaskImageType * mask, MaskImagePixelType BG);
itkSetMacro(PatientMaskBackgroundValue, MaskImagePixelType);
itkGetConstMacro(PatientMaskBackgroundValue, MaskImagePixelType);
GGO_DefineOption(patientBG, SetPatientMaskBackgroundValue, MaskImagePixelType);
+ // Output filename (for AFBD)
+ itkSetMacro(OutputLungFilename, std::string);
+ itkGetMacro(OutputLungFilename, std::string);
+ GGO_DefineOption(output, SetOutputLungFilename, std::string);
+
+ itkSetMacro(OutputTracheaFilename, std::string);
+ itkGetMacro(OutputTracheaFilename, std::string);
+ GGO_DefineOption(outputTrachea, SetOutputTracheaFilename, std::string);
+
// Set all options at a time
template<class ArgsInfoType>
void SetArgsInfo(ArgsInfoType arg);
GGO_DefineOption_LabelParam(3, SetLabelizeParameters3, LabelParamType);
// Step 5 final openclose
- itkSetMacro(FinalOpenClose, bool);
- itkGetConstMacro(FinalOpenClose, bool);
- itkBooleanMacro(FinalOpenClose);
- GGO_DefineOption_Flag(openclose, SetFinalOpenClose);
-
- itkSetMacro(FinalOpenCloseRadius, int);
- itkGetConstMacro(FinalOpenCloseRadius, int);
- GGO_DefineOption(opencloseRadius, SetFinalOpenCloseRadius, int);
+ itkSetMacro(OpenClose, bool);
+ itkGetConstMacro(OpenClose, bool);
+ itkBooleanMacro(OpenClose);
+ GGO_DefineOption_Flag(openclose, SetOpenClose);
+
+ itkSetMacro(OpenCloseRadius, int);
+ itkGetConstMacro(OpenCloseRadius, int);
+ GGO_DefineOption(opencloseRadius, SetOpenCloseRadius, int);
+
+ // Step 6 fill holes
+ itkSetMacro(FillHoles, bool);
+ itkGetConstMacro(FillHoles, bool);
+ itkBooleanMacro(FillHoles);
+ GGO_DefineOption_Flag(doNotFillHoles, SetFillHoles);
protected:
ExtractLungFilter();
InputImageConstPointer input;
MaskImageConstPointer patient;
InputImagePointer working_input;
+ std::string m_OutputLungFilename;
+ std::string m_OutputTracheaFilename;
typename InternalImageType::Pointer working_image;
typename InternalImageType::Pointer trachea_tmp;
MaskImagePointer trachea;
LabelParamType* m_LabelizeParameters3;
// Step 5
- bool m_FinalOpenClose;
- int m_FinalOpenCloseRadius;
+ bool m_OpenClose;
+ int m_OpenCloseRadius;
+
+ // Step 6
+ bool m_FillHoles;
+ InputImageSizeType m_FillHolesDirections;
// Main functions
virtual void GenerateOutputInformation();
#include "clitkSetBackgroundImageFilter.h"
#include "clitkSegmentationUtils.h"
#include "clitkAutoCropFilter.h"
+#include "clitkCropLikeImageFilter.h"
+#include "clitkFillMaskFilter.h"
// itk
#include "itkBinaryThresholdImageFilter.h"
#include "itkBinaryMorphologicalClosingImageFilter.h"
//--------------------------------------------------------------------
-template <class ImageType, class MaskImageType>
-clitk::ExtractLungFilter<ImageType, MaskImageType>::
+template <class ImageType>
+clitk::ExtractLungFilter<ImageType>::
ExtractLungFilter():
clitk::FilterBase(),
+ clitk::FilterWithAnatomicalFeatureDatabaseManagement(),
itk::ImageToImageFilter<ImageType, MaskImageType>()
{
SetNumberOfSteps(10);
m_MaxSeedNumber = 500;
// Default global options
- this->SetNumberOfRequiredInputs(2);
+ this->SetNumberOfRequiredInputs(1);
SetPatientMaskBackgroundValue(0);
SetBackgroundValue(0); // Must be zero
SetForegroundValue(1);
SetLabelizeParameters3(p3);
// Step 5
- FinalOpenCloseOff();
- SetFinalOpenCloseRadius(1);
+ OpenCloseOff();
+ SetOpenCloseRadius(1);
+
+ // Step 6
+ FillHolesOn();
}
//--------------------------------------------------------------------
//--------------------------------------------------------------------
-template <class ImageType, class MaskImageType>
+template <class ImageType>
void
-clitk::ExtractLungFilter<ImageType, MaskImageType>::
+clitk::ExtractLungFilter<ImageType>::
SetInput(const ImageType * image)
{
this->SetNthInput(0, const_cast<ImageType *>(image));
//--------------------------------------------------------------------
-template <class ImageType, class MaskImageType>
-void
-clitk::ExtractLungFilter<ImageType, MaskImageType>::
-SetInputPatientMask(MaskImageType * image, MaskImagePixelType bg )
-{
- this->SetNthInput(1, const_cast<MaskImageType *>(image));
- SetPatientMaskBackgroundValue(bg);
-}
-//--------------------------------------------------------------------
-
-
-//--------------------------------------------------------------------
-template <class ImageType, class MaskImageType>
+template <class ImageType>
void
-clitk::ExtractLungFilter<ImageType, MaskImageType>::
+clitk::ExtractLungFilter<ImageType>::
AddSeed(InternalIndexType s)
{
m_Seeds.push_back(s);
//--------------------------------------------------------------------
-template <class ImageType, class MaskImageType>
+template <class ImageType>
template<class ArgsInfoType>
void
-clitk::ExtractLungFilter<ImageType, MaskImageType>::
+clitk::ExtractLungFilter<ImageType>::
SetArgsInfo(ArgsInfoType mArgsInfo)
{
SetVerboseOption_GGO(mArgsInfo);
SetWriteStep_GGO(mArgsInfo);
SetVerboseWarningOff_GGO(mArgsInfo);
+ SetAFDBFilename_GGO(mArgsInfo);
+ SetOutputLungFilename_GGO(mArgsInfo);
+ SetOutputTracheaFilename_GGO(mArgsInfo);
+
SetUpperThreshold_GGO(mArgsInfo);
SetLowerThreshold_GGO(mArgsInfo);
SetNumberOfSlicesToSkipBeforeSearchingSeed_GGO(mArgsInfo);
SetRadiusForTrachea_GGO(mArgsInfo);
SetLabelizeParameters3_GGO(mArgsInfo);
- SetFinalOpenCloseRadius_GGO(mArgsInfo);
- SetFinalOpenClose_GGO(mArgsInfo);
+ SetOpenCloseRadius_GGO(mArgsInfo);
+ SetOpenClose_GGO(mArgsInfo);
+
+ SetFillHoles_GGO(mArgsInfo);
}
//--------------------------------------------------------------------
//--------------------------------------------------------------------
-template <class ImageType, class MaskImageType>
+template <class ImageType>
void
-clitk::ExtractLungFilter<ImageType, MaskImageType>::
+clitk::ExtractLungFilter<ImageType>::
GenerateOutputInformation()
{
Superclass::GenerateOutputInformation();
+
+ // Read DB
+ LoadAFDB();
// Get input pointers
- patient = dynamic_cast<const MaskImageType*>(itk::ProcessObject::GetInput(1));
input = dynamic_cast<const ImageType*>(itk::ProcessObject::GetInput(0));
+ patient = GetAFDB()->template GetImage <MaskImageType>("patient");
- // Check image
- if (!HaveSameSizeAndSpacing<ImageType, MaskImageType>(input, patient)) {
- clitkExceptionMacro("the 'input' and 'patient' masks must have the same size & spacing.");
- }
-
+ //--------------------------------------------------------------------
+ //--------------------------------------------------------------------
+ // Crop input like patient image (must have the same spacing)
+ StartNewStep("Crop input image to 'patient' extends");
+ typedef clitk::CropLikeImageFilter<ImageType> CropImageFilter;
+ typename CropImageFilter::Pointer cropFilter = CropImageFilter::New();
+ cropFilter->SetInput(input);
+ cropFilter->SetCropLikeImage(patient);
+ cropFilter->Update();
+ working_input = cropFilter->GetOutput();
+ StopCurrentStep<ImageType>(working_input);
+
//--------------------------------------------------------------------
//--------------------------------------------------------------------
StartNewStep("Set background to initial image");
working_input = SetBackground<ImageType, MaskImageType>
- (input, patient, GetPatientMaskBackgroundValue(), -1000);
+ (working_input, patient, GetPatientMaskBackgroundValue(), -1000);
StopCurrentStep<ImageType>(working_input);
//--------------------------------------------------------------------
//--------------------------------------------------------------------
//--------------------------------------------------------------------
- typedef clitk::AutoCropFilter<InternalImageType> CropFilterType;
- typename CropFilterType::Pointer cropFilter = CropFilterType::New();
+ typedef clitk::AutoCropFilter<InternalImageType> AutoCropFilterType;
+ typename AutoCropFilterType::Pointer autocropFilter = AutoCropFilterType::New();
if (m_Seeds.size() != 0) { // if ==0 ->no trachea found
- StartNewStep("Croping trachea");
- cropFilter->SetInput(trachea_tmp);
- cropFilter->Update(); // Needed
+ StartNewStep("Cropping trachea");
+ autocropFilter->SetInput(trachea_tmp);
+ autocropFilter->Update(); // Needed
typedef itk::CastImageFilter<InternalImageType, MaskImageType> CastImageFilterType;
typename CastImageFilterType::Pointer caster= CastImageFilterType::New();
- caster->SetInput(cropFilter->GetOutput());
+ caster->SetInput(autocropFilter->GetOutput());
caster->Update();
trachea = caster->GetOutput();
StopCurrentStep<MaskImageType>(trachea);
//--------------------------------------------------------------------
//--------------------------------------------------------------------
- StartNewStep("Croping lung");
- typename CropFilterType::Pointer cropFilter2 = CropFilterType::New(); // Needed to reset pipeline
- cropFilter2->SetInput(working_image);
- cropFilter2->Update();
- working_image = cropFilter2->GetOutput();
+ StartNewStep("Cropping lung");
+ typename AutoCropFilterType::Pointer autocropFilter2 = AutoCropFilterType::New(); // Needed to reset pipeline
+ autocropFilter2->SetInput(working_image);
+ autocropFilter2->Update();
+ working_image = autocropFilter2->GetOutput();
StopCurrentStep<InternalImageType>(working_image);
//--------------------------------------------------------------------
//--------------------------------------------------------------------
// Final OpenClose
- if (GetFinalOpenClose()) {
+ if (GetOpenClose()) {
StartNewStep("Open/Close");
// Structuring element
typedef itk::BinaryBallStructuringElement<InternalPixelType, ImageDimension> KernelType;
KernelType structuringElement;
- structuringElement.SetRadius(GetFinalOpenCloseRadius());
+ structuringElement.SetRadius(GetOpenCloseRadius());
structuringElement.CreateStructuringElement();
// Open
working_image = closeFilter->GetOutput();
}
+ //--------------------------------------------------------------------
+ //--------------------------------------------------------------------
+ // Fill Lungs
+ if (GetFillHoles()) {
+ StartNewStep("Fill Holes");
+ /*
+ typename FillMaskFilterType::Pointer fillMaskFilter = FillMaskFilterType::New();
+ fillMaskFilter(working_image);
+ fillMaskFilter->Update();
+ working_image = fillMaskFilter->GetOutput();
+ StopCurrentStep<InternalImageType>(working_image);
+ */
+ }
+
//--------------------------------------------------------------------
//--------------------------------------------------------------------
StartNewStep("Separate Left/Right lungs");
// Update output info
this->GetOutput(0)->SetRegions(output->GetLargestPossibleRegion());
-
-
}
//--------------------------------------------------------------------
//--------------------------------------------------------------------
-template <class ImageType, class MaskImageType>
+template <class ImageType>
void
-clitk::ExtractLungFilter<ImageType, MaskImageType>::
+clitk::ExtractLungFilter<ImageType>::
GenerateData()
{
// Set the output
this->GraftOutput(output); // not SetNthOutput
+ // Store image filenames into AFDB
+ GetAFDB()->SetImageFilename("lungs", this->GetOutputLungFilename());
+ GetAFDB()->SetImageFilename("trachea", this->GetOutputTracheaFilename());
+ WriteAFDB();
}
//--------------------------------------------------------------------
//--------------------------------------------------------------------
-template <class ImageType, class MaskImageType>
+template <class ImageType>
bool
-clitk::ExtractLungFilter<ImageType, MaskImageType>::
+clitk::ExtractLungFilter<ImageType>::
SearchForTracheaSeed(int skip)
{
if (m_Seeds.size() == 0) { // try to find seed (if not zero, it is given by user)
//--------------------------------------------------------------------
-template <class ImageType, class MaskImageType>
+template <class ImageType>
void
-clitk::ExtractLungFilter<ImageType, MaskImageType>::
+clitk::ExtractLungFilter<ImageType>::
TracheaRegionGrowing()
{
// Explosion controlled region growing
//--------------------------------------------------------------------
-template <class ImageType, class MaskImageType>
+template <class ImageType>
double
-clitk::ExtractLungFilter<ImageType, MaskImageType>::
+clitk::ExtractLungFilter<ImageType>::
ComputeTracheaVolume()
{
typedef itk::ImageRegionConstIterator<InternalImageType> IteratorType;
//--------------------------------------------------------------------
-template <class ImageType, class MaskImageType>
+template <class ImageType>
void
-clitk::ExtractLungFilter<ImageType, MaskImageType>::
+clitk::ExtractLungFilter<ImageType>::
SearchForTrachea()
{
// Search for seed among n slices, skip some slices before starting
#ifndef CLITKEXTRACTLUNGSGENERICFILTER_H
#define CLITKEXTRACTLUNGSGENERICFILTER_H
+// clitk
#include "clitkIO.h"
#include "clitkImageToImageGenericFilter.h"
#include "clitkExtractLungFilter.h"
//--------------------------------------------------------------------
namespace clitk
{
-
template<class ArgsInfoType>
class ITK_EXPORT ExtractLungGenericFilter:
public ImageToImageGenericFilter<ExtractLungGenericFilter<ArgsInfoType> >
SetIOVerbose(mArgsInfo.verbose_flag);
if (mArgsInfo.imagetypes_flag) this->PrintAvailableImageTypes();
if (mArgsInfo.input_given) AddInputFilename(mArgsInfo.input_arg);
- if (mArgsInfo.patient_given) AddInputFilename(mArgsInfo.patient_arg);
if (mArgsInfo.output_given) AddOutputFilename(mArgsInfo.output_arg);
if (mArgsInfo.outputTrachea_given) AddOutputFilename(mArgsInfo.outputTrachea_arg);
}
void clitk::ExtractLungGenericFilter<ArgsInfoType>::UpdateWithInputImageType()
{
// Mask & output image type
- typedef itk::Image<uchar, ImageType::ImageDimension> OutputImageType;
typedef itk::Image<uchar, ImageType::ImageDimension> MaskImageType;
// Reading input
typename ImageType::Pointer input = this->template GetInput<ImageType>(0);
- typename MaskImageType::Pointer patient = this->template GetInput<MaskImageType>(1);
// Create filter
- typedef clitk::ExtractLungFilter<ImageType, MaskImageType> FilterType;
+ typedef clitk::ExtractLungFilter<ImageType> FilterType;
typename FilterType::Pointer filter = FilterType::New();
// Set the filter (needed for example for threaded monitoring)
// Set global Options
filter->SetArgsInfo(mArgsInfo);
filter->SetInput(input);
- filter->SetInputPatientMask(patient, mArgsInfo.patientBG_arg);
// Go !
filter->Update();
// Write/Save results
- typename OutputImageType::Pointer output = filter->GetOutput();
- this->template SetNextOutput<OutputImageType>(output);
+ typename MaskImageType::Pointer output = filter->GetOutput();
+ this->template SetNextOutput<MaskImageType>(output);
this->template SetNextOutput<typename FilterType::MaskImageType>(filter->GetTracheaImage());
}
//--------------------------------------------------------------------
#include "clitkAddRelativePositionConstraintToLabelImageFilter.h"
#include "clitkSegmentationUtils.h"
#include "clitkExtractAirwaysTreeInfoFilter.h"
+#include "clitkCropLikeImageFilter.h"
// std
#include <deque>
SetFuzzyThreshold1_GGO(mArgsInfo);
SetFuzzyThreshold2_GGO(mArgsInfo);
SetFuzzyThreshold3_GGO(mArgsInfo);
+
+ SetAFDBFilename_GGO(mArgsInfo);
}
//--------------------------------------------------------------------
{
// Call default
Superclass::GenerateInputRequestedRegion();
- // Get input pointers
- ImagePointer patient = dynamic_cast<ImageType*>(itk::ProcessObject::GetInput(0));
- ImagePointer lung = dynamic_cast<ImageType*>(itk::ProcessObject::GetInput(1));
- ImagePointer bones = dynamic_cast<ImageType*>(itk::ProcessObject::GetInput(2));
- ImagePointer trachea = dynamic_cast<ImageType*>(itk::ProcessObject::GetInput(3));
+
+ // Get input pointers
+ LoadAFDB();
+ ImagePointer patient = GetAFDB()->template GetImage <ImageType>("patient");
+ ImagePointer lung = GetAFDB()->template GetImage <ImageType>("lungs");
+ ImagePointer bones = GetAFDB()->template GetImage <ImageType>("bones");
+ ImagePointer trachea = GetAFDB()->template GetImage <ImageType>("trachea");
patient->SetRequestedRegion(patient->GetLargestPossibleRegion());
lung->SetRequestedRegion(lung->GetLargestPossibleRegion());
GenerateData()
{
// Get input pointers
- ImageConstPointer patient = dynamic_cast<const ImageType*>(itk::ProcessObject::GetInput(0));
- ImageConstPointer lung = dynamic_cast<const ImageType*>(itk::ProcessObject::GetInput(1));
- ImageConstPointer bones = dynamic_cast<const ImageType*>(itk::ProcessObject::GetInput(2));
- ImageConstPointer trachea = dynamic_cast<const ImageType*>(itk::ProcessObject::GetInput(3));
+ ImagePointer patient = GetAFDB()->template GetImage <ImageType>("patient");
+ ImagePointer lung = GetAFDB()->template GetImage <ImageType>("lungs");
+ ImagePointer bones = GetAFDB()->template GetImage <ImageType>("bones");
+ ImagePointer trachea = GetAFDB()->template GetImage <ImageType>("trachea");
// Get output pointer
ImagePointer output;
+ // Step 0: Crop support (patient) to lung extend in RL
+ StartNewStep("Crop support like lungs along LR");
+ typedef clitk::CropLikeImageFilter<ImageType> CropFilterType;
+ typename CropFilterType::Pointer cropFilter = CropFilterType::New();
+ cropFilter->SetInput(patient);
+ cropFilter->SetCropLikeImage(lung, 0);// Indicate that we only crop in X (Left-Right) axe
+ cropFilter->Update();
+ output = cropFilter->GetOutput();
+ this->template StopCurrentStep<ImageType>(output);
+
+ // Step 0: Crop support (previous) to bones extend in AP
+ StartNewStep("Crop support like bones along AP");
+ cropFilter = CropFilterType::New();
+ cropFilter->SetInput(output);
+ cropFilter->SetCropLikeImage(bones, 1);// Indicate that we only crop in Y (Ant-Post) axe
+ cropFilter->Update();
+ output = cropFilter->GetOutput();
+ this->template StopCurrentStep<ImageType>(output);
+
// Step 1: patient minus lungs, minus bones
StartNewStep("Patient contours minus lungs and minus bones");
typedef clitk::BooleanOperatorLabelImageFilter<ImageType> BoolFilterType;
typename BoolFilterType::Pointer boolFilter = BoolFilterType::New();
boolFilter->InPlaceOn();
- boolFilter->SetInput1(patient);
+ boolFilter->SetInput1(output);
boolFilter->SetInput2(lung);
boolFilter->SetOperationType(BoolFilterType::AndNot);
boolFilter->Update();
// Step 2: LR limits from lung (need separate lung ?)
StartNewStep("Left/Right limits with lungs");
- /* // WE DO NOT NEED THE FOLLOWING
- // Get separate lung images to get only the right and left lung
- // (label must be '1' because right is greater than left).
- ImagePointer right_lung = clitk::SetBackground<ImageType, ImageType>(lung, lung, 2, 0);
- ImagePointer left_lung = clitk::SetBackground<ImageType, ImageType>(lung, lung, 1, 0);
- writeImage<ImageType>(right_lung, "right.mhd");
- writeImage<ImageType>(left_lung, "left.mhd");
+ /*
+ // WE DO NOT NEED THE FOLLOWING ?
+ // Get separate lung images to get only the right and left lung (because RelativePositionPropImageFilter only consider fg=1);
+ // (label must be '1' because right is greater than left).
+ ImagePointer right_lung = clitk::SetBackground<ImageType, ImageType>(lung, lung, 2, 0);
+ ImagePointer left_lung = clitk::SetBackground<ImageType, ImageType>(lung, lung, 1, 0);
+ writeImage<ImageType>(right_lung, "right.mhd");
+ writeImage<ImageType>(left_lung, "left.mhd");
*/
typedef clitk::AddRelativePositionConstraintToLabelImageFilter<ImageType> RelPosFilterType;
relPosFilter->VerboseStepOff();
relPosFilter->WriteStepOff();
relPosFilter->SetInput(output);
- DD(output->GetLargestPossibleRegion().GetIndex());
- // relPosFilter->SetInputObject(left_lung);
+ //relPosFilter->SetInputObject(left_lung);
relPosFilter->SetInputObject(lung);
relPosFilter->SetOrientationType(RelPosFilterType::LeftTo); // warning left lung is at right ;)
relPosFilter->SetIntermediateSpacing(GetIntermediateSpacing());
relPosFilter->SetFuzzyThreshold(GetFuzzyThreshold1());
relPosFilter->Update();
output = relPosFilter->GetOutput();
- DD(output->GetLargestPossibleRegion());
+ // writeImage<ImageType>(right_lung, "step4-left.mhd");
relPosFilter->SetInput(output);
relPosFilter->SetCurrentStepBaseId(this->GetCurrentStepId());
relPosFilter->VerboseStepOff();
relPosFilter->WriteStepOff();
- // relPosFilter->SetInputObject(right_lung);
+ //relPosFilter->SetInputObject(right_lung);
relPosFilter->SetInputObject(lung);
relPosFilter->SetOrientationType(RelPosFilterType::RightTo);
relPosFilter->SetIntermediateSpacing(GetIntermediateSpacing());
relPosFilter->SetFuzzyThreshold(GetFuzzyThreshold1());
relPosFilter->Update();
output = relPosFilter->GetOutput();
- DD(output->GetLargestPossibleRegion());
this->template StopCurrentStep<ImageType>(output);
// Step 3: AP limits from bones
DD(index_trachea);
// Split bone image first into two parts (ant and post)
- typedef itk::RegionOfInterestImageFilter<ImageType, ImageType> CropFilterType;
- // typedef itk::ExtractImageFilter<ImageType, ImageType> CropFilterType;
- typename CropFilterType::Pointer cropFilter = CropFilterType::New();
+ typedef itk::RegionOfInterestImageFilter<ImageType, ImageType> ROIFilterType;
+ // typedef itk::ExtractImageFilter<ImageType, ImageType> ROIFilterType;
+ typename ROIFilterType::Pointer roiFilter = ROIFilterType::New();
ImageRegionType region = bones->GetLargestPossibleRegion();
ImageSizeType size = region.GetSize();
DD(size);
size[1] = index_trachea[1]; //size[1]/2.0;
DD(size);
region.SetSize(size);
- cropFilter->SetInput(bones);
- // cropFilter->SetExtractionRegion(region);
- cropFilter->SetRegionOfInterest(region);
- cropFilter->ReleaseDataFlagOff();
- cropFilter->Update();
- bones_ant = cropFilter->GetOutput();
+ roiFilter->SetInput(bones);
+ // roiFilter->SetExtractionRegion(region);
+ roiFilter->SetRegionOfInterest(region);
+ roiFilter->ReleaseDataFlagOff();
+ roiFilter->Update();
+ bones_ant = roiFilter->GetOutput();
writeImage<ImageType>(bones_ant, "b_ant.mhd");
- // cropFilter->ResetPipeline();// = CropFilterType::New();
- cropFilter = CropFilterType::New();
+ // roiFilter->ResetPipeline();// = ROIFilterType::New();
+ roiFilter = ROIFilterType::New();
ImageIndexType index = region.GetIndex();
index[1] = bones->GetLargestPossibleRegion().GetIndex()[1] + size[1]-1;
size[1] = bones->GetLargestPossibleRegion().GetSize()[1] - size[1];
DD(size);
region.SetIndex(index);
region.SetSize(size);
- cropFilter->SetInput(bones);
- // cropFilter->SetExtractionRegion(region);
- cropFilter->SetRegionOfInterest(region);
- cropFilter->ReleaseDataFlagOff();
- cropFilter->Update();
- bones_post = cropFilter->GetOutput();
+ roiFilter->SetInput(bones);
+ // roiFilter->SetExtractionRegion(region);
+ roiFilter->SetRegionOfInterest(region);
+ roiFilter->ReleaseDataFlagOff();
+ roiFilter->Update();
+ bones_post = roiFilter->GetOutput();
writeImage<ImageType>(bones_post, "b_post.mhd");
// Go !
relPosFilter->Update();
output = relPosFilter->GetOutput();
this->template StopCurrentStep<ImageType>(output);
+
// Get CCL
- output = clitk::Labelize<ImageType>(output, GetBackgroundValue(), true, 100);
+ StartNewStep("Keep main connected component");
+ output = clitk::Labelize<ImageType>(output, GetBackgroundValue(), true, 500);
// output = RemoveLabels<ImageType>(output, BG, param->GetLabelsToRemove());
output = clitk::KeepLabels<ImageType>(output, GetBackgroundValue(),
GetForegroundValue(), 1, 1, 0);
-
+ this->template StopCurrentStep<ImageType>(output);
// Step : Lower limits from lung (need separate lung ?)
StartNewStep("Lower limits with lungs");
DD(output->GetLargestPossibleRegion());
output = clitk::AutoCrop<ImageType>(output, GetBackgroundValue());
- // cropFilter = CropFilterType::New();
- //cropFilter->SetInput(output);
- //cropFilter->Update();
- //output = cropFilter->GetOutput();
+ // roiFilter = ROIFilterType::New();
+ //roiFilter->SetInput(output);
+ //roiFilter->Update();
+ //output = roiFilter->GetOutput();
// Final Step -> set output
this->SetNthOutput(0, output);
#File clitkExtractPatient.ggo
package "clitkExtractPatient"
version "1.0"
-purpose "Prefer high resolution input and resample (NN) output at the end (like). Input is binarized using initial thresholds, connected components are labeled (firstLabel). The air label (1) is removed. The remaining is binarized and relabeled, patient should now be the principal label (secondLabel). Two mechanismes are provided to influence the label images. Crop to reduce connectivity (image is restored to original size), eg for SBF. Decomposition through ersion and reconstruction through dilation (slow), eg for Pulmo bellows. Choose which labels to keep from second Label image. Final mask is cleaned by opening and closing."
+purpose "Input is binarized using initial thresholds, connected components are labeled (firstLabel). The air label (1) is removed. The remaining is binarized and relabeled, patient should now be the principal label (secondLabel). Two mechanismes are provided to influence the label images. Crop to reduce connectivity (image is restored to original size), eg for SBF. Decomposition through ersion and reconstruction through dilation (slow), eg for Pulmo bellows. Choose which labels to keep from second Label image. Final mask is cleaned by opening and closing."
option "config" - "Config file" string no
option "imagetypes" - "Display allowed image types" flag off
section "I/O"
-option "input" i "Input image filename" string yes
-option "output" o "Output image filename" string yes
+option "input" i "Input image filename" string yes
+option "afdb" a "Output Anatomical Feature in a DB" string no
+option "output" o "Output image filename" string yes
section "Binarize"
section "Clean-up"
-option "openClose" - "Perform morphological opening and closing with unit radius" flag on
-option "autoCrop" - "Crop final mask to BoundingBox" flag off
+option "openClose" - "Perform morphological opening and closing with unit radius" flag off
+option "noAutoCrop" - "If set : do no crop final mask to BoundingBox" flag on
#define CLITKEXTRACTPATIENTFILTER_H
#include "clitkFilterBase.h"
+#include "clitkFilterWithAnatomicalFeatureDatabaseManagement.h"
namespace clitk {
*/
//--------------------------------------------------------------------
- template <class TInputImageType, class TOutputImageType>
+ template <class TInputImageType>
class ITK_EXPORT ExtractPatientFilter:
- public clitk::FilterBase,
- public itk::ImageToImageFilter<TInputImageType, TOutputImageType>
+ public virtual clitk::FilterBase,
+ public clitk::FilterWithAnatomicalFeatureDatabaseManagement,
+ public itk::ImageToImageFilter<TInputImageType,
+ itk::Image<uchar, TInputImageType::ImageDimension> >
{
public:
/** Standard class typedefs. */
- typedef ExtractPatientFilter Self;
- typedef itk::ImageToImageFilter<TInputImageType, TOutputImageType> Superclass;
- typedef itk::SmartPointer<Self> Pointer;
- typedef itk::SmartPointer<const Self> ConstPointer;
+ typedef itk::Image<uchar, TInputImageType::ImageDimension> MaskImageType;
+ typedef ExtractPatientFilter Self;
+ typedef itk::ImageToImageFilter<TInputImageType, MaskImageType> Superclass;
+ typedef itk::SmartPointer<Self> Pointer;
+ typedef itk::SmartPointer<const Self> ConstPointer;
/** Method for creation through the object factory. */
itkNewMacro(Self);
typedef typename InputImageType::SizeType InputImageSizeType;
typedef typename InputImageType::IndexType InputImageIndexType;
- typedef TOutputImageType OutputImageType;
- typedef typename OutputImageType::ConstPointer OutputImageConstPointer;
- typedef typename OutputImageType::Pointer OutputImagePointer;
- typedef typename OutputImageType::RegionType OutputImageRegionType;
- typedef typename OutputImageType::PixelType OutputImagePixelType;
- typedef typename OutputImageType::SizeType OutputImageSizeType;
- typedef typename OutputImageType::IndexType OutputImageIndexType;
+ typedef typename MaskImageType::ConstPointer MaskImageConstPointer;
+ typedef typename MaskImageType::Pointer MaskImagePointer;
+ typedef typename MaskImageType::RegionType MaskImageRegionType;
+ typedef typename MaskImageType::PixelType MaskImagePixelType;
+ typedef typename MaskImageType::SizeType MaskImageSizeType;
+ typedef typename MaskImageType::IndexType MaskImageIndexType;
itkStaticConstMacro(ImageDimension, unsigned int, InputImageType::ImageDimension);
typedef int InternalPixelType;
/** Connect inputs */
void SetInput(const TInputImageType * image);
+ itkSetMacro(OutputPatientFilename, std::string);
+ itkGetMacro(OutputPatientFilename, std::string);
+ GGO_DefineOption(output, SetOutputPatientFilename, std::string);
// Set all options at a time
template<class ArgsInfoType>
itkSetMacro(AutoCrop, bool);
itkGetConstMacro(AutoCrop, bool);
itkBooleanMacro(AutoCrop);
- GGO_DefineOption_Flag(autoCrop, SetAutoCrop);
+ GGO_DefineOption_Flag(noAutoCrop, SetAutoCrop);
protected:
ExtractPatientFilter();
virtual ~ExtractPatientFilter() {}
- itkSetMacro(BackgroundValue, OutputImagePixelType);
- itkSetMacro(ForegroundValue, OutputImagePixelType);
- itkGetConstMacro(BackgroundValue, OutputImagePixelType);
- itkGetConstMacro(ForegroundValue, OutputImagePixelType);
- OutputImagePixelType m_BackgroundValue;
- OutputImagePixelType m_ForegroundValue;
-
+ itkSetMacro(BackgroundValue, MaskImagePixelType);
+ itkSetMacro(ForegroundValue, MaskImagePixelType);
+ itkGetConstMacro(BackgroundValue, MaskImagePixelType);
+ itkGetConstMacro(ForegroundValue, MaskImagePixelType);
+ MaskImagePixelType m_BackgroundValue;
+ MaskImagePixelType m_ForegroundValue;
+
+ std::string m_OutputPatientFilename;
InputImagePixelType m_UpperThreshold;
InputImagePixelType m_LowerThreshold;
bool m_UseLowerThreshold;
virtual void GenerateData();
InputImageConstPointer input;
- OutputImagePointer output;
+ MaskImagePointer output;
typename InternalImageType::Pointer working_image;
private:
#include "itkCastImageFilter.h"
//--------------------------------------------------------------------
-template <class TInputImageType, class TOutputImageType>
-clitk::ExtractPatientFilter<TInputImageType, TOutputImageType>::
+template <class TInputImageType>
+clitk::ExtractPatientFilter<TInputImageType>::
ExtractPatientFilter():
clitk::FilterBase(),
- itk::ImageToImageFilter<TInputImageType, TOutputImageType>()
+ clitk::FilterWithAnatomicalFeatureDatabaseManagement(),
+ itk::ImageToImageFilter<TInputImageType, MaskImageType>()
{
this->SetNumberOfRequiredInputs(1);
SetBackgroundValue(0); // Must be zero
SetLastKeep(1);
// Step 4: OpenClose (option)
- FinalOpenCloseOn();
- AutoCropOff();
+ FinalOpenCloseOff();
+ AutoCropOn();
}
//--------------------------------------------------------------------
//--------------------------------------------------------------------
-template <class TInputImageType, class TOutputImageType>
+template <class TInputImageType>
void
-clitk::ExtractPatientFilter<TInputImageType, TOutputImageType>::
+clitk::ExtractPatientFilter<TInputImageType>::
SetInput(const TInputImageType * image)
{
this->SetNthInput(0, const_cast<TInputImageType *>(image));
//--------------------------------------------------------------------
-template <class TInputImageType, class TOutputImageType>
+template <class TInputImageType>
template<class ArgsInfoType>
void
-clitk::ExtractPatientFilter<TInputImageType, TOutputImageType>::
+clitk::ExtractPatientFilter<TInputImageType>::
SetArgsInfo(ArgsInfoType arg)
{
SetVerboseOption_GGO(arg);
SetWriteStep_GGO(arg);
SetVerboseWarningOff_GGO(arg);
+ SetOutputPatientFilename_GGO(arg);
+
SetUpperThreshold_GGO(arg);
SetLowerThreshold_GGO(arg);
SetFinalOpenClose_GGO(arg);
SetAutoCrop_GGO(arg);
+
+ SetAFDBFilename_GGO(arg);
}
//--------------------------------------------------------------------
//--------------------------------------------------------------------
-template <class TInputImageType, class TOutputImageType>
+template <class TInputImageType>
void
-clitk::ExtractPatientFilter<TInputImageType, TOutputImageType>::
+clitk::ExtractPatientFilter<TInputImageType>::
GenerateOutputInformation() {
Superclass::GenerateOutputInformation();
input = dynamic_cast<const TInputImageType*>(itk::ProcessObject::GetInput(0));
- // OutputImagePointer outputImage = this->GetOutput(0);
+ // MaskImagePointer outputImage = this->GetOutput(0);
// outputImage->SetRegions(input->GetLargestPossibleRegion());
// Get input pointers
relabelFilter2->SetInput(connectFilter2->GetOutput());
relabelFilter2->Update();
working_image = relabelFilter2->GetOutput();
+
+ // Keep main label
+ working_image = KeepLabels<InternalImageType>
+ (working_image, GetBackgroundValue(), GetForegroundValue(), 1, 1, true);
StopCurrentStep<InternalImageType>(working_image);
//--------------------------------------------------------------------
//--------------------------------------------------------------------
//--------------------------------------------------------------------
// Final Cast
- typedef itk::CastImageFilter<InternalImageType, OutputImageType> CastImageFilterType;
+ typedef itk::CastImageFilter<InternalImageType, MaskImageType> CastImageFilterType;
typename CastImageFilterType::Pointer caster= CastImageFilterType::New();
caster->SetInput(working_image);
caster->Update();
// [Optional]
if (GetAutoCrop()) {
StartNewStep("AutoCrop");
- typedef clitk::AutoCropFilter<OutputImageType> CropFilterType;
+ typedef clitk::AutoCropFilter<MaskImageType> CropFilterType;
typename CropFilterType::Pointer cropFilter = CropFilterType::New();
cropFilter->SetInput(output);
cropFilter->SetBackgroundValue(GetBackgroundValue());
cropFilter->Update();
output = cropFilter->GetOutput();
- StopCurrentStep<OutputImageType>(output);
+ StopCurrentStep<MaskImageType>(output);
}
}
//--------------------------------------------------------------------
//--------------------------------------------------------------------
-template <class TInputImageType, class TOutputImageType>
+template <class TInputImageType>
void
-clitk::ExtractPatientFilter<TInputImageType, TOutputImageType>::
+clitk::ExtractPatientFilter<TInputImageType>::
GenerateData() {
- //this->SetNthOutput(0, output); // -> no because redo filter otherwise
+ // Final Graft
this->GraftOutput(output);
+ // Store image filename into AFDB
+ GetAFDB()->SetImageFilename("patient", this->GetOutputPatientFilename());
+ WriteAFDB();
}
//--------------------------------------------------------------------
typename ImageType::Pointer input = this->template GetInput<ImageType>(0);
// Create filter
- typedef clitk::ExtractPatientFilter<ImageType, OutputImageType> FilterType;
+ typedef clitk::ExtractPatientFilter<ImageType> FilterType;
typename FilterType::Pointer filter = FilterType::New();
// Set the filter (needed for example for threaded monitoring)
// Go !
filter->Update();
-
- // // Check if error
- // if (filter->HasError()) {
- // SetLastError(filter->GetLastError());
- // // No output
- // return;
- // }
// Write/Save results
typename OutputImageType::Pointer output = filter->GetOutput();