Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
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
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
00153 LabelGeometry()
00154 {
00155
00156 this->m_Label = 0;
00157 this->m_Sum = NumericTraits<RealType>::Zero;
00158
00159 const unsigned int imageDimension = itkGetStaticConstMacro(ImageDimension);
00160
00161
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
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
00245 itkGetMacro(CalculatePixelIndices, bool);
00246 itkBooleanMacro(CalculatePixelIndices);
00247 void SetCalculatePixelIndices( const bool value )
00248 {
00249
00250
00251
00252
00253 if( value == false )
00254 {
00255 if( (this->m_CalculateOrientedBoundingBox == true) ||
00256 (this->m_CalculateOrientedLabelRegions == true) ||
00257 (this->m_CalculateOrientedIntensityRegions == true) )
00258 {
00259
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
00283
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
00301
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
00319
00320 if( value == true )
00321 {
00322 this->SetCalculateOrientedBoundingBox( true );
00323 }
00324 }
00325 }
00326
00328 void SetIntensityInput(const TIntensityImage *input )
00329 {
00330
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
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&);
00470 void operator=(const Self&);
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 };
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 }
00498
00499 #ifndef ITK_MANUAL_INSTANTIATION
00500 #include "itkLabelGeometryImageFilter.txx"
00501 #endif
00502
00503 #endif
00504