From: dsarrut Date: Mon, 12 Jul 2010 06:57:08 +0000 (+0000) Subject: some small corrections X-Git-Tag: v1.2.0~538 X-Git-Url: https://git.creatis.insa-lyon.fr/pubgit/?a=commitdiff_plain;h=38786c4da19b87319bbe3cecc145e3d1771d10da;p=clitk.git some small corrections --- diff --git a/common/clitkCommonGenericFilter.h b/common/clitkCommonGenericFilter.h index 3f9d63c..b75c1b7 100644 --- a/common/clitkCommonGenericFilter.h +++ b/common/clitkCommonGenericFilter.h @@ -20,6 +20,7 @@ #define CLITKCOMMONGENERICFILTER_H #include "clitkCommon.h" +#include "clitkFilterBase.h" /*-------------------------------------------------------------------- DISCLAIMER : I obviously know how to make this mess much clearer and @@ -65,14 +66,14 @@ namespace clitk { mMapOfImageTypeToFunction[dim][ncomp][pixelname]->Execute(); } template - void AddNewDimensionAndPixelType() { + void AddNewDimensionAndPixelType() { typedef itk::Image,Dim> InputImageType; mMapOfImageTypeToFunction[Dim][NComp][ GetTypeAsString() ] = new GenericFilterFunctorWithDimAndPixelType(mFilter); } /// Specialization for NComp == 1 template - void AddNewDimensionAndPixelType() { + void AddNewDimensionAndPixelType() { typedef itk::Image InputImageType; mMapOfImageTypeToFunction[Dim][1][ GetTypeAsString() ] = new GenericFilterFunctorWithDimAndPixelType(mFilter); diff --git a/common/clitkFilterBase.cxx b/common/clitkFilterBase.cxx index 74424d4..2b42720 100644 --- a/common/clitkFilterBase.cxx +++ b/common/clitkFilterBase.cxx @@ -22,6 +22,7 @@ //-------------------------------------------------------------------- clitk::FilterBase::FilterBase() { + m_MustStop = false; SetVerboseOption(false); SetCurrentStepNumber(0); SetCurrentStepBaseId(""); @@ -79,8 +80,10 @@ void clitk::FilterBase::StartNewStep(std::string s) SetCurrentStepId(oss.str()); } + m_CurrentStepName = "Step "+GetCurrentStepId()+" -- "+s; if (m_VerboseStep) { - std::cout << "Step " << GetCurrentStepId() << " -- " << s << std::endl; + std::cout << m_CurrentStepName << std::endl; + //"Step " << GetCurrentStepId() << " -- " << s << std::endl; } } //-------------------------------------------------------------------- @@ -93,3 +96,12 @@ void clitk::FilterBase::StopCurrentStep() } //-------------------------------------------------------------------- + +//-------------------------------------------------------------------- +void clitk::FilterBase::MustStop() +{ + m_MustStop = true; +} +//-------------------------------------------------------------------- + + diff --git a/common/clitkFilterBase.h b/common/clitkFilterBase.h index 7c3922a..ef0a0d9 100644 --- a/common/clitkFilterBase.h +++ b/common/clitkFilterBase.h @@ -60,6 +60,8 @@ namespace clitk { GGO_DefineOption_Flag(verboseOption, SetVerboseOption); // Steps management + itkSetMacro(NumberOfSteps, int); + itkGetConstMacro(NumberOfSteps, int); itkSetMacro(VerboseStep, bool); itkGetConstMacro(VerboseStep, bool); itkBooleanMacro(VerboseStep); @@ -76,6 +78,8 @@ namespace clitk { itkGetConstMacro(CurrentStepId, std::string); itkSetMacro(CurrentStepBaseId, std::string); itkGetConstMacro(CurrentStepBaseId, std::string); + itkSetMacro(CurrentStepName, std::string); + itkGetConstMacro(CurrentStepName, std::string); // Convenient function for verbose option template @@ -101,6 +105,9 @@ namespace clitk { itkBooleanMacro(VerboseWarningOff); GGO_DefineOption_Flag(verboseWarningOff, SetVerboseWarningOff); + // Use this function to stop (when threaded) + void MustStop(); + protected: FilterBase(); virtual ~FilterBase() {} @@ -113,12 +120,15 @@ namespace clitk { bool m_VerboseStep; bool m_WriteStep; int m_CurrentStepNumber; + int m_NumberOfSteps; std::string m_CurrentStepId; std::string m_CurrentStepBaseId; std::string m_LastError; + std::string m_CurrentStepName; bool m_StopOnError; std::string m_Warning; bool m_VerboseWarningOff; + bool m_MustStop; private: FilterBase(const Self&); //purposely not implemented diff --git a/common/clitkImageToImageGenericFilterBase.cxx b/common/clitkImageToImageGenericFilterBase.cxx index a685f6d..1da0144 100644 --- a/common/clitkImageToImageGenericFilterBase.cxx +++ b/common/clitkImageToImageGenericFilterBase.cxx @@ -15,7 +15,11 @@ - BSD See included LICENSE.txt file - CeCILL-B http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html ======================================================================-====*/ + +// clitk #include "clitkImageToImageGenericFilterBase.h" + +// itk #include //-------------------------------------------------------------------- diff --git a/common/clitkImageToImageGenericFilterBase.h b/common/clitkImageToImageGenericFilterBase.h index 2d624ba..4b27950 100644 --- a/common/clitkImageToImageGenericFilterBase.h +++ b/common/clitkImageToImageGenericFilterBase.h @@ -15,6 +15,7 @@ - BSD See included LICENSE.txt file - CeCILL-B http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html ======================================================================-====*/ + #ifndef CLITKIMAGETOIMAGEGENERICFILTERBASE_H #define CLITKIMAGETOIMAGEGENERICFILTERBASE_H @@ -22,6 +23,7 @@ #include "clitkCommon.h" #include "clitkImageCommon.h" #include "clitkCommonGenericFilter.h" +#include "clitkFilterBase.h" // itk #include @@ -60,7 +62,6 @@ namespace clitk { /// Returns the dimension and pixel type of the *first* input void GetInputImageDimensionAndPixelType(unsigned int& dim, std::string& pixeltype, unsigned int & components); - // File IO void SetInputFilename(const std::string & filename); void AddInputFilename(const std::string & filename); @@ -89,6 +90,9 @@ namespace clitk { // Main function to call for using the filter. virtual bool Update() = 0; + // Get the associated filter + FilterBase * GetFilterBase() { return m_FilterBase; } + protected: bool m_ReadOnDisk; /// Call this function to dispatch an output towards the correct sink @@ -116,6 +120,8 @@ namespace clitk { bool m_FailOnImageTypeError; std::string m_LastError; + void SetFilterBase(FilterBase * f) { m_FilterBase = f; } + FilterBase * m_FilterBase; }; // end class clitk::ImageToImageGenericFilter diff --git a/itk/RelativePositionPropImageFilter.h b/itk/RelativePositionPropImageFilter.h index e7f7da5..fca49f6 100644 --- a/itk/RelativePositionPropImageFilter.h +++ b/itk/RelativePositionPropImageFilter.h @@ -3,24 +3,24 @@ Program: Insight Segmentation & Registration Toolkit Module: $RCSfile: RelativePositionPropImageFilter.h,v $ Language: C++ - Date: $Date: 2010/06/30 05:58:56 $ - Version: $Revision: 1.1 $ + Date: $Date: 2010/07/12 06:57:25 $ + Version: $Revision: 1.2 $ Copyright (c) Insight Software Consortium. All rights reserved. See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details. - This software is distributed WITHOUT ANY WARRANTY; without even - the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR - PURPOSE. See the above copyright notices for more information. + This software is distributed WITHOUT ANY WARRANTY; without even + the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + PURPOSE. See the above copyright notices for more information. + + =========================================================================*/ -=========================================================================*/ #ifndef __RelativePositionPropImageFilter_h #define __RelativePositionPropImageFilter_h #include "itkImageToImageFilter.h" #include "itkImage.h" #include "itkConceptChecking.h" - #include "itkPointSet.h" #include "itkImageRegionConstIteratorWithIndex.h" #include "itkImageRegionIteratorWithIndex.h" @@ -30,182 +30,179 @@ namespace itk { -/** \class RelativePositionPropImageFilter - * \brief Compute the fuzzy subset of an image which satisfies some directional relative position. - * \author Jamal Atif and Olivier Nempont - * - * This filter computes a fuzzy subset of an image satisfying a particular directionnal relative position from an object (crisp or fuzzy). - * - * - * \par INPUT / OUTPUT - * This filter takes a crisp or a fuzzy object as input. - * In fuzzy case, the values have to be defined between 0 and 1. - * - * The result is a fuzzy subset which values are defined between - * 0 if the relation isn't fulfilled in this point to 1 is the relation is - * fully satisfied. - * WARNING: the output image type as to be decimal. - * - * \par PARAMETERS - * \par - * The Alpha1 and Alpha2 parameters are used to specify the direction. - * Alpha1 is the angle in 'xy' plane from 'x' unit vector. - * Alpha2 is used in 3D to specify the angle with 'xy' plane - * - * \par - * K is an opening parameter. Higher value enlarge the support of the result. - * By default it is fixed at PI/2 - * - * \par REFERENCE - * Fuzzy Relative Position Between Objects in Image Processing: A Morphological Approach - * Isabelle Bloch - * IEEE TRANSACTIONS ON PATTERN ANALYSIS AND MACHINE INTELLIGENCE, VOL. 21, NO. 7, JULY 1999 - * - * This filter is implemented using the propagation algorithm - */ + /** \class RelativePositionPropImageFilter + * \brief Compute the fuzzy subset of an image which satisfies some directional relative position. + * \author Jamal Atif and Olivier Nempont + * + * This filter computes a fuzzy subset of an image satisfying a particular directionnal relative position from an object (crisp or fuzzy). + * + * + * \par INPUT / OUTPUT + * This filter takes a crisp or a fuzzy object as input. + * In fuzzy case, the values have to be defined between 0 and 1. + * + * The result is a fuzzy subset which values are defined between + * 0 if the relation isn't fulfilled in this point to 1 is the relation is + * fully satisfied. + * WARNING: the output image type as to be decimal. + * + * \par PARAMETERS + * \par + * The Alpha1 and Alpha2 parameters are used to specify the direction. + * Alpha1 is the angle in 'xy' plane from 'x' unit vector. + * Alpha2 is used in 3D to specify the angle with 'xy' plane + * + * \par + * K is an opening parameter. Higher value enlarge the support of the result. + * By default it is fixed at PI/2 + * + * \par REFERENCE + * Fuzzy Relative Position Between Objects in Image Processing: A Morphological Approach + * Isabelle Bloch + * IEEE TRANSACTIONS ON PATTERN ANALYSIS AND MACHINE INTELLIGENCE, VOL. 21, NO. 7, JULY 1999 + * + * This filter is implemented using the propagation algorithm + */ -template > -class ITK_EXPORT RelativePositionPropImageFilter : + template > + class ITK_EXPORT RelativePositionPropImageFilter : public ImageToImageFilter< TInputImage, TOutputImage > -{ -public: - /** Standard class typedefs. */ - typedef RelativePositionPropImageFilter Self; - typedef ImageToImageFilter< TInputImage, TOutputImage > Superclass; - typedef SmartPointer Pointer; - typedef SmartPointer ConstPointer; - - /** Extract some information from the image types. Dimensionality - * of the two images is assumed to be the same. */ - typedef typename TOutputImage::PixelType OutputPixelType; - typedef typename TOutputImage::InternalPixelType OutputInternalPixelType; - typedef typename TInputImage::PixelType InputPixelType; - typedef typename TInputImage::InternalPixelType InputInternalPixelType; - - /** Extract some information from the image types. Dimensionality - * of the two images is assumed to be the same. */ - itkStaticConstMacro(ImageDimension, unsigned int, - TOutputImage::ImageDimension); + { + public: + /** Standard class typedefs. */ + typedef RelativePositionPropImageFilter Self; + typedef ImageToImageFilter< TInputImage, TOutputImage > Superclass; + typedef SmartPointer Pointer; + typedef SmartPointer ConstPointer; + + /** Extract some information from the image types. Dimensionality + * of the two images is assumed to be the same. */ + typedef typename TOutputImage::PixelType OutputPixelType; + typedef typename TOutputImage::InternalPixelType OutputInternalPixelType; + typedef typename TInputImage::PixelType InputPixelType; + typedef typename TInputImage::InternalPixelType InputInternalPixelType; + + /** Extract some information from the image types. Dimensionality + * of the two images is assumed to be the same. */ + itkStaticConstMacro(ImageDimension, unsigned int, + TOutputImage::ImageDimension); - typedef typename itk::Image - CorrespondanceMapType; - typedef float TabulationPixelType; - typedef typename itk::Image TabulationImageType; + typedef typename itk::Image + CorrespondanceMapType; + typedef float TabulationPixelType; + typedef typename itk::Image TabulationImageType; - /** Image typedef support. */ - typedef TInputImage InputImageType; - typedef TOutputImage OutputImageType; + /** Image typedef support. */ + typedef TInputImage InputImageType; + typedef TOutputImage OutputImageType; - typedef TtNorm TNormType; + typedef TtNorm TNormType; - typedef itk::Vector VectorType; + typedef itk::Vector VectorType; - /** Method for creation through the object factory. */ - itkNewMacro(Self); + /** Method for creation through the object factory. */ + itkNewMacro(Self); - /** Run-time type information (and related methods). */ - itkTypeMacro(RelativePositionPropImageFilter, ImageToImageFilter); + /** Run-time type information (and related methods). */ + itkTypeMacro(RelativePositionPropImageFilter, ImageToImageFilter); - /** The output pixel type must be signed. */ - itkConceptMacro(SignedOutputPixelType, (Concept::Signed)); + /** The output pixel type must be signed. */ + itkConceptMacro(SignedOutputPixelType, (Concept::Signed)); - /** Standard get/set macros for filter parameters. */ + /** Standard get/set macros for filter parameters. */ - itkSetMacro(Alpha1, double); - itkGetMacro(Alpha1, double); - itkSetMacro(Alpha2, double); - itkGetMacro(Alpha2, double); + itkSetMacro(Alpha1, double); + itkGetMacro(Alpha1, double); + itkSetMacro(Alpha2, double); + itkGetMacro(Alpha2, double); - itkSetMacro(K1, double); - itkGetMacro(K1, double); -// itkSetMacro(K2, double); -// itkGetMacro(K2, double); + itkSetMacro(K1, double); + itkGetMacro(K1, double); + // itkSetMacro(K2, double); + // itkGetMacro(K2, double); - itkSetMacro(Radius, double); - itkGetMacro(Radius, double); + itkSetMacro(Radius, double); + itkGetMacro(Radius, double); - itkSetMacro(VerboseProgress, bool); - itkGetMacro(VerboseProgress, bool); - itkBooleanMacro(VerboseProgress); + itkSetMacro(VerboseProgress, bool); + itkGetMacro(VerboseProgress, bool); + itkBooleanMacro(VerboseProgress); - itkSetMacro(Fast, bool); - itkGetMacro(Fast, bool); - itkBooleanMacro(Fast); + itkSetMacro(Fast, bool); + itkGetMacro(Fast, bool); + itkBooleanMacro(Fast); - void computeDirection() - { - switch(ImageDimension) - { -// case 2: // DS comment to avoid warning -// m_DirectionVector[0]=cos(m_Alpha1); -// m_DirectionVector[1]=sin(m_Alpha1); -// break; - case 3: - m_DirectionVector[0]=cos(m_Alpha1)*cos(m_Alpha2); - m_DirectionVector[1]=cos(m_Alpha2)*sin(m_Alpha1); - m_DirectionVector[2]=sin(m_Alpha2); - break; - } - } + void computeDirection() + { + if (ImageDimension == 2) { + m_DirectionVector[0]=cos(m_Alpha1); + m_DirectionVector[1]=sin(m_Alpha1); + } + else { // 3D + m_DirectionVector[0]=cos(m_Alpha1)*cos(m_Alpha2); + m_DirectionVector[1]=cos(m_Alpha2)*sin(m_Alpha1); + m_DirectionVector[2]=sin(m_Alpha2); + } + } - virtual void GenerateInputRequestedRegion() throw(InvalidRequestedRegionError); - void EnlargeOutputRequestedRegion (DataObject * output); - -protected: - RelativePositionPropImageFilter() - { - m_Alpha1 = 0; - m_Alpha2 = 0; - m_K1 = vcl_acos(-1.0)/2; - // m_K2 = 3.1417/2; - m_Radius = 2; // DS - m_Fast = true; // DS - m_VerboseProgress = false; - } - virtual ~RelativePositionPropImageFilter() {} - void PrintSelf(std::ostream& os, Indent indent) const; - - //void GenerateThreadedData(const typename TOutputImage::RegionType& outputRegionForThread, int threadId); - void GenerateData(); - -private: - RelativePositionPropImageFilter(const Self&); //purposely not implemented - void operator=(const Self&); //purposely not implemented - - - /** The angles*/ - double m_Alpha1; - double m_Alpha2; - double m_K1; - // double m_K2; + virtual void GenerateInputRequestedRegion() throw(InvalidRequestedRegionError); + void EnlargeOutputRequestedRegion (DataObject * output); + + protected: + RelativePositionPropImageFilter() + { + m_Alpha1 = 0; + m_Alpha2 = 0; + m_K1 = vcl_acos(-1.0)/2; + // m_K2 = 3.1417/2; + m_Radius = 2; // DS + m_Fast = true; // DS + m_VerboseProgress = false; + } + virtual ~RelativePositionPropImageFilter() {} + void PrintSelf(std::ostream& os, Indent indent) const; + + //void GenerateThreadedData(const typename TOutputImage::RegionType& outputRegionForThread, int threadId); + void GenerateData(); + + private: + RelativePositionPropImageFilter(const Self&); //purposely not implemented + void operator=(const Self&); //purposely not implemented + + + /** The angles*/ + double m_Alpha1; + double m_Alpha2; + double m_K1; + // double m_K2; - unsigned int m_Radius; - TNormType m_TNorm; - bool m_VerboseProgress; + unsigned int m_Radius; + TNormType m_TNorm; + bool m_VerboseProgress; - VectorType m_DirectionVector; + VectorType m_DirectionVector; - /** - * 2 pass instead of 2^NDimension. Warning this may cause some artifacts - */ - bool m_Fast; + /** + * 2 pass instead of 2^NDimension. Warning this may cause some artifacts + */ + bool m_Fast; - //allocation et initialisation de la carte de correspondance - typename CorrespondanceMapType::Pointer InitCorrespondanceMap(); + //allocation et initialisation de la carte de correspondance + typename CorrespondanceMapType::Pointer InitCorrespondanceMap(); - //compute the tabulation map - typename TabulationImageType::Pointer ComputeAngleTabulation(); + //compute the tabulation map + typename TabulationImageType::Pointer ComputeAngleTabulation(); -}; + }; } // end namespace itk diff --git a/itk/RelativePositionPropImageFilter.txx b/itk/RelativePositionPropImageFilter.txx index 56a27d4..c2b5149 100644 --- a/itk/RelativePositionPropImageFilter.txx +++ b/itk/RelativePositionPropImageFilter.txx @@ -3,8 +3,8 @@ Program: Insight Segmentation & Registration Toolkit Module: $RCSfile: RelativePositionPropImageFilter.txx,v $ Language: C++ - Date: $Date: 2010/06/30 05:58:56 $ - Version: $Revision: 1.1 $ + Date: $Date: 2010/07/12 06:57:25 $ + Version: $Revision: 1.2 $ Copyright (c) Insight Software Consortium. All rights reserved. See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details. @@ -16,6 +16,7 @@ =========================================================================*/ #ifndef _RelativePositionPropImageFilter_txx #define _RelativePositionPropImageFilter_txx + #include "RelativePositionPropImageFilter.h" #include "itkNeighborhoodOperatorImageFilter.h" @@ -23,7 +24,6 @@ #include "itkZeroFluxNeumannBoundaryCondition.h" #include "itkProgressAccumulator.h" #include "itkImageFileWriter.h" - #include "itkSimpleContourExtractorImageFilter.h" #include "itkUnaryFunctorImageFilter.h" diff --git a/itk/clitkAddRelativePositionConstraintToLabelImageFilter.h b/itk/clitkAddRelativePositionConstraintToLabelImageFilter.h index 83400ef..249598b 100644 --- a/itk/clitkAddRelativePositionConstraintToLabelImageFilter.h +++ b/itk/clitkAddRelativePositionConstraintToLabelImageFilter.h @@ -43,15 +43,15 @@ namespace clitk { */ //-------------------------------------------------------------------- - template + template class ITK_EXPORT AddRelativePositionConstraintToLabelImageFilter: public clitk::FilterBase, - public itk::ImageToImageFilter + public itk::ImageToImageFilter { public: /** Standard class typedefs. */ - typedef itk::ImageToImageFilter Superclass; + typedef itk::ImageToImageFilter Superclass; typedef AddRelativePositionConstraintToLabelImageFilter Self; typedef itk::SmartPointer Pointer; typedef itk::SmartPointer ConstPointer; @@ -64,7 +64,6 @@ namespace clitk { FILTERBASE_INIT; /** Some convenient typedefs. */ - typedef TImageType ImageType; typedef typename ImageType::ConstPointer ImageConstPointer; typedef typename ImageType::Pointer ImagePointer; typedef typename ImageType::RegionType RegionType; @@ -73,7 +72,7 @@ namespace clitk { typedef typename ImageType::SizeType SizeType; /** ImageDimension constants */ - itkStaticConstMacro(ImageDimension, unsigned int, TImageType::ImageDimension); + itkStaticConstMacro(ImageDimension, unsigned int, ImageType::ImageDimension); typedef itk::Image FloatImageType; /** Orientation types */ @@ -89,22 +88,32 @@ namespace clitk { // Options void SetOrientationType(OrientationTypeEnumeration orientation); itkGetConstMacro(OrientationType, OrientationTypeEnumeration); + void SetAngle1(double a); void SetAngle2(double a); itkGetConstMacro(Angle1, double); itkGetConstMacro(Angle2, double); + itkGetConstMacro(ResampleBeforeRelativePositionFilter, bool); itkSetMacro(ResampleBeforeRelativePositionFilter, bool); itkBooleanMacro(ResampleBeforeRelativePositionFilter); + itkGetConstMacro(IntermediateSpacing, double); itkSetMacro(IntermediateSpacing, double); + itkGetConstMacro(FuzzyThreshold, double); itkSetMacro(FuzzyThreshold, double); + itkGetConstMacro(BackgroundValue, PixelType); itkSetMacro(BackgroundValue, PixelType); + itkGetConstMacro(ObjectBackgroundValue, PixelType); itkSetMacro(ObjectBackgroundValue, PixelType); + itkGetConstMacro(AutoCrop, bool); + itkSetMacro(AutoCrop, bool); + itkBooleanMacro(AutoCrop); + protected: AddRelativePositionConstraintToLabelImageFilter(); virtual ~AddRelativePositionConstraintToLabelImageFilter() {} @@ -117,6 +126,7 @@ namespace clitk { double m_Angle1; double m_Angle2; bool m_ResampleBeforeRelativePositionFilter; + bool m_AutoCrop; virtual void GenerateOutputInformation(); virtual void GenerateInputRequestedRegion(); diff --git a/itk/clitkAddRelativePositionConstraintToLabelImageFilter.txx b/itk/clitkAddRelativePositionConstraintToLabelImageFilter.txx index 66624a0..5e7011a 100644 --- a/itk/clitkAddRelativePositionConstraintToLabelImageFilter.txx +++ b/itk/clitkAddRelativePositionConstraintToLabelImageFilter.txx @@ -36,11 +36,11 @@ #include "RelativePositionPropImageFilter.h" //-------------------------------------------------------------------- -template -clitk::AddRelativePositionConstraintToLabelImageFilter:: +template +clitk::AddRelativePositionConstraintToLabelImageFilter:: AddRelativePositionConstraintToLabelImageFilter(): clitk::FilterBase(), - itk::ImageToImageFilter() + itk::ImageToImageFilter() { this->SetNumberOfRequiredInputs(2); SetFuzzyThreshold(0.6); @@ -49,39 +49,17 @@ AddRelativePositionConstraintToLabelImageFilter(): SetOrientationType(LeftTo); ResampleBeforeRelativePositionFilterOn(); SetIntermediateSpacing(10); - - // Step 1 : resample (option=sampling) - // Step 2 : Pad (no) - // Step 3 : relative position (option = angle) - // Step 4 : Threshold - // Step 5 : Erode for boundary - // Step 6 : resample to initial spacing - // Step 7 : pad if not the same size : it can occur when downsample and upsample - // Step 6: combine input+thresholded relpos - // Step 7: autocrop - - // Step 1 : resample - ResampleBeforeRelativePositionFilterOn(); - SetIntermediateSpacing(10); - SetOrientationType(LeftTo); - // SegmentationStep * step = new SegmentationStep; - // step->SetName("Initial resampling and relative position map"); - // SetStep(step, &Self::ResampleAndRelativePositionMap); - - // Step 3 : threshold + postprocess - // SetFuzzyThreshold(0.4); - // step = new SegmentationStep; - // step->SetName("Map threshold and post-processing"); - // SetStep(step, &Self::MapThresholdAndPostProcessing); + AutoCropOn(); } //-------------------------------------------------------------------- //-------------------------------------------------------------------- -template +template void -clitk::AddRelativePositionConstraintToLabelImageFilter:: -SetInput(const ImageType * image) { +clitk::AddRelativePositionConstraintToLabelImageFilter:: +SetInput(const ImageType * image) +{ // Process object is not const-correct so the const casting is required. this->SetNthInput(0, const_cast(image)); } @@ -89,10 +67,11 @@ SetInput(const ImageType * image) { //-------------------------------------------------------------------- -template +template void -clitk::AddRelativePositionConstraintToLabelImageFilter:: -SetInputObject(const ImageType * image) { +clitk::AddRelativePositionConstraintToLabelImageFilter:: +SetInputObject(const ImageType * image) +{ // Process object is not const-correct so the const casting is required. this->SetNthInput(1, const_cast(image)); } @@ -100,11 +79,12 @@ SetInputObject(const ImageType * image) { //-------------------------------------------------------------------- -template +template void -clitk::AddRelativePositionConstraintToLabelImageFilter:: -GenerateOutputInformation() { - ImagePointer input = dynamic_cast(itk::ProcessObject::GetInput(0)); +clitk::AddRelativePositionConstraintToLabelImageFilter:: +GenerateOutputInformation() +{ + ImagePointer input = dynamic_cast(itk::ProcessObject::GetInput(0)); ImagePointer outputImage = this->GetOutput(0); outputImage->SetRegions(outputImage->GetLargestPossibleRegion()); } @@ -112,15 +92,16 @@ GenerateOutputInformation() { //-------------------------------------------------------------------- -template +template void -clitk::AddRelativePositionConstraintToLabelImageFilter:: -GenerateInputRequestedRegion() { +clitk::AddRelativePositionConstraintToLabelImageFilter:: +GenerateInputRequestedRegion() +{ // Call default - itk::ImageToImageFilter::GenerateInputRequestedRegion(); + itk::ImageToImageFilter::GenerateInputRequestedRegion(); // Get input pointers and set requested region to common region - ImagePointer input1 = dynamic_cast(itk::ProcessObject::GetInput(0)); - ImagePointer input2 = dynamic_cast(itk::ProcessObject::GetInput(1)); + ImagePointer input1 = dynamic_cast(itk::ProcessObject::GetInput(0)); + ImagePointer input2 = dynamic_cast(itk::ProcessObject::GetInput(1)); input1->SetRequestedRegion(input1->GetLargestPossibleRegion()); input2->SetRequestedRegion(input2->GetLargestPossibleRegion()); } @@ -128,10 +109,11 @@ GenerateInputRequestedRegion() { //-------------------------------------------------------------------- -template +template void -clitk::AddRelativePositionConstraintToLabelImageFilter:: -SetAngle1(double a) { +clitk::AddRelativePositionConstraintToLabelImageFilter:: +SetAngle1(double a) +{ SetOrientationType(Angle); m_Angle1 = a; } @@ -139,10 +121,11 @@ SetAngle1(double a) { //-------------------------------------------------------------------- -template +template void -clitk::AddRelativePositionConstraintToLabelImageFilter:: -SetAngle2(double a) { +clitk::AddRelativePositionConstraintToLabelImageFilter:: +SetAngle2(double a) +{ SetOrientationType(Angle); m_Angle2 = a; } @@ -150,10 +133,11 @@ SetAngle2(double a) { //-------------------------------------------------------------------- -template +template void -clitk::AddRelativePositionConstraintToLabelImageFilter:: -SetOrientationType(OrientationTypeEnumeration orientation) { +clitk::AddRelativePositionConstraintToLabelImageFilter:: +SetOrientationType(OrientationTypeEnumeration orientation) +{ m_OrientationType = orientation; switch (m_OrientationType) { case LeftTo: m_Angle1 = clitk::deg2rad(0); m_Angle2 = clitk::deg2rad(0); break; @@ -177,19 +161,19 @@ SetOrientationType(OrientationTypeEnumeration orientation) { //-------------------------------------------------------------------- -template +template void -clitk::AddRelativePositionConstraintToLabelImageFilter:: -GenerateData() { +clitk::AddRelativePositionConstraintToLabelImageFilter:: +GenerateData() +{ // Get input pointer input = dynamic_cast(itk::ProcessObject::GetInput(0)); object = dynamic_cast(itk::ProcessObject::GetInput(1)); //-------------------------------------------------------------------- //-------------------------------------------------------------------- - StartNewStep("Resample And Relative Position Map"); - static const unsigned int dim = ImageType::ImageDimension; + StartNewStep("Initial resample and pad"); // Step 1 : resample if (m_ResampleBeforeRelativePositionFilter) { typedef clitk::ResampleImageWithOptionsFilter ResampleFilterType; @@ -203,8 +187,7 @@ GenerateData() { } else { working_image = object; - } - // writeImage(working_image, "res.mhd"); + } // Step 2: object pad to input image -> we want to compute the // relative position for each point belonging to the input image @@ -227,7 +210,7 @@ GenerateData() { typename PadFilterType::Pointer padFilter = PadFilterType::New(); typename PadFilterType::InputImageIndexType index; for(unsigned int i=0; iGetOrigin()[i] - input->GetOrigin()[i])/(double)m_IntermediateSpacing); + index[i] = lrint((working_image->GetOrigin()[i] - input->GetOrigin()[i])/working_image->GetSpacing()[i]); } padFilter->SetSourceImage(working_image); padFilter->SetDestinationImage(output); @@ -237,14 +220,14 @@ GenerateData() { working_image = padFilter->GetOutput(); } else { - DD("[debug] RelPos : same size and spacing : no padding"); + // DD("[debug] RelPos : same size and spacing : no padding"); } - // Keep object image (with resampline and pad) object_resampled = working_image; - // writeImage(working_image, "pad.mhd"); + StopCurrentStep(working_image); // Step 3: compute rel pos in object + StartNewStep("Relative Position Map"); typedef itk::RelativePositionPropImageFilter RelPosFilterType; typename RelPosFilterType::Pointer relPosFilter = RelPosFilterType::New(); relPosFilter->SetInput(working_image); @@ -256,12 +239,11 @@ GenerateData() { // relPosFilter->SetVerboseProgress(true); relPosFilter->Update(); relPos = relPosFilter->GetOutput(); - this->template StopCurrentStep(relPos); + StopCurrentStep(relPos); //-------------------------------------------------------------------- //-------------------------------------------------------------------- - StartNewStep("Map Threshold And Post Processing"); - + StartNewStep("Map Threshold"); // Step 1: threshold typedef itk::BinaryThresholdImageFilter BinaryThresholdImageFilterType; typename BinaryThresholdImageFilterType::Pointer thresholdFilter = BinaryThresholdImageFilterType::New(); @@ -271,10 +253,14 @@ GenerateData() { thresholdFilter->SetLowerThreshold(m_FuzzyThreshold); thresholdFilter->Update(); working_image = thresholdFilter->GetOutput(); + StopCurrentStep(working_image); + //-------------------------------------------------------------------- + //-------------------------------------------------------------------- + StartNewStep("Post Processing: erosion with initial mask"); // Step 2 : erosion with initial mask to exclude pixels that were // inside the resampled version and outside the original mask - typedef itk::BinaryBallStructuringElement StructuringElementType; + typedef itk::BinaryBallStructuringElement StructuringElementType; StructuringElementType kernel; kernel.SetRadius(1); kernel.CreateStructuringElement(); @@ -286,9 +272,13 @@ GenerateData() { erodeFilter->SetErodeValue(m_BackgroundValue+1); erodeFilter->Update(); working_image = erodeFilter->GetOutput(); + StopCurrentStep(working_image); + //-------------------------------------------------------------------- + //-------------------------------------------------------------------- // Step 5: resample to initial spacing if (m_ResampleBeforeRelativePositionFilter) { + StartNewStep("Resample to get the same sampling than input"); typedef clitk::ResampleImageWithOptionsFilter ResampleFilterType; typename ResampleFilterType::Pointer resampleFilter = ResampleFilterType::New(); resampleFilter->SetDefaultPixelValue(m_BackgroundValue); @@ -298,12 +288,14 @@ GenerateData() { // resampleFilter->SetVerboseOptions(true); resampleFilter->Update(); working_image = resampleFilter->GetOutput(); + StopCurrentStep(working_image); } - // writeImage(working_image, "resinitial.mhd"); - + //-------------------------------------------------------------------- + //-------------------------------------------------------------------- // Pre Step 6: pad if not the same size : it can occur when downsample and upsample if (working_image->GetLargestPossibleRegion() != input->GetLargestPossibleRegion()) { + StartNewStep("Pad to get the same size than input"); typename ImageType::Pointer temp = ImageType::New(); temp->CopyInformation(input); temp->SetRegions(input->GetLargestPossibleRegion()); // Do not forget !! @@ -316,15 +308,20 @@ GenerateData() { padFilter2->SetSourceRegion(working_image->GetLargestPossibleRegion()); padFilter2->Update(); working_image = padFilter2->GetOutput(); + StopCurrentStep(working_image); } else { - DD("[debug] Rel Pos : no padding after"); + //DD("[debug] Rel Pos : no padding after"); } - // writeImage(working_image, "pad2.mhd"); + //-------------------------------------------------------------------- + //-------------------------------------------------------------------- // Step 6: combine input+thresholded relpos + StartNewStep("Combine with initial input (boolean And)"); typedef clitk::BooleanOperatorLabelImageFilter BoolFilterType; typename BoolFilterType::Pointer combineFilter = BoolFilterType::New(); + writeImage(input, "i.mhd"); + writeImage(working_image, "w.mhd"); combineFilter->SetBackgroundValue(m_BackgroundValue); combineFilter->SetBackgroundValue1(m_BackgroundValue); combineFilter->SetBackgroundValue2(m_BackgroundValue); @@ -335,6 +332,7 @@ GenerateData() { combineFilter->InPlaceOn(); combineFilter->Update(); working_image = combineFilter->GetOutput(); + // writeImage(working_image, "res.mhd"); combineFilter = BoolFilterType::New(); combineFilter->SetInput1(working_image); @@ -344,16 +342,21 @@ GenerateData() { combineFilter->Update(); working_image = combineFilter->GetOutput(); - // writeImage(working_image, "combine.mhd"); + StopCurrentStep(working_image); + //-------------------------------------------------------------------- + //-------------------------------------------------------------------- // Step 7: autocrop - typedef clitk::AutoCropFilter CropFilterType; - typename CropFilterType::Pointer cropFilter = CropFilterType::New(); - cropFilter->SetInput(working_image); - cropFilter->ReleaseDataFlagOff(); - cropFilter->Update(); - working_image = cropFilter->GetOutput(); - this->template StopCurrentStep(working_image); + if (GetAutoCrop()) { + StartNewStep("Final AutoCrop"); + typedef clitk::AutoCropFilter CropFilterType; + typename CropFilterType::Pointer cropFilter = CropFilterType::New(); + cropFilter->SetInput(working_image); + cropFilter->ReleaseDataFlagOff(); + cropFilter->Update(); + working_image = cropFilter->GetOutput(); + StopCurrentStep(working_image); + } //-------------------------------------------------------------------- //-------------------------------------------------------------------- diff --git a/itk/clitkAutoCropFilter.txx b/itk/clitkAutoCropFilter.txx index 164bb22..6f00926 100644 --- a/itk/clitkAutoCropFilter.txx +++ b/itk/clitkAutoCropFilter.txx @@ -89,12 +89,13 @@ namespace clitk { typename ImageToMapFilterType::Pointer imageToLabelFilter = ImageToMapFilterType::New(); imageToLabelFilter->SetBackgroundValue(m_BackgroundValue); imageToLabelFilter->SetInput(input); + DD(input->GetLargestPossibleRegion()); // AutoCrop typedef itk::AutoCropLabelMapFilter AutoCropFilterType; typename AutoCropFilterType::Pointer autoCropFilter = AutoCropFilterType::New(); autoCropFilter->SetInput(imageToLabelFilter->GetOutput()); - + // Convert to LabelImage typedef itk::LabelMapToLabelImageFilter MapToImageFilterType; typename MapToImageFilterType::Pointer labelToImageFilter = MapToImageFilterType::New(); @@ -102,10 +103,18 @@ namespace clitk { // Go ! (needed) labelToImageFilter->Update(); + DD("CHECK AUTOCROP IF NB LABEL == 0 !!!"); m_labeImage = labelToImageFilter->GetOutput(); // Update the output size m_Region = m_labeImage->GetLargestPossibleRegion(); + DD(m_Region); + // Sometimes the index is 9223372036854775807 ??? + if (m_Region.GetIndex()[0] > 99999) { + typename ImageType::IndexType index; + index.Fill(0); + m_Region.SetIndex(index); + } output->SetLargestPossibleRegion(m_Region); output->SetRequestedRegion(m_Region); output->SetBufferedRegion(m_Region); @@ -118,7 +127,6 @@ namespace clitk { void AutoCropFilter:: GenerateData() { - DD("AutoCropFilter::GenerateData"); // Get input pointers ImageConstPointer input = dynamic_cast(itk::ProcessObject::GetInput(0)); diff --git a/itk/clitkExtractSliceFilter.h b/itk/clitkExtractSliceFilter.h index 93d3cd0..136f431 100644 --- a/itk/clitkExtractSliceFilter.h +++ b/itk/clitkExtractSliceFilter.h @@ -47,24 +47,10 @@ namespace clitk { class ITK_EXPORT ExtractSliceFilter: public clitk::FilterBase, public itk::ImageToImageFilter::Pointer> > + typename itk::Image > { public: - /** Standard class typedefs. */ - typedef itk::ImageToImageFilter Superclass; - typedef ExtractSliceFilter 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(ExtractSliceFilter, ImageToImageFilter); - FILTERBASE_INIT; - /** Some convenient typedefs. */ typedef typename ImageType::ConstPointer ImageConstPointer; typedef typename ImageType::Pointer ImagePointer; @@ -72,6 +58,7 @@ namespace clitk { typedef typename ImageType::PixelType PixelType; typedef typename ImageType::SpacingType SpacingType; typedef typename ImageType::SizeType SizeType; + typedef typename ImageType::IndexType IndexType; /** ImageDimension constants */ itkStaticConstMacro(ImageDimension, unsigned int, ImageType::ImageDimension); @@ -80,12 +67,28 @@ namespace clitk { typedef itk::Image SliceType; typedef typename SliceType::Pointer SliceTypePointer; + /** Standard class typedefs. */ + typedef itk::ImageToImageFilter Superclass; + typedef ExtractSliceFilter 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(ExtractSliceFilter, ImageToImageFilter); + FILTERBASE_INIT; + /** Input : initial image and object */ void SetInput(const ImageType * image); // Options itkGetConstMacro(Direction, int); itkSetMacro(Direction, int); + + // Get results + void GetOutputSlices(std::vector & o); protected: ExtractSliceFilter(); @@ -97,9 +100,14 @@ namespace clitk { virtual void GenerateInputRequestedRegion(); virtual void GenerateData(); + int m_NumberOfSlices; ImagePointer input; ImagePointer object; - std::vector output; + SliceType * output; + + RegionType m_region; + SizeType m_size; + IndexType m_index; private: ExtractSliceFilter(const Self&); //purposely not implemented diff --git a/itk/clitkExtractSliceFilter.txx b/itk/clitkExtractSliceFilter.txx index 40f7982..594fa10 100644 --- a/itk/clitkExtractSliceFilter.txx +++ b/itk/clitkExtractSliceFilter.txx @@ -19,13 +19,15 @@ // clitk #include "clitkCommon.h" +// itk +#include //-------------------------------------------------------------------- template clitk::ExtractSliceFilter:: ExtractSliceFilter(): clitk::FilterBase(), - itk::ImageToImageFilter() + Superclass() { this->SetNumberOfRequiredInputs(1); SetDirection(2); @@ -37,35 +39,45 @@ ExtractSliceFilter(): template void clitk::ExtractSliceFilter:: -SetInput(const ImageType * image) { +SetInput(const ImageType * image) +{ // Process object is not const-correct so the const casting is required. this->SetNthInput(0, const_cast(image)); } //-------------------------------------------------------------------- +//-------------------------------------------------------------------- +template +void +clitk::ExtractSliceFilter:: +GetOutputSlices(std::vector & o) +{ + DD("GetOutputSlices"); + o.clear(); + for(unsigned int i=0; iGetNumberOfOutputs(); i++) { + o.push_back(this->GetOutput(i)); + // writeImage(this->GetOutput(i), "extractB"+clitk::toString(i)+".mhd"); + } +} +//-------------------------------------------------------------------- + + //-------------------------------------------------------------------- template void clitk::ExtractSliceFilter:: -GenerateOutputInformation() { +GenerateOutputInformation() +{ DD("GenerateOutputInformation"); ImagePointer input = dynamic_cast(itk::ProcessObject::GetInput(0)); - // ImagePointer outputImage = this->GetOutput(0); - // outputImage->SetRegions(input->GetLargestPossibleRegion()); - - output = this->GetOutput(0); - // create vector - typename SliceType::RegionType SliceRegionType; - typename SliceType::SizeType SliceSizeType; - typename SliceType::IndexType SliceIndexType; - // SliceRegionType region; - - // create region - // loop ExtractImageFilter with region updated, push_back - - + // Create region to extract + m_region = input->GetLargestPossibleRegion(); + m_size = m_region.GetSize(); + m_index = m_region.GetIndex(); + m_NumberOfSlices = m_region.GetSize()[GetDirection()]; + DD(m_NumberOfSlices); } //-------------------------------------------------------------------- @@ -77,7 +89,7 @@ clitk::ExtractSliceFilter:: GenerateInputRequestedRegion() { DD("GenerateInputRequestedRegion"); // Call default - itk::ImageToImageFilter::GenerateInputRequestedRegion(); + Superclass::GenerateInputRequestedRegion(); // Get input pointers and set requested region to common region ImagePointer input = dynamic_cast(itk::ProcessObject::GetInput(0)); input->SetRequestedRegion(input->GetLargestPossibleRegion()); @@ -91,15 +103,53 @@ clitk::ExtractSliceFilter:: GenerateData() { DD("GenerateData"); + //-------------------------------------------------------------------- // Get input pointer input = dynamic_cast(itk::ProcessObject::GetInput(0)); - + //-------------------------------------------------------------------- + // Create region to extract in 3D (and 2D = not used) + m_size[GetDirection()] = 0; + m_region.SetSize(m_size); + int start = m_index[GetDirection()]; + DD(start); + this->SetNumberOfOutputs(m_NumberOfSlices); + /* + typename SliceType::RegionType regionSlice; + typename SliceType::SizeType sizeSlice; + typename SliceType::IndexType indexSlice; + int j=0; + for(int i=0; i set output - //this->SetNthOutput(0, working_image); + // loop ExtractImageFilter with region updated, push_back + typedef itk::ExtractImageFilter ExtractImageFilterType; + typename ExtractImageFilterType::Pointer extract = ExtractImageFilterType::New(); + extract->SetInput(input); + for(int i=0; iSetInput(input); + // DD(i); + m_index[GetDirection()] = start + i; + m_region.SetIndex(m_index); + // DD(m_region); + extract->SetExtractionRegion(m_region); + extract->Update(); + // DD("set output"); + SetNthOutput(i, extract->GetOutput()); + // writeImage(extract->GetOutput(), "extractA"+clitk::toString(i)+".mhd"); + } + return; } //-------------------------------------------------------------------- diff --git a/itk/clitkSliceBySliceRelativePositionFilter.h b/itk/clitkSliceBySliceRelativePositionFilter.h index 01f9cd9..219f867 100644 --- a/itk/clitkSliceBySliceRelativePositionFilter.h +++ b/itk/clitkSliceBySliceRelativePositionFilter.h @@ -21,6 +21,7 @@ // clitk #include "clitkFilterBase.h" +#include "clitkAddRelativePositionConstraintToLabelImageFilter.h" namespace clitk { @@ -38,7 +39,7 @@ namespace clitk { public: /** Standard class typedefs. */ - typedef itk::ImageToImageFilter Superclass; + typedef itk::ImageToImageFilter Superclass; typedef SliceBySliceRelativePositionFilter Self; typedef itk::SmartPointer Pointer; typedef itk::SmartPointer ConstPointer; @@ -50,6 +51,10 @@ namespace clitk { itkTypeMacro(SliceBySliceRelativePositionFilter, ImageToImageFilter); FILTERBASE_INIT; + /** ImageDimension constants */ + itkStaticConstMacro(ImageDimension, unsigned int, ImageType::ImageDimension); + typedef itk::Image FloatImageType; + /** Some convenient typedefs. */ typedef typename ImageType::ConstPointer ImageConstPointer; typedef typename ImageType::Pointer ImagePointer; @@ -57,11 +62,10 @@ namespace clitk { typedef typename ImageType::PixelType PixelType; typedef typename ImageType::SpacingType SpacingType; typedef typename ImageType::SizeType SizeType; + typedef itk::Image SliceType; + typedef clitk::AddRelativePositionConstraintToLabelImageFilter RelPosFilterType; + typedef typename RelPosFilterType::OrientationTypeEnumeration OrientationTypeEnumeration; - /** ImageDimension constants */ - itkStaticConstMacro(ImageDimension, unsigned int, ImageType::ImageDimension); - typedef itk::Image FloatImageType; - /** Input : initial image and object */ void SetInput(const ImageType * image); void SetInputObject(const ImageType * image); @@ -72,12 +76,26 @@ namespace clitk { itkGetConstMacro(ObjectBackgroundValue, PixelType); itkSetMacro(ObjectBackgroundValue, PixelType); + itkSetMacro(OrientationType, OrientationTypeEnumeration); + itkGetConstMacro(OrientationType, OrientationTypeEnumeration); + itkGetConstMacro(ResampleBeforeRelativePositionFilter, bool); + itkSetMacro(ResampleBeforeRelativePositionFilter, bool); + itkBooleanMacro(ResampleBeforeRelativePositionFilter); + itkGetConstMacro(IntermediateSpacing, double); + itkSetMacro(IntermediateSpacing, double); + itkGetConstMacro(FuzzyThreshold, double); + itkSetMacro(FuzzyThreshold, double); + protected: SliceBySliceRelativePositionFilter(); virtual ~SliceBySliceRelativePositionFilter() {} int m_Direction; PixelType m_ObjectBackgroundValue; + OrientationTypeEnumeration m_OrientationType; + double m_IntermediateSpacing; + double m_FuzzyThreshold; + bool m_ResampleBeforeRelativePositionFilter; virtual void GenerateOutputInformation(); virtual void GenerateInputRequestedRegion(); diff --git a/itk/clitkSliceBySliceRelativePositionFilter.txx b/itk/clitkSliceBySliceRelativePositionFilter.txx index af9c4c5..6cea983 100644 --- a/itk/clitkSliceBySliceRelativePositionFilter.txx +++ b/itk/clitkSliceBySliceRelativePositionFilter.txx @@ -18,24 +18,8 @@ // clitk #include "clitkSegmentationUtils.h" -// #include "clitkBooleanOperatorLabelImageFilter.h" -// #include "clitkAutoCropFilter.h" -// #include "clitkResampleImageWithOptionsFilter.h" -// #include "clitkBooleanOperatorLabelImageFilter.h" #include "clitkExtractSliceFilter.h" -// // itk -// #include -// #include "itkStatisticsLabelMapFilter.h" -// #include "itkLabelImageToStatisticsLabelMapFilter.h" -// #include "itkRegionOfInterestImageFilter.h" -// #include "itkBinaryThresholdImageFilter.h" -// #include "itkBinaryErodeImageFilter.h" -// #include "itkBinaryBallStructuringElement.h" - -// // itk [Bloch et al] -// #include "RelativePositionPropImageFilter.h" - //-------------------------------------------------------------------- template clitk::SliceBySliceRelativePositionFilter:: @@ -45,7 +29,11 @@ SliceBySliceRelativePositionFilter(): { this->SetNumberOfRequiredInputs(2); SetDirection(2); - SetObjectBackgroundValue(0); + SetObjectBackgroundValue(0); + SetFuzzyThreshold(0.6); + SetOrientationType(RelPosFilterType::LeftTo); + SetIntermediateSpacing(10); + ResampleBeforeRelativePositionFilterOff(); } //-------------------------------------------------------------------- @@ -54,7 +42,8 @@ SliceBySliceRelativePositionFilter(): template void clitk::SliceBySliceRelativePositionFilter:: -SetInput(const ImageType * image) { +SetInput(const ImageType * image) +{ // Process object is not const-correct so the const casting is required. this->SetNthInput(0, const_cast(image)); } @@ -65,7 +54,8 @@ SetInput(const ImageType * image) { template void clitk::SliceBySliceRelativePositionFilter:: -SetInputObject(const ImageType * image) { +SetInputObject(const ImageType * image) +{ // Process object is not const-correct so the const casting is required. this->SetNthInput(1, const_cast(image)); } @@ -76,7 +66,8 @@ SetInputObject(const ImageType * image) { template void clitk::SliceBySliceRelativePositionFilter:: -GenerateOutputInformation() { +GenerateOutputInformation() +{ ImagePointer input = dynamic_cast(itk::ProcessObject::GetInput(0)); ImagePointer outputImage = this->GetOutput(0); outputImage->SetRegions(input->GetLargestPossibleRegion()); @@ -88,7 +79,8 @@ GenerateOutputInformation() { template void clitk::SliceBySliceRelativePositionFilter:: -GenerateInputRequestedRegion() { +GenerateInputRequestedRegion() +{ // Call default itk::ImageToImageFilter::GenerateInputRequestedRegion(); // Get input pointers and set requested region to common region @@ -104,7 +96,8 @@ GenerateInputRequestedRegion() { template void clitk::SliceBySliceRelativePositionFilter:: -GenerateData() { +GenerateData() +{ // Get input pointer input = dynamic_cast(itk::ProcessObject::GetInput(0)); object = dynamic_cast(itk::ProcessObject::GetInput(1)); @@ -133,66 +126,105 @@ GenerateData() { else { DD("no pad"); } - + /* + - extract vector of slices in input, in object + - slice by slice rel position + - joint result + - post process + */ //-------------------------------------------------------------------- // Extract input slices StartNewStep("Extract input slices"); + writeImage(input, "beforex.mhd"); typedef clitk::ExtractSliceFilter ExtractSliceFilterType; - typename ExtractSliceFilterType::Pointer extractSliceFilter = Extractslicefilter::New(); + typename ExtractSliceFilterType::Pointer extractSliceFilter = ExtractSliceFilterType::New(); extractSliceFilter->SetInput(input); extractSliceFilter->SetDirection(GetDirection()); extractSliceFilter->Update(); typedef typename ExtractSliceFilterType::SliceType SliceType; - std::vector & mInputSlices = extractSliceFilter->GetOutput(); + std::vector mInputSlices; + extractSliceFilter->GetOutputSlices(mInputSlices); DD(mInputSlices.size()); - StopCurrentStep(mInputSlices[5]); + StopCurrentStep(mInputSlices[0]); //-------------------------------------------------------------------- // Extract object slices - StartNewStep("Extract object slices"); - extractSliceFilter = Extractslicefilter::New(); - extractSliceFilter->SetInput(input); + extractSliceFilter = ExtractSliceFilterType::New(); + extractSliceFilter->SetInput(object); extractSliceFilter->SetDirection(GetDirection()); extractSliceFilter->Update(); - std::vector & mObjectSlices = extractSliceFilter->GetOutput(); + std::vector mObjectSlices; + extractSliceFilter->GetOutputSlices(mObjectSlices); DD(mObjectSlices.size()); - StopCurrentStep(mInputSlices[5]); + StopCurrentStep(mObjectSlices[0]); - //-------------------------------------------------------------------- // Perform slice by slice relative position StartNewStep("Perform slice by slice relative position"); - for(int i=0; iGetOrigin()); + // writeImage(mInputSlices[i], "inp"+clitk::toString(i)+".mhd"); + + // Select main CC in each object slice : this should be the main bronchus + mObjectSlices[i] = Labelize(mObjectSlices[i], 0, true, 1); + mObjectSlices[i] = KeepLabels(mObjectSlices[i], 0, 1, 1, 1, true); + + // Relative position typedef clitk::AddRelativePositionConstraintToLabelImageFilter RelPosFilterType; typename RelPosFilterType::Pointer relPosFilter = RelPosFilterType::New(); relPosFilter->VerboseStepOff(); relPosFilter->WriteStepOff(); + relPosFilter->SetCurrentStepBaseId(this->GetCurrentStepId()); relPosFilter->SetInput(mInputSlices[i]); relPosFilter->SetInputObject(mObjectSlices[i]); - relPosFilter->SetOrientationType(GetOrientationType()); - relPosFilter->SetIntermediateSpacing(GetIntermediateSpacing()); - relPosFilter->SetFuzzyThreshold(GetFuzzyThreshold()); + relPosFilter->SetOrientationType(this->GetOrientationType()); + relPosFilter->SetIntermediateSpacing(this->GetIntermediateSpacing()); + relPosFilter->SetResampleBeforeRelativePositionFilter(this->GetResampleBeforeRelativePositionFilter()); + relPosFilter->SetFuzzyThreshold(this->GetFuzzyThreshold()); + relPosFilter->AutoCropOff(); // important ! because we join the slices after this loop relPosFilter->Update(); + // writeImage(relPosFilter->GetOutput(), "inp-after"+clitk::toString(i)+".mhd"); mInputSlices[i] = relPosFilter->GetOutput(); } - typedef itk::JoinSeriesImageFilter JointSeriesFilterType; - typename JointSeriesFilterType::Pointer jointFilter = JointSeriesFilterType::New(); - for(int i=0; iSetInput(i, mInputSlices[i]); + DD(this->GetIntermediateSpacing()); + DD(this->GetResampleBeforeRelativePositionFilter()); + DD("End slice"); + + typedef itk::JoinSeriesImageFilter JoinSeriesFilterType; + typename JoinSeriesFilterType::Pointer joinFilter = JoinSeriesFilterType::New(); + joinFilter->SetOrigin(input->GetOrigin()[GetDirection()]); + joinFilter->SetSpacing(input->GetSpacing()[GetDirection()]); + for(unsigned int i=0; iGetLargestPossibleRegion().GetIndex()); +// DD(mInputSlices[i]->GetLargestPossibleRegion().GetSize()); +// DD(mInputSlices[i]->GetRequestedRegion().GetIndex()); +// DD(mInputSlices[i]->GetRequestedRegion().GetSize()); + joinFilter->PushBackInput(mInputSlices[i]); + //SetInput(i, mInputSlices[i]); } - m_working_input = jointFilter->GetOutput(); + DD("before update"); + joinFilter->Update(); + DD("after update"); + m_working_input = joinFilter->GetOutput(); + + // Update the origin + DD(input->GetSpacing()); + DD(input->GetOrigin()); + DD(mInputSlices[0]->GetSpacing()); + DD(mInputSlices[0]->GetOrigin()); DD(m_working_input->GetSpacing()); DD(m_working_input->GetOrigin()); + // typename ImageType::PointType origin = m_working_input->GetOrigin(); +// origin[GetDirection()] = input->GetOrigin()[GetDirection()]; +// m_working_input->SetOrigin(origin); +// DD(m_working_input->GetOrigin()); StopCurrentStep(m_working_input); - */ - - //-------------------------------------------------------------------- //-------------------------------------------------------------------- // Final Step -> set output diff --git a/segmentation/clitkExtractLungFilter.txx b/segmentation/clitkExtractLungFilter.txx index f291739..e4aa902 100644 --- a/segmentation/clitkExtractLungFilter.txx +++ b/segmentation/clitkExtractLungFilter.txx @@ -38,6 +38,7 @@ ExtractLungFilter(): clitk::FilterBase(), itk::ImageToImageFilter() { + SetNumberOfSteps(10); // Default global options this->SetNumberOfRequiredInputs(2); SetPatientMaskBackgroundValue(0); @@ -154,7 +155,6 @@ GenerateOutputInformation() { input = dynamic_cast(itk::ProcessObject::GetInput(0)); Superclass::GenerateOutputInformation(); -// MaskImagePointer output = this->GetOutput(0); // Get input pointers input = dynamic_cast(itk::ProcessObject::GetInput(0)); @@ -166,6 +166,9 @@ GenerateOutputInformation() return; } + // Set Number of steps + SetNumberOfSteps(9); + //-------------------------------------------------------------------- //-------------------------------------------------------------------- StartNewStep("Set background to initial image"); diff --git a/segmentation/clitkExtractLungGenericFilter.txx b/segmentation/clitkExtractLungGenericFilter.txx index 2bc8af8..77b4e8b 100644 --- a/segmentation/clitkExtractLungGenericFilter.txx +++ b/segmentation/clitkExtractLungGenericFilter.txx @@ -26,6 +26,7 @@ template clitk::ExtractLungGenericFilter::ExtractLungGenericFilter(): ImageToImageGenericFilter("ExtractLung") { + this->SetFilterBase(NULL); // Default values cmdline_parser_clitkExtractLung_init(&mArgsInfo); InitializeImageType<3>(); @@ -78,6 +79,9 @@ void clitk::ExtractLungGenericFilter::UpdateWithInputImageType() // Create filter typedef clitk::ExtractLungFilter FilterType; typename FilterType::Pointer filter = FilterType::New(); + + // Set the filter (needed for example for threaded monitoring) + this->SetFilterBase(filter); // Set global Options filter->SetArgsInfo(mArgsInfo); diff --git a/segmentation/clitkExtractLymphStations.ggo b/segmentation/clitkExtractLymphStations.ggo index 78efb35..28d78f6 100644 --- a/segmentation/clitkExtractLymphStations.ggo +++ b/segmentation/clitkExtractLymphStations.ggo @@ -17,8 +17,8 @@ option "mediastinum" m "Input mediastinum mask filename" string yes option "trachea" t "Input trachea mask filename" string yes option "output" o "Output lungs mask filename" string yes -option "carenaZposition" c "Sup-Inf position of the carena (in mm)" double no -option "middleLobeBronchusZposition" b "Sup-Inf position of the middle lobe bronchus (in mm)" double no +option "carenaZposition" c "Sup-Inf position of the carena (in mm, with origin)" double no +option "middleLobeBronchusZposition" b "Sup-Inf position of the middle lobe bronchus (in mm, with origin)" double no option "spacing" - "Intermediate resampling spacing" double no default="6" option "fuzzy1" - "Fuzzy relative position threshold" double no default="0.6" diff --git a/segmentation/clitkExtractLymphStationsFilter.txx b/segmentation/clitkExtractLymphStationsFilter.txx index 993d288..5994f8f 100644 --- a/segmentation/clitkExtractLymphStationsFilter.txx +++ b/segmentation/clitkExtractLymphStationsFilter.txx @@ -29,12 +29,12 @@ #include "clitkSliceBySliceRelativePositionFilter.h" // itk -#include #include #include #include #include #include +#include // itk ENST #include "RelativePositionPropImageFilter.h" @@ -119,7 +119,7 @@ GenerateOutputInformation() { // ---------------------------------------------------------------- // Superior limit = carena // Inferior limit = origine middle lobe bronchus - StartNewStep("Inf/Sup limits with carena/bronchus"); + StartNewStep("Inf/Sup mediastinum limits with carena/bronchus"); ImageRegionType region = m_mediastinum->GetLargestPossibleRegion(); DD(region); ImageSizeType size = region.GetSize(); ImageIndexType index = region.GetIndex(); @@ -144,7 +144,7 @@ GenerateOutputInformation() { // ---------------------------------------------------------------- // ---------------------------------------------------------------- // Separate trachea in two CCL - StartNewStep("Separate trachea"); + StartNewStep("Separate trachea under carena"); // DD(region); ImageRegionType trachea_region = m_trachea->GetLargestPossibleRegion(); for(int i=0; i<3; i++) { @@ -176,8 +176,7 @@ GenerateOutputInformation() { // Labelize and consider two main labels m_working_trachea = Labelize(m_working_trachea, 0, true, 1); - StopCurrentStep(m_working_trachea); - + // Detect wich label is at Left typedef itk::ImageSliceConstIteratorWithIndex SliceIteratorType; SliceIteratorType iter(m_working_trachea, m_working_trachea->GetLargestPossibleRegion()); @@ -186,6 +185,7 @@ GenerateOutputInformation() { iter.GoToBegin(); bool stop = false; ImagePixelType leftLabel; + ImagePixelType rightLabel; while (!stop) { if (iter.Get() != m_BackgroundValueTrachea) { // DD(iter.GetIndex()); @@ -195,62 +195,30 @@ GenerateOutputInformation() { } ++iter; } + if (leftLabel == 1) rightLabel = 2; + else rightLabel = 1; DD((int)leftLabel); - - /* - // Relative position - StartNewStep("Left/Right limits with trachea"); - - // Select LeftLabel (set label 1 to 0) - ImagePointer temp = SetBackground(m_working_trachea, m_working_trachea, 1, 0); - writeImage(temp, "temp1.mhd"); - - // Left relative position - typedef clitk::AddRelativePositionConstraintToLabelImageFilter RelPosFilterType; - typename RelPosFilterType::Pointer relPosFilter = RelPosFilterType::New(); - relPosFilter->SetCurrentStepBaseId(this->GetCurrentStepId()); - relPosFilter->VerboseStepOff(); - relPosFilter->WriteStepOff(); - relPosFilter->SetInput(m_working_image); - relPosFilter->SetInputObject(temp); - relPosFilter->SetOrientationType(RelPosFilterType::RightTo); - relPosFilter->SetIntermediateSpacing(GetIntermediateSpacing()); - relPosFilter->SetFuzzyThreshold(GetFuzzyThreshold1()); - relPosFilter->Update(); - m_working_image = relPosFilter->GetOutput(); - - // Select RightLabel (set label 2 to 0) - temp = SetBackground(m_working_trachea, m_working_trachea, 2, 0); - writeImage(temp, "temp2.mhd"); + DD((int)rightLabel); - // Left relative position - relPosFilter = RelPosFilterType::New(); - relPosFilter->SetCurrentStepBaseId(this->GetCurrentStepId()); - relPosFilter->VerboseStepOn(); - relPosFilter->WriteStepOn(); - relPosFilter->SetInput(m_working_image); - relPosFilter->SetInputObject(temp); - relPosFilter->SetOrientationType(RelPosFilterType::LeftTo); - relPosFilter->SetIntermediateSpacing(GetIntermediateSpacing()); - relPosFilter->SetFuzzyThreshold(GetFuzzyThreshold1()); - relPosFilter->Update(); - m_working_image = relPosFilter->GetOutput(); + // End step + StopCurrentStep(m_working_trachea); + + //----------------------------------------------------- + /* DD("TEST Skeleton"); + typedef itk::BinaryThinningImageFilter SkeletonFilterType; + typename SkeletonFilterType::Pointer skeletonFilter = SkeletonFilterType::New(); + skeletonFilter->SetInput(m_working_trachea); + skeletonFilter->Update(); + writeImage(skeletonFilter->GetOutput(), "skel.mhd"); + writeImage(skeletonFilter->GetThinning(), "skel2.mhd"); */ //----------------------------------------------------- - StartNewStep("Left/Right limits with trachea (slice by slice"); - - // Select LeftLabel (set label 1 to 0) - ImagePointer temp = SetBackground(m_working_trachea, m_working_trachea, 1, 0); + StartNewStep("Left limits with bronchus (slice by slice)"); + // Select LeftLabel (set right label to 0) + ImagePointer temp = SetBackground(m_working_trachea, m_working_trachea, rightLabel, 0); writeImage(temp, "temp1.mhd"); - /* - - écrire utilisation de filter SliceBySliceRelPosFilter (combine in a 3D) - - filter SliceBySliceRelPosFilter + combine in a 3D - - resampling, affine transfo to pair the slices - - extract list of images (ecrire utilisation de ExtractSliceFilter) - */ - typedef clitk::SliceBySliceRelativePositionFilter SliceRelPosFilterType; typename SliceRelPosFilterType::Pointer sliceRelPosFilter = SliceRelPosFilterType::New(); sliceRelPosFilter->SetCurrentStepBaseId(this->GetCurrentStepId()); @@ -259,79 +227,33 @@ GenerateOutputInformation() { sliceRelPosFilter->SetInput(m_working_image); sliceRelPosFilter->SetInputObject(temp); sliceRelPosFilter->SetDirection(2); + sliceRelPosFilter->SetFuzzyThreshold(0.8); + sliceRelPosFilter->SetOrientationType(SliceRelPosFilterType::RelPosFilterType::RightTo); sliceRelPosFilter->Update(); m_working_image = sliceRelPosFilter->GetOutput(); writeImage(m_working_image, "afterslicebyslice.mhd"); - /* - - itk::ImageSliceConstIteratorWithIndex it(temp, temp->GetRequestedRegion()); - itk::ImageRegionIterator * ot; - typename SliceType::Pointer slice; - it.SetFirstDirection(0); - it.SetSecondDirection(1); - it.GoToBegin(); - typename SliceType::RegionType mSliceRegion; - typename SliceType::IndexType mSliceIndex; - typename SliceType::SizeType mSliceSize; - typename SliceType::SpacingType mSliceSpacing; - typename SliceType::PointType mSliceOrigin; - mSliceIndex[0] = temp->GetLargestPossibleRegion().GetIndex()[0]; - mSliceIndex[1] = temp->GetLargestPossibleRegion().GetIndex()[1]; - mSliceSize[0] = temp->GetLargestPossibleRegion().GetSize()[0]; - mSliceSize[1] = temp->GetLargestPossibleRegion().GetSize()[1]; - mSliceSpacing[0] = temp->GetSpacing()[0]; - mSliceSpacing[1] = temp->GetSpacing()[1]; - mSliceOrigin[0] = temp->GetOrigin()[0]; - mSliceOrigin[1] = temp->GetOrigin()[1]; - mSliceRegion.SetIndex(mSliceIndex); - mSliceRegion.SetSize(mSliceSize); - int i=0; - while( !it.IsAtEnd() ) { - // DD(i); - slice = SliceType::New(); - slice->SetRegions(mSliceRegion); - slice->SetOrigin(mSliceOrigin); - slice->SetSpacing(mSliceSpacing); - slice->Allocate(); - ot = new itk::ImageRegionIterator(slice, slice->GetLargestPossibleRegion()); - ot->GoToBegin(); - // DD(it.GetIndex()); - while(!it.IsAtEndOfSlice()) { - // DD(ot->GetIndex()); - while(!it.IsAtEndOfLine()) { - ot->Set(it.Get()); - ++it; - ++(*ot); - } - it.NextLine(); - } - mImageSlices.push_back(slice); - it.NextSlice(); - ++i; - } - writeImage(mImageSlices[10], "slice.mhd"); - - // Perform RelPos by slice - for(int i=0; i RelPosFilterType; - typename RelPosFilterType::Pointer relPosFilter = RelPosFilterType::New(); - // relPosFilter->SetCurrentStepBaseId(this->GetCurrentStepId()); - relPosFilter->VerboseStepOff(); - relPosFilter->WriteStepOff(); - relPosFilter->SetInput(m_working_image); - relPosFilter->SetInputObject(temp); - relPosFilter->SetOrientationType(RelPosFilterType::RightTo); - relPosFilter->SetIntermediateSpacing(GetIntermediateSpacing()); - relPosFilter->SetFuzzyThreshold(GetFuzzyThreshold1()); - relPosFilter->Update(); - m_working_image = relPosFilter->GetOutput(); - } + //----------------------------------------------------- + StartNewStep("Right limits with bronchus (slice by slice)"); + // Select LeftLabel (set right label to 0) + temp = SetBackground(m_working_trachea, m_working_trachea, leftLabel, 0); + writeImage(temp, "temp2.mhd"); + + sliceRelPosFilter = SliceRelPosFilterType::New(); + sliceRelPosFilter->SetCurrentStepBaseId(this->GetCurrentStepId()); + sliceRelPosFilter->VerboseStepOn(); + sliceRelPosFilter->WriteStepOn(); + sliceRelPosFilter->SetInput(m_working_image); + sliceRelPosFilter->SetInputObject(temp); + sliceRelPosFilter->SetDirection(2); + sliceRelPosFilter->SetFuzzyThreshold(0.8); + sliceRelPosFilter->SetOrientationType(SliceRelPosFilterType::RelPosFilterType::LeftTo); + sliceRelPosFilter->Update(); + m_working_image = sliceRelPosFilter->GetOutput(); + writeImage(m_working_image, "afterslicebyslice.mhd"); + - */ - DD("end"); m_output = m_working_image; StopCurrentStep(m_output);