From 205ae7d81e6049af88e1cf14dde9c3473240887a Mon Sep 17 00:00:00 2001 From: dsarrut Date: Fri, 22 Oct 2010 07:56:13 +0000 Subject: [PATCH] new FillMask with itk filter --- segmentation/clitkFillMaskFilter.h | 102 +++++++++++ segmentation/clitkFillMaskFilter.txx | 247 +++++++++++++++++++++++++++ 2 files changed, 349 insertions(+) create mode 100644 segmentation/clitkFillMaskFilter.h create mode 100644 segmentation/clitkFillMaskFilter.txx diff --git a/segmentation/clitkFillMaskFilter.h b/segmentation/clitkFillMaskFilter.h new file mode 100644 index 0000000..31c25b3 --- /dev/null +++ b/segmentation/clitkFillMaskFilter.h @@ -0,0 +1,102 @@ +/*========================================================================= + Program: vv http://www.creatis.insa-lyon.fr/rio/vv + + 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. + + It is distributed under dual licence + + - BSD See included LICENSE.txt file + - CeCILL-B http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html + ======================================================================-====*/ + +#ifndef CLITKFILLMASKFILTER_H +#define CLITKFILLMASKFILTER_H + +// clitk +#include "clitkCommon.h" + +//itk +#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" + +namespace clitk +{ + + //-------------------------------------------------------------------- + template + class ITK_EXPORT FillMaskFilter: + public itk::ImageToImageFilter + { + public: + /** Standard class typedefs. */ + typedef itk::ImageToImageFilter Superclass; + typedef FillMaskFilter Self; + typedef itk::SmartPointer Pointer; + typedef itk::SmartPointer ConstPointer; + + /** Method for creation through the object factory */ + itkNewMacro(Self); + + /** Run-time type information (and related methods)*/ + itkTypeMacro(FillMaskFilter, ImageToImageFilter); + + /** Some convenient typedefs */ + typedef TImageType ImageType; + typedef typename ImageType::ConstPointer InputImageConstPointer; + typedef typename ImageType::Pointer InputImagePointer; + typedef typename ImageType::RegionType InputImageRegionType; + typedef typename ImageType::PixelType InputImagePixelType; + typedef typename ImageType::SizeType InputImageSizeType; + typedef typename ImageType::IndexType InputImageIndexType; + typedef typename ImageType::PointType InputImagePointType; + itkStaticConstMacro(ImageDimension, unsigned int, ImageType::ImageDimension); + + /** Options */ + void AddDirection(int dir); + void ResetDirections(); + const std::vector & GetDirections() const { return m_Directions; } + + // Set all options at a time + template void SetOptionsFromArgsInfo(ArgsInfoType & arg); + template void SetOptionsToArgsInfo(ArgsInfoType & arg); + + protected: + FillMaskFilter(); + virtual ~FillMaskFilter() {}; + + // Main members + InputImageConstPointer input; + std::vector m_Directions; + + // Main function + virtual void GenerateData(); + + private: + FillMaskFilter(const Self&); //purposely not implemented + void operator=(const Self&); //purposely not implemented + + }; // end class + //-------------------------------------------------------------------- + +} // end namespace clitk +//-------------------------------------------------------------------- + +#ifndef ITK_MANUAL_INSTANTIATION +#include "clitkFillMaskFilter.txx" +#endif + +#endif diff --git a/segmentation/clitkFillMaskFilter.txx b/segmentation/clitkFillMaskFilter.txx new file mode 100644 index 0000000..7ddda01 --- /dev/null +++ b/segmentation/clitkFillMaskFilter.txx @@ -0,0 +1,247 @@ +/*========================================================================= + Program: vv http://www.creatis.insa-lyon.fr/rio/vv + + 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. + + It is distributed under dual licence + + - BSD See included LICENSE.txt file + - CeCILL-B http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html + ======================================================================-====*/ + +#ifndef CLITKFILLMASKFILTER_TXX +#define CLITKFILLMASKFILTER_TXX + +//-------------------------------------------------------------------- +template +clitk::FillMaskFilter::FillMaskFilter(): + itk::ImageToImageFilter() +{ + // Default global options + this->SetNumberOfRequiredInputs(1); + ResetDirections(); + AddDirection(2); + AddDirection(1); + AddDirection(0); +} +//-------------------------------------------------------------------- + + +//-------------------------------------------------------------------- +template +void +clitk::FillMaskFilter:: +AddDirection(int dir) +{ + m_Directions.push_back(dir); +} +//-------------------------------------------------------------------- + + +//-------------------------------------------------------------------- +template +void +clitk::FillMaskFilter:: +ResetDirections() +{ + m_Directions.clear(); +} +//-------------------------------------------------------------------- + + +//-------------------------------------------------------------------- +template +template +void +clitk::FillMaskFilter:: +SetOptionsFromArgsInfo(ArgsInfoType & mArgsInfo) +{ + ResetDirections(); + for(uint i=0; i +template +void +clitk::FillMaskFilter:: +SetOptionsToArgsInfo(ArgsInfoType & mArgsInfo) +{ + mArgsInfo.dir_arg = new int[m_Directions.size()]; + mArgsInfo.dir_given = m_Directions.size(); + for(uint i=0; i +void +clitk::FillMaskFilter:: +GenerateData() +{ + InputImagePointer input = dynamic_cast(itk::ProcessObject::GetInput(0)); + + // Cast + typedef int InternalPixelType; + typedef itk::Image InternalImageType; + typedef itk::CastImageFilter InputCastImageFilterType; + typename InputCastImageFilterType::Pointer inputCaster = InputCastImageFilterType::New(); + inputCaster->SetInput(input); + inputCaster->Update(); + + //---------------------------------------- + // Loop over directions + //---------------------------------------- + typename InternalImageType::Pointer output = inputCaster->GetOutput(); + for (unsigned int i=0; i ImageSliceType; + typedef itk::Image MaskSliceType; + typename InternalImageType::RegionType region3D = input->GetLargestPossibleRegion(); + typename InternalImageType::RegionType::SizeType size3D = region3D.GetSize(); + typename InternalImageType::RegionType::SizeType size2D = size3D; + size2D[m_Directions[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 ExtractImageFilterType; + typedef itk::JoinSeriesImageFilter JoinSeriesFilterType; + typename JoinSeriesFilterType::Pointer joinFilter=JoinSeriesFilterType::New(); + joinFilter->SetSpacing(input->GetSpacing()[m_Directions[i]]); + + //---------------------------------------- + // Run over the sliceIndexs + // ---------------------------------------- + for(unsigned int sliceIndex=0; sliceIndex SetInput(output); + start2D[m_Directions[i]]=sliceIndex; + desiredRegion.SetIndex( start2D ); + extractFilter->SetExtractionRegion( desiredRegion ); + extractFilter->Update( ); + typename ImageSliceType::Pointer slice= extractFilter->GetOutput(); + + // Binarize the image (Before: OBJECT!=0, rest=0, After: object=1, rest=0 ) + typedef itk::BinaryThresholdImageFilter BinarizeFilterType; + typename BinarizeFilterType::Pointer binarizeFilter=BinarizeFilterType::New(); + binarizeFilter->SetInput(slice); + binarizeFilter->SetUpperThreshold(0); + binarizeFilter->SetOutsideValue(0); + binarizeFilter->SetInsideValue(1); + // writeImage(binarizeFilter->GetOutput(),"/home/jef/tmp/input.mhd"); + + // Perform connected labelling on the slice (body+air=0 ) + typedef itk::ConnectedComponentImageFilter ConnectFilterType; + typename ConnectFilterType::Pointer connectFilter=ConnectFilterType::New(); + connectFilter->SetInput(binarizeFilter->GetOutput()); + connectFilter->SetBackgroundValue(0); + connectFilter->SetFullyConnected(false); + //connectFilter->Update(); + //writeImage(connectFilter->GetOutput(),"/home/jef/tmp/connect.mhd"); + + // Sort the labels + typedef itk::RelabelComponentImageFilter RelabelFilterType; + typename RelabelFilterType::Pointer relabelFilter=RelabelFilterType::New(); + relabelFilter->SetInput(connectFilter->GetOutput()); + //relabelFilter->Update(); + //writeImage(relabelFilter->GetOutput(),"/home/jef/tmp/label.mhd"); + + // Keep the first + typedef itk::ThresholdImageFilter ThresholdFilterType; + typename ThresholdFilterType::Pointer thresholdFilter=ThresholdFilterType::New(); + thresholdFilter->SetInput(relabelFilter->GetOutput()); + thresholdFilter->SetUpper(1); + thresholdFilter->SetOutsideValue(0); + // thresholdFilter->Update(); + // writeImage(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(switchFilter->GetOutput(),"/home/jef/tmp/inv_bin.mhd"); + + //Join + joinFilter->SetInput( sliceIndex, switchFilter->GetOutput()); + } + + // Join to a 3D image + std::cout<<"Joining the slices..."<Update(); + + // Permute the axes to reset to orientation + typedef itk::PermuteAxesImageFilter PermuteFilterType; + typename PermuteFilterType::Pointer permuteFilter=PermuteFilterType::New(); + permuteFilter->SetInput(joinFilter->GetOutput()); + typename PermuteFilterType::PermuteOrderArrayType order; + order[m_Directions[i]]=2; + if( m_Directions[i]==2) + { + order[0]=0; + order[1]=1; + } + else if ( m_Directions[i]==1) + { + order[0]=0; + order[2]=1; + } + else if (m_Directions[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()); + } + + writeImage(output, "toto.mhd"); + + // Cast + DD("cast"); + typedef itk::CastImageFilter OutputCastImageFilterType; + typename OutputCastImageFilterType::Pointer outputCaster =OutputCastImageFilterType::New(); + outputCaster->SetInput(output); + outputCaster->Update(); + + // Output + DD("Graft"); + this->GraftOutput(outputCaster->GetOutput()); +} +//-------------------------------------------------------------------- + +#endif //#define CLITKFILLMASKFILTER_TXX -- 2.47.1