#define CLITKCOMMONGENERICFILTER_H
#include "clitkCommon.h"
+#include "clitkFilterBase.h"
/*--------------------------------------------------------------------
DISCLAIMER : I obviously know how to make this mess much clearer and
mMapOfImageTypeToFunction[dim][ncomp][pixelname]->Execute();
}
template<unsigned int Dim, unsigned int NComp, class PixelType>
- void AddNewDimensionAndPixelType() {
+ void AddNewDimensionAndPixelType() {
typedef itk::Image<itk::Vector<PixelType,NComp>,Dim> InputImageType;
mMapOfImageTypeToFunction[Dim][NComp][ GetTypeAsString<PixelType>() ] =
new GenericFilterFunctorWithDimAndPixelType<FilterType, InputImageType>(mFilter);
}
/// Specialization for NComp == 1
template<unsigned int Dim, class PixelType>
- void AddNewDimensionAndPixelType() {
+ void AddNewDimensionAndPixelType() {
typedef itk::Image<PixelType,Dim> InputImageType;
mMapOfImageTypeToFunction[Dim][1][ GetTypeAsString<PixelType>() ] =
new GenericFilterFunctorWithDimAndPixelType<FilterType, InputImageType>(mFilter);
//--------------------------------------------------------------------
clitk::FilterBase::FilterBase()
{
+ m_MustStop = false;
SetVerboseOption(false);
SetCurrentStepNumber(0);
SetCurrentStepBaseId("");
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;
}
}
//--------------------------------------------------------------------
}
//--------------------------------------------------------------------
+
+//--------------------------------------------------------------------
+void clitk::FilterBase::MustStop()
+{
+ m_MustStop = true;
+}
+//--------------------------------------------------------------------
+
+
GGO_DefineOption_Flag(verboseOption, SetVerboseOption);
// Steps management
+ itkSetMacro(NumberOfSteps, int);
+ itkGetConstMacro(NumberOfSteps, int);
itkSetMacro(VerboseStep, bool);
itkGetConstMacro(VerboseStep, bool);
itkBooleanMacro(VerboseStep);
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<class OptionType>
itkBooleanMacro(VerboseWarningOff);
GGO_DefineOption_Flag(verboseWarningOff, SetVerboseWarningOff);
+ // Use this function to stop (when threaded)
+ void MustStop();
+
protected:
FilterBase();
virtual ~FilterBase() {}
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
- 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 <itkImage.h>
//--------------------------------------------------------------------
- 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
#include "clitkCommon.h"
#include "clitkImageCommon.h"
#include "clitkCommonGenericFilter.h"
+#include "clitkFilterBase.h"
// itk
#include <itkImage.h>
/// 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);
// 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
bool m_FailOnImageTypeError;
std::string m_LastError;
+ void SetFilterBase(FilterBase * f) { m_FilterBase = f; }
+ FilterBase * m_FilterBase;
}; // end class clitk::ImageToImageGenericFilter
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"
{
-/** \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 TInputImage, class TOutputImage, class TtNorm=Function::Minimum<
- typename TOutputImage::PixelType,
- typename TOutputImage::PixelType,
- typename TOutputImage::PixelType> >
-class ITK_EXPORT RelativePositionPropImageFilter :
+ template <class TInputImage, class TOutputImage, class TtNorm=Function::Minimum<
+ typename TOutputImage::PixelType,
+ typename TOutputImage::PixelType,
+ typename TOutputImage::PixelType> >
+ class ITK_EXPORT RelativePositionPropImageFilter :
public ImageToImageFilter< TInputImage, TOutputImage >
-{
-public:
- /** Standard class typedefs. */
- typedef RelativePositionPropImageFilter Self;
- typedef ImageToImageFilter< TInputImage, TOutputImage > Superclass;
- typedef SmartPointer<Self> Pointer;
- typedef SmartPointer<const Self> 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<Self> Pointer;
+ typedef SmartPointer<const Self> 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<typename TInputImage::IndexType , ImageDimension>
- CorrespondanceMapType;
- typedef float TabulationPixelType;
- typedef typename itk::Image<TabulationPixelType , ImageDimension> TabulationImageType;
+ typedef typename itk::Image<typename TInputImage::IndexType , ImageDimension>
+ CorrespondanceMapType;
+ typedef float TabulationPixelType;
+ typedef typename itk::Image<TabulationPixelType , ImageDimension> 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<double, ImageDimension> VectorType;
+ typedef itk::Vector<double, ImageDimension> 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<OutputPixelType>));
+ /** The output pixel type must be signed. */
+ itkConceptMacro(SignedOutputPixelType, (Concept::Signed<OutputPixelType>));
- /** 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
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.
=========================================================================*/
#ifndef _RelativePositionPropImageFilter_txx
#define _RelativePositionPropImageFilter_txx
+
#include "RelativePositionPropImageFilter.h"
#include "itkNeighborhoodOperatorImageFilter.h"
#include "itkZeroFluxNeumannBoundaryCondition.h"
#include "itkProgressAccumulator.h"
#include "itkImageFileWriter.h"
-
#include "itkSimpleContourExtractorImageFilter.h"
#include "itkUnaryFunctorImageFilter.h"
*/
//--------------------------------------------------------------------
- template <class TImageType>
+ template <class ImageType>
class ITK_EXPORT AddRelativePositionConstraintToLabelImageFilter:
public clitk::FilterBase,
- public itk::ImageToImageFilter<TImageType, TImageType>
+ public itk::ImageToImageFilter<ImageType, ImageType>
{
public:
/** Standard class typedefs. */
- typedef itk::ImageToImageFilter<TImageType, TImageType> Superclass;
+ typedef itk::ImageToImageFilter<ImageType, ImageType> Superclass;
typedef AddRelativePositionConstraintToLabelImageFilter Self;
typedef itk::SmartPointer<Self> Pointer;
typedef itk::SmartPointer<const Self> ConstPointer;
FILTERBASE_INIT;
/** Some convenient typedefs. */
- typedef TImageType ImageType;
typedef typename ImageType::ConstPointer ImageConstPointer;
typedef typename ImageType::Pointer ImagePointer;
typedef typename ImageType::RegionType RegionType;
typedef typename ImageType::SizeType SizeType;
/** ImageDimension constants */
- itkStaticConstMacro(ImageDimension, unsigned int, TImageType::ImageDimension);
+ itkStaticConstMacro(ImageDimension, unsigned int, ImageType::ImageDimension);
typedef itk::Image<float, ImageDimension> FloatImageType;
/** Orientation types */
// 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() {}
double m_Angle1;
double m_Angle2;
bool m_ResampleBeforeRelativePositionFilter;
+ bool m_AutoCrop;
virtual void GenerateOutputInformation();
virtual void GenerateInputRequestedRegion();
#include "RelativePositionPropImageFilter.h"
//--------------------------------------------------------------------
-template <class TImageType>
-clitk::AddRelativePositionConstraintToLabelImageFilter<TImageType>::
+template <class ImageType>
+clitk::AddRelativePositionConstraintToLabelImageFilter<ImageType>::
AddRelativePositionConstraintToLabelImageFilter():
clitk::FilterBase(),
- itk::ImageToImageFilter<TImageType, TImageType>()
+ itk::ImageToImageFilter<ImageType, ImageType>()
{
this->SetNumberOfRequiredInputs(2);
SetFuzzyThreshold(0.6);
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 <class TImageType>
+template <class ImageType>
void
-clitk::AddRelativePositionConstraintToLabelImageFilter<TImageType>::
-SetInput(const ImageType * image) {
+clitk::AddRelativePositionConstraintToLabelImageFilter<ImageType>::
+SetInput(const ImageType * image)
+{
// Process object is not const-correct so the const casting is required.
this->SetNthInput(0, const_cast<ImageType *>(image));
}
//--------------------------------------------------------------------
-template <class TImageType>
+template <class ImageType>
void
-clitk::AddRelativePositionConstraintToLabelImageFilter<TImageType>::
-SetInputObject(const ImageType * image) {
+clitk::AddRelativePositionConstraintToLabelImageFilter<ImageType>::
+SetInputObject(const ImageType * image)
+{
// Process object is not const-correct so the const casting is required.
this->SetNthInput(1, const_cast<ImageType *>(image));
}
//--------------------------------------------------------------------
-template <class TImageType>
+template <class ImageType>
void
-clitk::AddRelativePositionConstraintToLabelImageFilter<TImageType>::
-GenerateOutputInformation() {
- ImagePointer input = dynamic_cast<TImageType*>(itk::ProcessObject::GetInput(0));
+clitk::AddRelativePositionConstraintToLabelImageFilter<ImageType>::
+GenerateOutputInformation()
+{
+ ImagePointer input = dynamic_cast<ImageType*>(itk::ProcessObject::GetInput(0));
ImagePointer outputImage = this->GetOutput(0);
outputImage->SetRegions(outputImage->GetLargestPossibleRegion());
}
//--------------------------------------------------------------------
-template <class TImageType>
+template <class ImageType>
void
-clitk::AddRelativePositionConstraintToLabelImageFilter<TImageType>::
-GenerateInputRequestedRegion() {
+clitk::AddRelativePositionConstraintToLabelImageFilter<ImageType>::
+GenerateInputRequestedRegion()
+{
// Call default
- itk::ImageToImageFilter<TImageType, TImageType>::GenerateInputRequestedRegion();
+ itk::ImageToImageFilter<ImageType, ImageType>::GenerateInputRequestedRegion();
// Get input pointers and set requested region to common region
- ImagePointer input1 = dynamic_cast<TImageType*>(itk::ProcessObject::GetInput(0));
- ImagePointer input2 = dynamic_cast<TImageType*>(itk::ProcessObject::GetInput(1));
+ ImagePointer input1 = dynamic_cast<ImageType*>(itk::ProcessObject::GetInput(0));
+ ImagePointer input2 = dynamic_cast<ImageType*>(itk::ProcessObject::GetInput(1));
input1->SetRequestedRegion(input1->GetLargestPossibleRegion());
input2->SetRequestedRegion(input2->GetLargestPossibleRegion());
}
//--------------------------------------------------------------------
-template <class TImageType>
+template <class ImageType>
void
-clitk::AddRelativePositionConstraintToLabelImageFilter<TImageType>::
-SetAngle1(double a) {
+clitk::AddRelativePositionConstraintToLabelImageFilter<ImageType>::
+SetAngle1(double a)
+{
SetOrientationType(Angle);
m_Angle1 = a;
}
//--------------------------------------------------------------------
-template <class TImageType>
+template <class ImageType>
void
-clitk::AddRelativePositionConstraintToLabelImageFilter<TImageType>::
-SetAngle2(double a) {
+clitk::AddRelativePositionConstraintToLabelImageFilter<ImageType>::
+SetAngle2(double a)
+{
SetOrientationType(Angle);
m_Angle2 = a;
}
//--------------------------------------------------------------------
-template <class TImageType>
+template <class ImageType>
void
-clitk::AddRelativePositionConstraintToLabelImageFilter<TImageType>::
-SetOrientationType(OrientationTypeEnumeration orientation) {
+clitk::AddRelativePositionConstraintToLabelImageFilter<ImageType>::
+SetOrientationType(OrientationTypeEnumeration orientation)
+{
m_OrientationType = orientation;
switch (m_OrientationType) {
case LeftTo: m_Angle1 = clitk::deg2rad(0); m_Angle2 = clitk::deg2rad(0); break;
//--------------------------------------------------------------------
-template <class TImageType>
+template <class ImageType>
void
-clitk::AddRelativePositionConstraintToLabelImageFilter<TImageType>::
-GenerateData() {
+clitk::AddRelativePositionConstraintToLabelImageFilter<ImageType>::
+GenerateData()
+{
// Get input pointer
input = dynamic_cast<ImageType*>(itk::ProcessObject::GetInput(0));
object = dynamic_cast<ImageType*>(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<ImageType> ResampleFilterType;
}
else {
working_image = object;
- }
- // writeImage<ImageType>(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
typename PadFilterType::Pointer padFilter = PadFilterType::New();
typename PadFilterType::InputImageIndexType index;
for(unsigned int i=0; i<dim; i++) {
- index[i] = lrint((working_image->GetOrigin()[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);
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<ImageType>(working_image, "pad.mhd");
+ StopCurrentStep<ImageType>(working_image);
// Step 3: compute rel pos in object
+ StartNewStep("Relative Position Map");
typedef itk::RelativePositionPropImageFilter<ImageType, FloatImageType> RelPosFilterType;
typename RelPosFilterType::Pointer relPosFilter = RelPosFilterType::New();
relPosFilter->SetInput(working_image);
// relPosFilter->SetVerboseProgress(true);
relPosFilter->Update();
relPos = relPosFilter->GetOutput();
- this->template StopCurrentStep<FloatImageType>(relPos);
+ StopCurrentStep<FloatImageType>(relPos);
//--------------------------------------------------------------------
//--------------------------------------------------------------------
- StartNewStep("Map Threshold And Post Processing");
-
+ StartNewStep("Map Threshold");
// Step 1: threshold
typedef itk::BinaryThresholdImageFilter<FloatImageType, ImageType> BinaryThresholdImageFilterType;
typename BinaryThresholdImageFilterType::Pointer thresholdFilter = BinaryThresholdImageFilterType::New();
thresholdFilter->SetLowerThreshold(m_FuzzyThreshold);
thresholdFilter->Update();
working_image = thresholdFilter->GetOutput();
+ StopCurrentStep<ImageType>(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<unsigned int, 3> StructuringElementType;
+ typedef itk::BinaryBallStructuringElement<unsigned int, ImageDimension> StructuringElementType;
StructuringElementType kernel;
kernel.SetRadius(1);
kernel.CreateStructuringElement();
erodeFilter->SetErodeValue(m_BackgroundValue+1);
erodeFilter->Update();
working_image = erodeFilter->GetOutput();
+ StopCurrentStep<ImageType>(working_image);
+ //--------------------------------------------------------------------
+ //--------------------------------------------------------------------
// Step 5: resample to initial spacing
if (m_ResampleBeforeRelativePositionFilter) {
+ StartNewStep("Resample to get the same sampling than input");
typedef clitk::ResampleImageWithOptionsFilter<ImageType> ResampleFilterType;
typename ResampleFilterType::Pointer resampleFilter = ResampleFilterType::New();
resampleFilter->SetDefaultPixelValue(m_BackgroundValue);
// resampleFilter->SetVerboseOptions(true);
resampleFilter->Update();
working_image = resampleFilter->GetOutput();
+ StopCurrentStep<ImageType>(working_image);
}
- // writeImage<ImageType>(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 !!
padFilter2->SetSourceRegion(working_image->GetLargestPossibleRegion());
padFilter2->Update();
working_image = padFilter2->GetOutput();
+ StopCurrentStep<ImageType>(working_image);
}
else {
- DD("[debug] Rel Pos : no padding after");
+ //DD("[debug] Rel Pos : no padding after");
}
- // writeImage<ImageType>(working_image, "pad2.mhd");
+ //--------------------------------------------------------------------
+ //--------------------------------------------------------------------
// Step 6: combine input+thresholded relpos
+ StartNewStep("Combine with initial input (boolean And)");
typedef clitk::BooleanOperatorLabelImageFilter<ImageType> BoolFilterType;
typename BoolFilterType::Pointer combineFilter = BoolFilterType::New();
+ writeImage<ImageType>(input, "i.mhd");
+ writeImage<ImageType>(working_image, "w.mhd");
combineFilter->SetBackgroundValue(m_BackgroundValue);
combineFilter->SetBackgroundValue1(m_BackgroundValue);
combineFilter->SetBackgroundValue2(m_BackgroundValue);
combineFilter->InPlaceOn();
combineFilter->Update();
working_image = combineFilter->GetOutput();
+ // writeImage<ImageType>(working_image, "res.mhd");
combineFilter = BoolFilterType::New();
combineFilter->SetInput1(working_image);
combineFilter->Update();
working_image = combineFilter->GetOutput();
- // writeImage<ImageType>(working_image, "combine.mhd");
+ StopCurrentStep<ImageType>(working_image);
+ //--------------------------------------------------------------------
+ //--------------------------------------------------------------------
// Step 7: autocrop
- typedef clitk::AutoCropFilter<ImageType> CropFilterType;
- typename CropFilterType::Pointer cropFilter = CropFilterType::New();
- cropFilter->SetInput(working_image);
- cropFilter->ReleaseDataFlagOff();
- cropFilter->Update();
- working_image = cropFilter->GetOutput();
- this->template StopCurrentStep<ImageType>(working_image);
+ if (GetAutoCrop()) {
+ StartNewStep("Final AutoCrop");
+ typedef clitk::AutoCropFilter<ImageType> CropFilterType;
+ typename CropFilterType::Pointer cropFilter = CropFilterType::New();
+ cropFilter->SetInput(working_image);
+ cropFilter->ReleaseDataFlagOff();
+ cropFilter->Update();
+ working_image = cropFilter->GetOutput();
+ StopCurrentStep<ImageType>(working_image);
+ }
//--------------------------------------------------------------------
//--------------------------------------------------------------------
typename ImageToMapFilterType::Pointer imageToLabelFilter = ImageToMapFilterType::New();
imageToLabelFilter->SetBackgroundValue(m_BackgroundValue);
imageToLabelFilter->SetInput(input);
+ DD(input->GetLargestPossibleRegion());
// AutoCrop
typedef itk::AutoCropLabelMapFilter<LabelMapType> AutoCropFilterType;
typename AutoCropFilterType::Pointer autoCropFilter = AutoCropFilterType::New();
autoCropFilter->SetInput(imageToLabelFilter->GetOutput());
-
+
// Convert to LabelImage
typedef itk::LabelMapToLabelImageFilter<LabelMapType, ImageType> MapToImageFilterType;
typename MapToImageFilterType::Pointer labelToImageFilter = MapToImageFilterType::New();
// 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);
void
AutoCropFilter<ImageType>::
GenerateData() {
- DD("AutoCropFilter::GenerateData");
// Get input pointers
ImageConstPointer input = dynamic_cast<const ImageType*>(itk::ProcessObject::GetInput(0));
class ITK_EXPORT ExtractSliceFilter:
public clitk::FilterBase,
public itk::ImageToImageFilter<ImageType,
- std::vector<typename itk::Image<typename ImageType::PixelType,
- ImageType::ImageDimension-1>::Pointer> >
+ typename itk::Image<typename ImageType::PixelType, ImageType::ImageDimension-1> >
{
public:
- /** Standard class typedefs. */
- typedef itk::ImageToImageFilter<ImageType, ImageType> Superclass;
- typedef ExtractSliceFilter Self;
- 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(ExtractSliceFilter, ImageToImageFilter);
- FILTERBASE_INIT;
-
/** Some convenient typedefs. */
typedef typename ImageType::ConstPointer ImageConstPointer;
typedef typename ImageType::Pointer ImagePointer;
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);
typedef itk::Image<PixelType, ImageDimension-1> SliceType;
typedef typename SliceType::Pointer SliceTypePointer;
+ /** Standard class typedefs. */
+ typedef itk::ImageToImageFilter<ImageType, SliceType> Superclass;
+ typedef ExtractSliceFilter Self;
+ 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(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<typename SliceType::Pointer> & o);
protected:
ExtractSliceFilter();
virtual void GenerateInputRequestedRegion();
virtual void GenerateData();
+ int m_NumberOfSlices;
ImagePointer input;
ImagePointer object;
- std::vector<SliceTypePointer> output;
+ SliceType * output;
+
+ RegionType m_region;
+ SizeType m_size;
+ IndexType m_index;
private:
ExtractSliceFilter(const Self&); //purposely not implemented
// clitk
#include "clitkCommon.h"
+// itk
+#include <itkExtractImageFilter.h>
//--------------------------------------------------------------------
template <class ImageType>
clitk::ExtractSliceFilter<ImageType>::
ExtractSliceFilter():
clitk::FilterBase(),
- itk::ImageToImageFilter<ImageType, ImageType>()
+ Superclass()
{
this->SetNumberOfRequiredInputs(1);
SetDirection(2);
template <class ImageType>
void
clitk::ExtractSliceFilter<ImageType>::
-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<ImageType *>(image));
}
//--------------------------------------------------------------------
+//--------------------------------------------------------------------
+template <class ImageType>
+void
+clitk::ExtractSliceFilter<ImageType>::
+GetOutputSlices(std::vector<typename SliceType::Pointer> & o)
+{
+ DD("GetOutputSlices");
+ o.clear();
+ for(unsigned int i=0; i<this->GetNumberOfOutputs(); i++) {
+ o.push_back(this->GetOutput(i));
+ // writeImage<SliceType>(this->GetOutput(i), "extractB"+clitk::toString(i)+".mhd");
+ }
+}
+//--------------------------------------------------------------------
+
+
//--------------------------------------------------------------------
template <class ImageType>
void
clitk::ExtractSliceFilter<ImageType>::
-GenerateOutputInformation() {
+GenerateOutputInformation()
+{
DD("GenerateOutputInformation");
ImagePointer input = dynamic_cast<ImageType*>(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);
}
//--------------------------------------------------------------------
GenerateInputRequestedRegion() {
DD("GenerateInputRequestedRegion");
// Call default
- itk::ImageToImageFilter<ImageType, ImageType>::GenerateInputRequestedRegion();
+ Superclass::GenerateInputRequestedRegion();
// Get input pointers and set requested region to common region
ImagePointer input = dynamic_cast<ImageType*>(itk::ProcessObject::GetInput(0));
input->SetRequestedRegion(input->GetLargestPossibleRegion());
GenerateData() {
DD("GenerateData");
+ //--------------------------------------------------------------------
// Get input pointer
input = dynamic_cast<ImageType*>(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<ImageDimension; i++) {
+ if (i != GetDirection()) {
+ sizeSlice[j] = m_size[i];
+ indexSlice[j] = m_index[j];
+ j++;
+ }
+ }
+ regionSlice.SetSize(sizeSlice);
+ regionSlice.SetIndex(indexSlice);
+ DD(regionSlice);
+ */
//--------------------------------------------------------------------
- //--------------------------------------------------------------------
- // Final Step -> set output
- //this->SetNthOutput(0, working_image);
+ // loop ExtractImageFilter with region updated, push_back
+ typedef itk::ExtractImageFilter<ImageType, SliceType> ExtractImageFilterType;
+ typename ExtractImageFilterType::Pointer extract = ExtractImageFilterType::New();
+ extract->SetInput(input);
+ for(int i=0; i<m_NumberOfSlices; i++) {
+ extract = ExtractImageFilterType::New();
+ extract->SetInput(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<SliceType>(extract->GetOutput(), "extractA"+clitk::toString(i)+".mhd");
+ }
+
return;
}
//--------------------------------------------------------------------
// clitk
#include "clitkFilterBase.h"
+#include "clitkAddRelativePositionConstraintToLabelImageFilter.h"
namespace clitk {
public:
/** Standard class typedefs. */
- typedef itk::ImageToImageFilter<ImageType, ImageType> Superclass;
+ typedef itk::ImageToImageFilter<ImageType, ImageType> Superclass;
typedef SliceBySliceRelativePositionFilter Self;
typedef itk::SmartPointer<Self> Pointer;
typedef itk::SmartPointer<const Self> ConstPointer;
itkTypeMacro(SliceBySliceRelativePositionFilter, ImageToImageFilter);
FILTERBASE_INIT;
+ /** ImageDimension constants */
+ itkStaticConstMacro(ImageDimension, unsigned int, ImageType::ImageDimension);
+ typedef itk::Image<float, ImageDimension> FloatImageType;
+
/** Some convenient typedefs. */
typedef typename ImageType::ConstPointer ImageConstPointer;
typedef typename ImageType::Pointer ImagePointer;
typedef typename ImageType::PixelType PixelType;
typedef typename ImageType::SpacingType SpacingType;
typedef typename ImageType::SizeType SizeType;
+ typedef itk::Image<PixelType, ImageDimension-1> SliceType;
+ typedef clitk::AddRelativePositionConstraintToLabelImageFilter<SliceType> RelPosFilterType;
+ typedef typename RelPosFilterType::OrientationTypeEnumeration OrientationTypeEnumeration;
- /** ImageDimension constants */
- itkStaticConstMacro(ImageDimension, unsigned int, ImageType::ImageDimension);
- typedef itk::Image<float, ImageDimension> FloatImageType;
-
/** Input : initial image and object */
void SetInput(const ImageType * image);
void SetInputObject(const ImageType * image);
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();
// clitk
#include "clitkSegmentationUtils.h"
-// #include "clitkBooleanOperatorLabelImageFilter.h"
-// #include "clitkAutoCropFilter.h"
-// #include "clitkResampleImageWithOptionsFilter.h"
-// #include "clitkBooleanOperatorLabelImageFilter.h"
#include "clitkExtractSliceFilter.h"
-// // itk
-// #include <deque>
-// #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 <class ImageType>
clitk::SliceBySliceRelativePositionFilter<ImageType>::
{
this->SetNumberOfRequiredInputs(2);
SetDirection(2);
- SetObjectBackgroundValue(0);
+ SetObjectBackgroundValue(0);
+ SetFuzzyThreshold(0.6);
+ SetOrientationType(RelPosFilterType::LeftTo);
+ SetIntermediateSpacing(10);
+ ResampleBeforeRelativePositionFilterOff();
}
//--------------------------------------------------------------------
template <class ImageType>
void
clitk::SliceBySliceRelativePositionFilter<ImageType>::
-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<ImageType *>(image));
}
template <class ImageType>
void
clitk::SliceBySliceRelativePositionFilter<ImageType>::
-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<ImageType *>(image));
}
template <class ImageType>
void
clitk::SliceBySliceRelativePositionFilter<ImageType>::
-GenerateOutputInformation() {
+GenerateOutputInformation()
+{
ImagePointer input = dynamic_cast<ImageType*>(itk::ProcessObject::GetInput(0));
ImagePointer outputImage = this->GetOutput(0);
outputImage->SetRegions(input->GetLargestPossibleRegion());
template <class ImageType>
void
clitk::SliceBySliceRelativePositionFilter<ImageType>::
-GenerateInputRequestedRegion() {
+GenerateInputRequestedRegion()
+{
// Call default
itk::ImageToImageFilter<ImageType, ImageType>::GenerateInputRequestedRegion();
// Get input pointers and set requested region to common region
template <class ImageType>
void
clitk::SliceBySliceRelativePositionFilter<ImageType>::
-GenerateData() {
+GenerateData()
+{
// Get input pointer
input = dynamic_cast<ImageType*>(itk::ProcessObject::GetInput(0));
object = dynamic_cast<ImageType*>(itk::ProcessObject::GetInput(1));
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<ImageType>(input, "beforex.mhd");
typedef clitk::ExtractSliceFilter<ImageType> 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<typename SliceType::Pointer> & mInputSlices = extractSliceFilter->GetOutput();
+ std::vector<typename SliceType::Pointer> mInputSlices;
+ extractSliceFilter->GetOutputSlices(mInputSlices);
DD(mInputSlices.size());
- StopCurrentStep<SliceType>(mInputSlices[5]);
+ StopCurrentStep<SliceType>(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<typename SliceType::Pointer> & mObjectSlices = extractSliceFilter->GetOutput();
+ std::vector<typename SliceType::Pointer> mObjectSlices;
+ extractSliceFilter->GetOutputSlices(mObjectSlices);
DD(mObjectSlices.size());
- StopCurrentStep<SliceType>(mInputSlices[5]);
+ StopCurrentStep<SliceType>(mObjectSlices[0]);
-
//--------------------------------------------------------------------
// Perform slice by slice relative position
StartNewStep("Perform slice by slice relative position");
- for(int i=0; i<mInputSlices.size(); i++) {
- DD(i);
+ for(unsigned int i=0; i<mInputSlices.size(); i++) {
+ // DD(i);
+ // DD(mInputSlices[i]->GetOrigin());
+ // writeImage<SliceType>(mInputSlices[i], "inp"+clitk::toString(i)+".mhd");
+
+ // Select main CC in each object slice : this should be the main bronchus
+ mObjectSlices[i] = Labelize<SliceType>(mObjectSlices[i], 0, true, 1);
+ mObjectSlices[i] = KeepLabels<SliceType>(mObjectSlices[i], 0, 1, 1, 1, true);
+
+ // Relative position
typedef clitk::AddRelativePositionConstraintToLabelImageFilter<SliceType> 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<SliceType>(relPosFilter->GetOutput(), "inp-after"+clitk::toString(i)+".mhd");
mInputSlices[i] = relPosFilter->GetOutput();
}
- typedef itk::JoinSeriesImageFilter<SliceType, ImageType> JointSeriesFilterType;
- typename JointSeriesFilterType::Pointer jointFilter = JointSeriesFilterType::New();
- for(int i=0; i<mInputSlices.size(); i++) {
- jointFilter->SetInput(i, mInputSlices[i]);
+ DD(this->GetIntermediateSpacing());
+ DD(this->GetResampleBeforeRelativePositionFilter());
+ DD("End slice");
+
+ typedef itk::JoinSeriesImageFilter<SliceType, ImageType> JoinSeriesFilterType;
+ typename JoinSeriesFilterType::Pointer joinFilter = JoinSeriesFilterType::New();
+ joinFilter->SetOrigin(input->GetOrigin()[GetDirection()]);
+ joinFilter->SetSpacing(input->GetSpacing()[GetDirection()]);
+ for(unsigned int i=0; i<mInputSlices.size(); i++) {
+ // DD(mInputSlices[i]->GetLargestPossibleRegion().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<ImageType>(m_working_input);
- */
-
-
//--------------------------------------------------------------------
//--------------------------------------------------------------------
// Final Step -> set output
clitk::FilterBase(),
itk::ImageToImageFilter<TInputImageType, TMaskImageType>()
{
+ SetNumberOfSteps(10);
// Default global options
this->SetNumberOfRequiredInputs(2);
SetPatientMaskBackgroundValue(0);
{
input = dynamic_cast<const TInputImageType*>(itk::ProcessObject::GetInput(0));
Superclass::GenerateOutputInformation();
-// MaskImagePointer output = this->GetOutput(0);
// Get input pointers
input = dynamic_cast<const TInputImageType*>(itk::ProcessObject::GetInput(0));
return;
}
+ // Set Number of steps
+ SetNumberOfSteps(9);
+
//--------------------------------------------------------------------
//--------------------------------------------------------------------
StartNewStep("Set background to initial image");
clitk::ExtractLungGenericFilter<ArgsInfoType>::ExtractLungGenericFilter():
ImageToImageGenericFilter<Self>("ExtractLung")
{
+ this->SetFilterBase(NULL);
// Default values
cmdline_parser_clitkExtractLung_init(&mArgsInfo);
InitializeImageType<3>();
// Create filter
typedef clitk::ExtractLungFilter<ImageType, MaskImageType> 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);
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"
#include "clitkSliceBySliceRelativePositionFilter.h"
// itk
-#include <deque>
#include <itkStatisticsLabelMapFilter.h>
#include <itkLabelImageToStatisticsLabelMapFilter.h>
#include <itkRegionOfInterestImageFilter.h>
#include <itkBinaryThresholdImageFilter.h>
#include <itkImageSliceConstIteratorWithIndex.h>
+#include <itkBinaryThinningImageFilter.h>
// itk ENST
#include "RelativePositionPropImageFilter.h"
// ----------------------------------------------------------------
// 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();
// ----------------------------------------------------------------
// ----------------------------------------------------------------
// 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++) {
// Labelize and consider two main labels
m_working_trachea = Labelize<ImageType>(m_working_trachea, 0, true, 1);
- StopCurrentStep<ImageType>(m_working_trachea);
-
+
// Detect wich label is at Left
typedef itk::ImageSliceConstIteratorWithIndex<ImageType> SliceIteratorType;
SliceIteratorType iter(m_working_trachea, m_working_trachea->GetLargestPossibleRegion());
iter.GoToBegin();
bool stop = false;
ImagePixelType leftLabel;
+ ImagePixelType rightLabel;
while (!stop) {
if (iter.Get() != m_BackgroundValueTrachea) {
// DD(iter.GetIndex());
}
++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<ImageType, ImageType>(m_working_trachea, m_working_trachea, 1, 0);
- writeImage<ImageType>(temp, "temp1.mhd");
-
- // Left relative position
- typedef clitk::AddRelativePositionConstraintToLabelImageFilter<TImageType> 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<ImageType, ImageType>(m_working_trachea, m_working_trachea, 2, 0);
- writeImage<ImageType>(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<ImageType>(m_working_trachea);
+
+ //-----------------------------------------------------
+ /* DD("TEST Skeleton");
+ typedef itk::BinaryThinningImageFilter<ImageType, ImageType> SkeletonFilterType;
+ typename SkeletonFilterType::Pointer skeletonFilter = SkeletonFilterType::New();
+ skeletonFilter->SetInput(m_working_trachea);
+ skeletonFilter->Update();
+ writeImage<ImageType>(skeletonFilter->GetOutput(), "skel.mhd");
+ writeImage<ImageType>(skeletonFilter->GetThinning(), "skel2.mhd");
*/
//-----------------------------------------------------
- StartNewStep("Left/Right limits with trachea (slice by slice");
-
- // Select LeftLabel (set label 1 to 0)
- ImagePointer temp = SetBackground<ImageType, ImageType>(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<ImageType, ImageType>(m_working_trachea, m_working_trachea, rightLabel, 0);
writeImage<ImageType>(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<ImageType> SliceRelPosFilterType;
typename SliceRelPosFilterType::Pointer sliceRelPosFilter = SliceRelPosFilterType::New();
sliceRelPosFilter->SetCurrentStepBaseId(this->GetCurrentStepId());
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<ImageType>(m_working_image, "afterslicebyslice.mhd");
- /*
-
- itk::ImageSliceConstIteratorWithIndex<ImageType> it(temp, temp->GetRequestedRegion());
- itk::ImageRegionIterator<SliceType> * 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<SliceType>(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<SliceType>(mImageSlices[10], "slice.mhd");
-
- // Perform RelPos by slice
- for(int i=0; i<mImageSlices.size(); i++) {
- DD(i);
- typedef clitk::AddRelativePositionConstraintToLabelImageFilter<SliceType> 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<ImageType, ImageType>(m_working_trachea, m_working_trachea, leftLabel, 0);
+ writeImage<ImageType>(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<ImageType>(m_working_image, "afterslicebyslice.mhd");
+
- */
-
DD("end");
m_output = m_working_image;
StopCurrentStep<ImageType>(m_output);