Main Page   Groups   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members   Concepts

itkLabelGeometryImageFilter.h

Go to the documentation of this file.
00001 /*=========================================================================
00002 
00003   Program:   Insight Segmentation & Registration Toolkit
00004   Module:    $RCSfile: itkLabelGeometryImageFilter.h,v $
00005   Language:  C++
00006   Date:      $Date: 2010-01-24 14:09:29 $
00007   Version:   $Revision: 1.3 $
00008 
00009   Copyright (c) Insight Software Consortium. All rights reserved.
00010   See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details.
00011 
00012      This software is distributed WITHOUT ANY WARRANTY; without even 
00013      the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
00014      PURPOSE.  See the above copyright notices for more information.
00015 
00016 =========================================================================*/
00017 #ifndef __itkLabelGeometryImageFilter_h
00018 #define __itkLabelGeometryImageFilter_h
00019 
00020 #include "itkImageToImageFilter.h"
00021 #include "itkNumericTraits.h"
00022 #include "itkArray.h"
00023 #include "itkSimpleDataObjectDecorator.h"
00024 #include "itk_hash_map.h"
00025 #include "itkFastMutexLock.h"
00026 #include <vector>
00027 #include <vnl/algo/vnl_symmetric_eigensystem.h>
00028 #include <vnl/vnl_det.h>
00029 #include <vnl/vnl_math.h>
00030 #include <vcl_cmath.h>
00031 
00032 
00033 namespace itk {
00034 
00073 template<class TLabelImage, class TIntensityImage = TLabelImage>
00074 class ITK_EXPORT LabelGeometryImageFilter : 
00075     public ImageToImageFilter<TLabelImage, TIntensityImage>
00076 {
00077 public:
00079   typedef LabelGeometryImageFilter                          Self;
00080   typedef ImageToImageFilter<TLabelImage,TIntensityImage>   Superclass;
00081   typedef SmartPointer<Self>                                Pointer;
00082   typedef SmartPointer<const Self>                          ConstPointer;
00083 
00085   itkNewMacro(Self);  
00086 
00088   itkTypeMacro(LabelGeometryImageFilter, ImageToImageFilter);
00089 
00091   typedef TIntensityImage                         IntensityImageType;
00092   typedef typename TIntensityImage::Pointer       InputImagePointer;
00093   typedef typename TIntensityImage::RegionType    RegionType;
00094   typedef typename TIntensityImage::SizeType      SizeType;
00095   typedef typename TIntensityImage::IndexType     IndexType;
00096   typedef typename TIntensityImage::PixelType     PixelType;
00097 
00099   typedef TLabelImage                             LabelImageType;
00100   typedef typename TLabelImage::Pointer           LabelImagePointer;
00101   typedef typename TLabelImage::RegionType        LabelRegionType;
00102   typedef typename TLabelImage::SizeType          LabelSizeType;
00103   typedef typename TLabelImage::IndexType         LabelIndexType;
00104   typedef typename TLabelImage::PixelType         LabelPixelType;
00105   typedef typename TLabelImage::PointType         LabelPointType;
00106 
00108   itkStaticConstMacro(ImageDimension, unsigned int,
00109                       TLabelImage::ImageDimension );
00110 
00112   typedef typename NumericTraits<PixelType>::RealType RealType;
00113 
00115   typedef typename DataObject::Pointer DataObjectPointer;
00116 
00118   typedef SimpleDataObjectDecorator<RealType> RealObjectType;
00119 
00121   typedef itk::FixedArray<typename LabelIndexType::IndexValueType,itkGetStaticConstMacro(ImageDimension)*2> BoundingBoxType;
00122   typedef itk::FixedArray< float,itkGetStaticConstMacro(ImageDimension)*2> BoundingBoxFloatType;
00124 
00125   //typedef itk::FixedArray< LabelPointType,vcl_pow(2.0,itkGetStaticConstMacro(ImageDimension))> BoundingBoxVerticesType;
00126   typedef std::vector< LabelPointType > BoundingBoxVerticesType;
00127 
00129   typedef itk::FixedArray<RealType,itkGetStaticConstMacro(ImageDimension)> AxesLengthType;
00130 
00132   typedef itk::FixedArray< typename LabelIndexType::IndexValueType, itkGetStaticConstMacro(ImageDimension) > IndexArrayType;
00133 
00135   typedef std::vector< LabelPixelType > LabelsType;
00136 
00138   typedef std::vector< LabelIndexType > LabelIndicesType;
00139 
00141   typedef std::vector< double > VectorType;
00142 
00144   typedef vnl_matrix<double> MatrixType;
00145 
00149   class LabelGeometry
00150     {
00151     public:
00152       // default constructor
00153       LabelGeometry()
00154       {
00155         // initialized to the default values
00156       this->m_Label = 0;
00157       this->m_Sum = NumericTraits<RealType>::Zero;
00158 
00159       const unsigned int imageDimension = itkGetStaticConstMacro(ImageDimension);
00160 
00161       //m_BoundingBox.resize(imageDimension*2);
00162       for (unsigned int i = 0; i < imageDimension * 2; i += 2)
00163         {
00164         m_BoundingBox[i] = NumericTraits<ITK_TYPENAME IndexType::IndexValueType>::max();
00165         m_BoundingBox[i+1] = NumericTraits<ITK_TYPENAME IndexType::IndexValueType>::NonpositiveMin();
00166         }
00167         
00168       m_BoundingBoxVolume = 0;
00169       m_BoundingBoxSize.Fill(0);
00170       m_PixelIndices.clear();
00171       m_Centroid.Fill( 0 );
00172       m_WeightedCentroid.Fill( 0 );
00173       m_ZeroOrderMoment = 0;
00174       m_FirstOrderRawMoments.Fill( 0 );
00175       m_FirstOrderWeightedRawMoments.Fill( 0 );
00176       m_Eigenvalues.resize(ImageDimension);
00177       m_Eigenvalues.clear();
00178       m_Eigenvectors.set_size(ImageDimension,ImageDimension);
00179       m_Eigenvectors.fill(0);
00180       m_AxesLength.Fill( 0 );
00181       m_Eccentricity = 1;
00182       m_Elongation = 1;
00183       m_Orientation = 0;
00184       LabelPointType emptyPoint;
00185       emptyPoint.Fill( 0 );
00186       unsigned int numberOfVertices = (unsigned int)vcl_pow( (double)2, (int)ImageDimension );
00187       m_OrientedBoundingBoxVertices.resize(numberOfVertices,emptyPoint);
00188       m_OrientedBoundingBoxVolume = 0;
00189       m_OrientedBoundingBoxSize.Fill(0);
00190       m_OrientedLabelImage = LabelImageType::New();
00191       m_OrientedIntensityImage = IntensityImageType::New();
00192       m_OrientedBoundingBoxOrigin.Fill( 0 );
00193       m_RotationMatrix.set_size(ImageDimension,ImageDimension);
00194       m_RotationMatrix.fill( 0.0 );
00195       
00196       m_SecondOrderRawMoments.set_size(ImageDimension,ImageDimension);
00197       m_SecondOrderCentralMoments.set_size(ImageDimension,ImageDimension);
00198       for( unsigned int i = 0; i < ImageDimension; i++ )
00199         {
00200         for( unsigned int j = 0; j < ImageDimension; j++ )
00201           {
00202           m_SecondOrderRawMoments(i,j) = 0;
00203           m_SecondOrderCentralMoments(i,j) = 0;
00204           }
00205         }
00206       }
00207 
00208     LabelPixelType m_Label;
00209     RealType m_Sum;
00210     LabelPointType m_Centroid;
00211     LabelPointType m_WeightedCentroid;
00212     unsigned long m_ZeroOrderMoment;
00213     IndexArrayType m_FirstOrderRawMoments;
00214     IndexArrayType m_FirstOrderWeightedRawMoments;
00215     unsigned long  m_FirstOrderRawCrossMoment;
00216     RealType  m_FirstOrderCentralCrossMoment;
00217     MatrixType m_SecondOrderRawMoments;
00218     MatrixType m_SecondOrderCentralMoments;
00219     VectorType m_Eigenvalues;
00220     MatrixType m_Eigenvectors;
00221     FixedArray<float,itkGetStaticConstMacro(ImageDimension)> m_AxesLength;
00222     RealType m_Eccentricity;
00223     RealType m_Elongation;
00224     RealType m_Orientation;
00225     BoundingBoxType m_BoundingBox;
00226     LabelSizeType m_BoundingBoxSize;
00227     RealType m_BoundingBoxVolume;
00228     LabelIndicesType m_PixelIndices;
00229     BoundingBoxVerticesType m_OrientedBoundingBoxVertices;
00230     RealType m_OrientedBoundingBoxVolume;
00231     LabelPointType m_OrientedBoundingBoxSize;
00232     typename LabelImageType::Pointer m_OrientedLabelImage;
00233     typename IntensityImageType::Pointer m_OrientedIntensityImage;
00234     MatrixType m_RotationMatrix;
00235     LabelPointType m_OrientedBoundingBoxOrigin;
00236   };
00237   
00239   // Map from the label to the class storing all of the geometry information.
00240   typedef itk::hash_map<LabelPixelType, LabelGeometry> MapType;
00241   typedef typename itk::hash_map<LabelPixelType, LabelGeometry>::iterator MapIterator;
00242   typedef typename itk::hash_map<LabelPixelType, LabelGeometry>::const_iterator MapConstIterator;
00243 
00244   // Macros for enabling the calculation of additional features.
00245   itkGetMacro(CalculatePixelIndices, bool);
00246   itkBooleanMacro(CalculatePixelIndices);
00247   void SetCalculatePixelIndices( const bool value )
00248     {
00249     // CalculateOrientedBoundingBox, CalculateOrientedLabelImage, and
00250     // CalculateOrientedIntensityImage all need CalculatePixelIndices to be turned
00251     // on if they are turned on.  So, CalculatePixelIndices cannot be
00252     // turned off if any of these flags are turned on.
00253     if( value == false )
00254       {
00255       if( (this->m_CalculateOrientedBoundingBox == true) ||
00256           (this->m_CalculateOrientedLabelRegions == true) ||
00257           (this->m_CalculateOrientedIntensityRegions == true) )
00258         {
00259         // We cannot change the value, so return.
00260         return;
00261         }
00262       }
00263     
00264     if ( this->m_CalculatePixelIndices != value )
00265       {
00266       this->m_CalculatePixelIndices = value;
00267       this->Modified();
00268       }
00269     }
00270   
00271   itkGetMacro(CalculateOrientedBoundingBox, bool);
00272   itkBooleanMacro(CalculateOrientedBoundingBox);
00273   void SetCalculateOrientedBoundingBox( const bool value )
00274     {
00275 
00276     if (this->m_CalculateOrientedBoundingBox != value)
00277       {
00278       this->m_CalculateOrientedBoundingBox = value;
00279       this->Modified();
00280       }
00281 
00282     // CalculateOrientedBoundingBox needs
00283     // CalculatePixelIndices to be turned on.
00284     if( value == true )
00285       {
00286       this->SetCalculatePixelIndices( true );
00287       }
00288 
00289     }
00290 
00291   itkGetMacro(CalculateOrientedLabelRegions, bool);
00292   itkBooleanMacro(CalculateOrientedLabelRegions);
00293   void SetCalculateOrientedLabelRegions( const bool value )
00294     {
00295     if (this->m_CalculateOrientedLabelRegions != value)
00296       {
00297       this->m_CalculateOrientedLabelRegions = value;
00298       this->Modified();
00299 
00300       // CalculateOrientedLabelImage needs
00301       // CalculateOrientedBoundingBox to be turned on.
00302       if( value == true )
00303         {
00304         SetCalculateOrientedBoundingBox( true );
00305         }
00306       }
00307     }
00308 
00309   itkGetMacro(CalculateOrientedIntensityRegions, bool);
00310   itkBooleanMacro(CalculateOrientedIntensityRegions);
00311   void SetCalculateOrientedIntensityRegions( const bool value )
00312     {
00313     if (this->m_CalculateOrientedIntensityRegions != value)
00314       {
00315       this->m_CalculateOrientedIntensityRegions = value;
00316       this->Modified();
00317 
00318       // CalculateOrientedIntensityImage needs
00319       // CalculateOrientedBoundingBox to be turned on.
00320       if( value == true )
00321         {
00322         this->SetCalculateOrientedBoundingBox( true );
00323         }
00324       }
00325     }
00326 
00328   void SetIntensityInput(const TIntensityImage *input )
00329     {
00330     // Process object is not const-correct so the const casting is required.
00331     this->SetNthInput(1, const_cast<TIntensityImage *>(input) );
00332     }
00333 
00335   const TIntensityImage * GetIntensityInput() const
00336     {
00337     return static_cast<TIntensityImage*>(const_cast<DataObject *>(this->ProcessObject::GetInput(1)));
00338     }
00339 
00342   bool HasLabel(LabelPixelType label) const
00343     {
00344     return m_LabelGeometryMapper.find(label) != m_LabelGeometryMapper.end();
00345     }
00346 
00348   unsigned long GetNumberOfObjects() const
00349     {
00350     return m_LabelGeometryMapper.size();
00351     }
00352   unsigned long GetNumberOfLabels() const
00353     {
00354     return this->GetNumberOfObjects();
00355     }
00357 
00359   std::vector< LabelPixelType > GetLabels() const
00360     {
00361     return m_AllLabels;
00362     }
00363 
00365   LabelIndicesType GetPixelIndices( LabelPixelType label) const;
00366 
00369   unsigned long GetVolume(LabelPixelType label) const;
00370 
00372   //std::vector<unsigned long> GetAllCounts() const;
00373 
00375   RealType GetIntegratedIntensity(LabelPixelType label) const;
00376 
00378   LabelPointType GetCentroid( LabelPixelType label) const;
00379 
00381   LabelPointType GetWeightedCentroid( LabelPixelType label) const;
00382 
00384   VectorType GetEigenvalues (LabelPixelType label) const;
00385 
00387   MatrixType GetEigenvectors (LabelPixelType label) const;
00388 
00390   AxesLengthType GetAxesLength( LabelPixelType label) const;
00391 
00394   RealType GetMinorAxisLength( LabelPixelType label) const;
00395 
00398   RealType GetMajorAxisLength( LabelPixelType label) const;
00399 
00401   RealType GetEccentricity( LabelPixelType label) const;
00402 
00405   RealType GetElongation( LabelPixelType label) const;
00406 
00408   RealType GetOrientation( LabelPixelType label) const;
00409 
00413   BoundingBoxType GetBoundingBox(LabelPixelType label) const;
00414 
00416   RealType GetBoundingBoxVolume(LabelPixelType label) const;
00417 
00419   LabelSizeType GetBoundingBoxSize(LabelPixelType label) const;
00420 
00427   BoundingBoxVerticesType GetOrientedBoundingBoxVertices(LabelPixelType label) const;
00428 
00430   RealType GetOrientedBoundingBoxVolume(LabelPixelType label) const;
00431 
00433   LabelPointType GetOrientedBoundingBoxSize(LabelPixelType label) const;
00434 
00436   LabelPointType GetOrientedBoundingBoxOrigin(LabelPixelType label) const;
00437 
00440   MatrixType GetRotationMatrix(LabelPixelType label) const;
00441 
00443   RegionType GetRegion(LabelPixelType label) const;
00444 
00446   TLabelImage *GetOrientedLabelImage( LabelPixelType label) const;
00447 
00450   TIntensityImage * GetOrientedIntensityImage( LabelPixelType label) const;
00451 
00452 
00453 #ifdef ITK_USE_CONCEPT_CHECKING
00454 
00455   itkConceptMacro(InputHasNumericTraitsCheck,
00456                   (Concept::HasNumericTraits<PixelType>));
00457 
00459 #endif
00460 
00461 protected:
00462   LabelGeometryImageFilter();
00463   ~LabelGeometryImageFilter(){};
00464   void PrintSelf(std::ostream& os, Indent indent) const;
00465 
00466   void GenerateData();
00467 
00468 private:
00469   LabelGeometryImageFilter(const Self&); //purposely not implemented
00470   void operator=(const Self&); //purposely not implemented
00471 
00472   bool CalculateOrientedBoundingBoxVertices(vnl_symmetric_eigensystem<double> eig, LabelGeometry & m_LabelGeometry);
00473 
00474   bool m_CalculatePixelIndices;
00475   bool m_CalculateOrientedBoundingBox;
00476   bool m_CalculateOrientedLabelRegions;
00477   bool m_CalculateOrientedIntensityRegions;
00478 
00479   MapType         m_LabelGeometryMapper;
00480   LabelGeometry   m_LabelGeometry;
00481   LabelsType      m_AllLabels;
00482 
00483   SimpleFastMutexLock m_Mutex;
00484 
00485 }; // end of class
00486 
00487 template<class TLabelImage, class TIntensityImage>
00488 typename LabelGeometryImageFilter<TLabelImage,TIntensityImage>::MatrixType CalculateRotationMatrix(vnl_symmetric_eigensystem<double> eig);
00489 
00490 template<class TLabelImage, class TIntensityImage, class TGenericImage>
00491 bool CalculateOrientedImage(
00492   LabelGeometryImageFilter<TLabelImage, TIntensityImage>  *filter,
00493   vnl_symmetric_eigensystem<double> eig,
00494   typename LabelGeometryImageFilter<TLabelImage,TIntensityImage>::LabelGeometry & labelGeometry,
00495   bool useLabelImage = true);
00496 
00497 } // end namespace itk
00498   
00499 #ifndef ITK_MANUAL_INSTANTIATION
00500 #include "itkLabelGeometryImageFilter.txx"
00501 #endif
00502 
00503 #endif
00504 

Generated at Fri Apr 16 18:50:25 2010 for ITK by doxygen 1.6.1 written by Dimitri van Heesch, © 1997-2000