-#ifndef clitkFillMaskGenericFilter_h
-#define clitkFillMaskGenericFilter_h
+/*=========================================================================
+ Program: vv http://www.creatis.insa-lyon.fr/rio/vv
-/* =================================================
- * @file clitkFillMaskGenericFilter.h
- * @author
- * @date
- *
- * @brief
- *
- ===================================================*/
+ Authors belong to:
+ - University of LYON http://www.universite-lyon.fr/
+ - Léon Bérard cancer center http://oncora1.lyon.fnclcc.fr
+ - CREATIS CNRS laboratory http://www.creatis.insa-lyon.fr
+ This software is distributed WITHOUT ANY WARRANTY; without even
+ the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ PURPOSE. See the copyright notices for more information.
-// clitk include
-#include "clitkFillMask_ggo.h"
-#include "clitkImageCommon.h"
-#include "clitkExtractImageFilter.h"
+ It is distributed under dual licence
-//itk include
-#include "itkLightObject.h"
-#include "itkJoinSeriesImageFilter.h"
-#include "itkBinaryThresholdImageFilter.h"
-#include "itkConnectedComponentImageFilter.h"
-#include "itkRelabelComponentImageFilter.h"
-#include "itkThresholdImageFilter.h"
-#include "itkPermuteAxesImageFilter.h"
-#include "itkExtractImageFilter.h"
-#include "itkCastImageFilter.h"
+ - BSD See included LICENSE.txt file
+ - CeCILL-B http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html
+======================================================================-====*/
+#ifndef CLITKFILLMASKGENERICFILTER_H
+#define CLITKFILLMASKGENERICFILTER_H
+
+// clitk
+#include "clitkImageToImageGenericFilter.h"
+#include "clitkFillMaskFilter.h"
+
+//--------------------------------------------------------------------
namespace clitk
{
-
- class ITK_EXPORT FillMaskGenericFilter : public itk::LightObject
+ template<class ArgsInfoType>
+ class ITK_EXPORT FillMaskGenericFilter :
+ public ImageToImageGenericFilter<FillMaskGenericFilter<ArgsInfoType> >
{
public:
- //----------------------------------------
- // ITK
- //----------------------------------------
- typedef FillMaskGenericFilter Self;
- typedef itk::LightObject Superclass;
- typedef itk::SmartPointer<Self> Pointer;
- typedef itk::SmartPointer<const Self> ConstPointer;
-
- // Method for creation through the object factory
- itkNewMacro(Self);
-
- // Run-time type information (and related methods)
- itkTypeMacro( FillMaskGenericFilter, LightObject );
-
-
- //----------------------------------------
- // Typedefs
- //----------------------------------------
-
-
- //----------------------------------------
- // Set & Get
- //----------------------------------------
- void SetArgsInfo(const args_info_clitkFillMask & a)
- {
- m_ArgsInfo=a;
- m_Verbose=m_ArgsInfo.verbose_flag;
- m_InputFileName=m_ArgsInfo.input_arg;
- }
-
-
- //----------------------------------------
- // Update
- //----------------------------------------
- void Update();
-
- protected:
-
- //----------------------------------------
- // Constructor & Destructor
- //----------------------------------------
+ //--------------------------------------------------------------------
FillMaskGenericFilter();
- ~FillMaskGenericFilter() {};
-
-
- //----------------------------------------
- // Templated members
- //----------------------------------------
- template <class PixelType> void UpdateWithPixelType();
+ //--------------------------------------------------------------------
+ typedef FillMaskGenericFilter Self;
+ typedef ImageToImageGenericFilter<Self > Superclass;
+ typedef itk::SmartPointer<Self> Pointer;
+ typedef itk::SmartPointer<const Self> ConstPointer;
+
+ //--------------------------------------------------------------------
+ itkNewMacro(Self);
+ itkTypeMacro(FillMaskGenericFilter, LightObject);
- //----------------------------------------
- // Data members
- //----------------------------------------
- args_info_clitkFillMask m_ArgsInfo;
- bool m_Verbose;
- std::string m_InputFileName;
+ //--------------------------------------------------------------------
+ void SetArgsInfo(const ArgsInfoType & a);
- };
+ //--------------------------------------------------------------------
+ // Main function called each time the filter is updated
+ template<class ImageType>
+ void UpdateWithInputImageType();
+ protected:
+ template<unsigned int Dim> void InitializeImageType();
+ ArgsInfoType mArgsInfo;
+ }; // end class
+ //--------------------------------------------------------------------
} // end namespace clitk
#include "clitkFillMaskGenericFilter.txx"
#endif
-#endif // #define clitkFillMaskGenericFilter_h
+#endif // #define CLITKFILLMASKGENERICFILTER_H
-#ifndef clitkFillMaskGenericFilter_txx
-#define clitkFillMaskGenericFilter_txx
+/*=========================================================================
+ Program: vv http://www.creatis.insa-lyon.fr/rio/vv
-/* =================================================
- * @file clitkFillMaskGenericFilter.txx
- * @author
- * @date
- *
- * @brief
- *
- ===================================================*/
+ Authors belong to:
+ - University of LYON http://www.universite-lyon.fr/
+ - Léon Bérard cancer center http://oncora1.lyon.fnclcc.fr
+ - CREATIS CNRS laboratory http://www.creatis.insa-lyon.fr
+ This software is distributed WITHOUT ANY WARRANTY; without even
+ the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ PURPOSE. See the copyright notices for more information.
-namespace clitk
-{
+ It is distributed under dual licence
- //-------------------------------------------------------------------
- // Update with the pixeltype
- //-------------------------------------------------------------------
- template <class PixelType>
- void
- FillMaskGenericFilter::UpdateWithPixelType()
- {
- // Dim & Pix
- const unsigned int Dimension=3;
- typedef int InternalPixelType;
+ - BSD See included LICENSE.txt file
+ - CeCILL-B http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html
+ ======================================================================-====*/
- // ImageTypes
- typedef itk::Image<PixelType, Dimension> InputImageType;
- typedef itk::Image<InternalPixelType, Dimension> InternalImageType;
- typedef itk::Image<PixelType, Dimension> OutputImageType;
-
- // Read the input
- typedef itk::ImageFileReader<InputImageType> InputReaderType;
- typename InputReaderType::Pointer reader = InputReaderType::New();
- reader->SetFileName( m_InputFileName);
- reader->Update();
- typename InputImageType::Pointer input= reader->GetOutput();
-
- // Read the directions over which to fill holes
- std::vector<unsigned int> direction;
- if (m_ArgsInfo.dir_given)
- for ( unsigned int i=0;i<m_ArgsInfo.dir_given;i++)
- direction.push_back(m_ArgsInfo.dir_arg[i]);
- else
- for ( unsigned int i=0;i<Dimension;i++)
- direction.push_back(Dimension-i-1);
+#ifndef CLITKFILLMASKGENERICFILTER_TXX
+#define CLITKFILLMASKGENERICFILTER_TXX
- //----------------------------------------
- // Cast to internal type
- //----------------------------------------
- typedef itk::CastImageFilter<InputImageType,InternalImageType> InputCastImageFilterType;
- typename InputCastImageFilterType::Pointer inputCaster= InputCastImageFilterType::New();
- inputCaster->SetInput(input);
- inputCaster->Update();
+#include "clitkImageCommon.h"
+
+//--------------------------------------------------------------------
+template<class ArgsInfoType>
+clitk::FillMaskGenericFilter<ArgsInfoType>::FillMaskGenericFilter():
+ ImageToImageGenericFilter<Self>("FillMask")
+{
+ this->SetFilterBase(NULL);
+ InitializeImageType<3>();
+}
+//--------------------------------------------------------------------
- //----------------------------------------
- // Loop over directions
- //----------------------------------------
- typename InternalImageType::Pointer output=inputCaster->GetOutput();
- for (unsigned int i=0; i<direction.size();i++)
- {
-
- //----------------------------------------
- // Fill the holes of a mask in 2D
- //----------------------------------------
- if(m_Verbose) std::cout<<"Fill holes in the mask slice by slice in direction "<<direction[i]<<"..."<<std::endl;
- // We define the region to be extracted.
- typedef itk::Image<InternalPixelType, Dimension-1> ImageSliceType;
- typedef itk::Image<InternalPixelType, Dimension-1> MaskSliceType;
- typename InternalImageType::RegionType region3D= input->GetLargestPossibleRegion();
- typename InternalImageType::RegionType::SizeType size3D= region3D.GetSize();
- typename InternalImageType::RegionType::SizeType size2D=size3D;
- size2D[direction[i]]=0;
- typename InternalImageType::IndexType start2D;
- start2D.Fill(0);
- typename InternalImageType::RegionType desiredRegion;
- desiredRegion.SetSize( size2D );
- desiredRegion.SetIndex( start2D );
-
- // Extract and Join
- typedef itk::ExtractImageFilter<InternalImageType, ImageSliceType> ExtractImageFilterType;
- typedef itk::JoinSeriesImageFilter<ImageSliceType, InternalImageType> JoinSeriesFilterType;
- typename JoinSeriesFilterType::Pointer joinFilter=JoinSeriesFilterType::New();
- joinFilter->SetSpacing(input->GetSpacing()[direction[i]]);
-
- //----------------------------------------
- // Run over the sliceIndexs
- // ----------------------------------------
- for(unsigned int sliceIndex=0; sliceIndex <size3D[direction[i]]; sliceIndex++)
- {
- //----------------------------------------
- // Extract mask sliceIndex
- //----------------------------------------
- typename ExtractImageFilterType::Pointer extractFilter=ExtractImageFilterType::New();
- extractFilter->SetInput(output);
- start2D[direction[i]]=sliceIndex;
- desiredRegion.SetIndex( start2D );
- extractFilter->SetExtractionRegion( desiredRegion );
- extractFilter->Update( );
- typename ImageSliceType::Pointer slice= extractFilter->GetOutput();
+//--------------------------------------------------------------------
+template<class ArgsInfoType>
+template<unsigned int Dim>
+void clitk::FillMaskGenericFilter<ArgsInfoType>::InitializeImageType()
+{
+ ADD_IMAGE_TYPE(Dim, uchar);
+ // ADD_IMAGE_TYPE(Dim, int);
+ // ADD_IMAGE_TYPE(Dim, float);
+}
+//--------------------------------------------------------------------
+
- // Binarize the image (Before: OBJECT!=0, rest=0, After: object=1, rest=0 )
- typedef itk::BinaryThresholdImageFilter<ImageSliceType,ImageSliceType> BinarizeFilterType;
- typename BinarizeFilterType::Pointer binarizeFilter=BinarizeFilterType::New();
- binarizeFilter->SetInput(slice);
- binarizeFilter->SetUpperThreshold(0);
- binarizeFilter->SetOutsideValue(0);
- binarizeFilter->SetInsideValue(1);
- // writeImage<ImageSliceType>(binarizeFilter->GetOutput(),"/home/jef/tmp/input.mhd");
+//--------------------------------------------------------------------
+template<class ArgsInfoType>
+void clitk::FillMaskGenericFilter<ArgsInfoType>::SetArgsInfo(const ArgsInfoType & a)
+{
+ mArgsInfo=a;
+ SetIOVerbose(mArgsInfo.verbose_flag);
+ // if (mArgsInfo.imagetypes_flag) this->PrintAvailableImageTypes();
+ if (mArgsInfo.input_given) AddInputFilename(mArgsInfo.input_arg);
+ if (mArgsInfo.output_given) AddOutputFilename(mArgsInfo.output_arg);
+}
+//--------------------------------------------------------------------
- // Perform connected labelling on the slice (body+air=0 )
- typedef itk::ConnectedComponentImageFilter<ImageSliceType, ImageSliceType> ConnectFilterType;
- typename ConnectFilterType::Pointer connectFilter=ConnectFilterType::New();
- connectFilter->SetInput(binarizeFilter->GetOutput());
- connectFilter->SetBackgroundValue(0);
- connectFilter->SetFullyConnected(false);
- //connectFilter->Update();
- //writeImage<ImageSliceType>(connectFilter->GetOutput(),"/home/jef/tmp/connect.mhd");
-
- // Sort the labels
- typedef itk::RelabelComponentImageFilter<ImageSliceType, ImageSliceType> RelabelFilterType;
- typename RelabelFilterType::Pointer relabelFilter=RelabelFilterType::New();
- relabelFilter->SetInput(connectFilter->GetOutput());
- //relabelFilter->Update();
- //writeImage<ImageSliceType>(relabelFilter->GetOutput(),"/home/jef/tmp/label.mhd");
-
- // Keep the first
- typedef itk::ThresholdImageFilter<ImageSliceType> ThresholdFilterType;
- typename ThresholdFilterType::Pointer thresholdFilter=ThresholdFilterType::New();
- thresholdFilter->SetInput(relabelFilter->GetOutput());
- thresholdFilter->SetUpper(1);
- thresholdFilter->SetOutsideValue(0);
- // thresholdFilter->Update();
- // writeImage<ImageSliceType>(thresholdFilter->GetOutput(),"/home/jef/tmp/bin.mhd");
- // Invert the labels (lung 1, rest 0)
- typename BinarizeFilterType::Pointer switchFilter=BinarizeFilterType::New();
- switchFilter->SetInput(thresholdFilter->GetOutput());
- switchFilter->SetUpperThreshold(0);
- switchFilter->SetOutsideValue(0);
- switchFilter->SetInsideValue(1);
- switchFilter->Update();
- //writeImage<ImageSliceType>(switchFilter->GetOutput(),"/home/jef/tmp/inv_bin.mhd");
-
- //Join
- joinFilter->SetInput( sliceIndex, switchFilter->GetOutput());
- }
-
- // Join to a 3D image
- if (m_Verbose) std::cout<<"Joining the slices..."<<std::endl;
- joinFilter->Update();
-
- // Permute the axes to reset to orientation
- typedef itk::PermuteAxesImageFilter<InternalImageType> PermuteFilterType;
- typename PermuteFilterType::Pointer permuteFilter=PermuteFilterType::New();
- permuteFilter->SetInput(joinFilter->GetOutput());
- typename PermuteFilterType::PermuteOrderArrayType order;
- order[direction[i]]=2;
- if( direction[i]==2)
- {
- order[0]=0;
- order[1]=1;
- }
- else if ( direction[i]==1)
- {
- order[0]=0;
- order[2]=1;
- }
- else if (direction[i]==0)
- {
- order[1]=0;
- order[2]=1;
- }
- permuteFilter->SetOrder(order);
- permuteFilter->Update();
- output =permuteFilter->GetOutput();
-
- // Set the image direction to the input one
- output->SetDirection(input->GetDirection());
- output->SetOrigin(input->GetOrigin());
- }
+//--------------------------------------------------------------------
+// Update with the number of dimensions and the pixeltype
+//--------------------------------------------------------------------
+template<class ArgsInfoType>
+template<class ImageType>
+void clitk::FillMaskGenericFilter<ArgsInfoType>::UpdateWithInputImageType()
+{
+ // Reading input
+ typename ImageType::Pointer input = this->template GetInput<ImageType>(0);
+ // Create filter
+ typedef clitk::FillMaskFilter<ImageType> FilterType;
+ typename FilterType::Pointer filter = FilterType::New();
- // Cast
- typedef itk::CastImageFilter<InternalImageType,OutputImageType> OutputCastImageFilterType;
- typename OutputCastImageFilterType::Pointer outputCaster =OutputCastImageFilterType::New();
- outputCaster->SetInput(output);
-
- // Output
- typedef itk::ImageFileWriter<OutputImageType> WriterType;
- typename WriterType::Pointer writer = WriterType::New();
- writer->SetFileName(m_ArgsInfo.output_arg);
- writer->SetInput(outputCaster->GetOutput());
- writer->Update();
- }
+ // Set Options
+ filter->SetInput(input);
+ filter->SetOptionsFromArgsInfo(mArgsInfo);
-}//end clitk
+ // Go !
+ filter->Update();
+
+ // Write/Save results
+ typename ImageType::Pointer output = filter->GetOutput();
+ this->template SetNextOutput<ImageType>(output);
+}
+//--------------------------------------------------------------------
-#endif //#define clitkFillMaskGenericFilter_txx
+#endif //#define CLITKFILLMASKGENERICFILTER_TXX