ITK  4.3.0
Insight Segmentation and Registration Toolkit
itkLabelGeometryImageFilter.h
Go to the documentation of this file.
1 /*=========================================================================
2  *
3  * Copyright Insight Software Consortium
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0.txt
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  *=========================================================================*/
18 #ifndef __itkLabelGeometryImageFilter_h
19 #define __itkLabelGeometryImageFilter_h
20 
21 #include "itkImageToImageFilter.h"
22 #include "itkNumericTraits.h"
23 #include "itkArray.h"
25 #include "itksys/hash_map.hxx"
26 #include "itkFastMutexLock.h"
27 #include <vector>
28 #include "vnl/algo/vnl_symmetric_eigensystem.h"
29 #include "vnl/vnl_det.h"
30 #include "vnl/vnl_math.h"
31 #include "vcl_cmath.h"
32 
33 namespace itk
34 {
78 template< class TLabelImage, class TIntensityImage = TLabelImage >
79 class ITK_EXPORT LabelGeometryImageFilter:
80  public ImageToImageFilter< TLabelImage, TIntensityImage >
81 {
82 public:
88 
90  itkNewMacro(Self);
91 
94 
96  typedef TIntensityImage IntensityImageType;
97  typedef typename TIntensityImage::Pointer InputImagePointer;
98  typedef typename TIntensityImage::RegionType RegionType;
99  typedef typename TIntensityImage::SizeType SizeType;
100  typedef typename TIntensityImage::IndexType IndexType;
101  typedef typename TIntensityImage::PixelType PixelType;
102 
104  typedef TLabelImage LabelImageType;
105  typedef typename TLabelImage::Pointer LabelImagePointer;
106  typedef typename TLabelImage::RegionType LabelRegionType;
107  typedef typename TLabelImage::SizeType LabelSizeType;
108  typedef typename TLabelImage::IndexType LabelIndexType;
109  typedef typename TLabelImage::PixelType LabelPixelType;
110  typedef typename TLabelImage::PointType LabelPointType;
111 
113  itkStaticConstMacro(ImageDimension, unsigned int,
114  TLabelImage::ImageDimension);
115 
118 
121 
124 
127  itkGetStaticConstMacro(ImageDimension) *2 > BoundingBoxType;
128  typedef itk::FixedArray< float,
129  itkGetStaticConstMacro(ImageDimension) *2 > BoundingBoxFloatType;
131 
132  //typedef itk::FixedArray<
133  // LabelPointType,vcl_pow(2.0,itkGetStaticConstMacro(ImageDimension))>
134  // BoundingBoxVerticesType;
135  typedef std::vector< LabelPointType > BoundingBoxVerticesType;
136 
139 
142  itkGetStaticConstMacro(ImageDimension) > IndexArrayType;
143 
145  typedef std::vector< LabelPixelType > LabelsType;
146 
148  typedef std::vector< LabelIndexType > LabelIndicesType;
149 
151  typedef std::vector< double > VectorType;
152 
155 
161  {
162 public:
163  // default constructor
165  {
166  // initialized to the default values
167  this->m_Label = 0;
168  this->m_Sum = NumericTraits< RealType >::Zero;
169 
170  const unsigned int imageDimension = itkGetStaticConstMacro(ImageDimension);
171 
172  //m_BoundingBox.resize(imageDimension*2);
173  for ( unsigned int i = 0; i < imageDimension * 2; i += 2 )
174  {
177  }
178 
179  m_BoundingBoxVolume = 0;
180  m_BoundingBoxSize.Fill(0);
181  m_PixelIndices.clear();
182  m_Centroid.Fill(0);
183  m_WeightedCentroid.Fill(0);
184  m_ZeroOrderMoment = 0;
185  m_FirstOrderRawMoments.Fill(0);
186  m_FirstOrderWeightedRawMoments.Fill(0);
187  m_Eigenvalues.resize(ImageDimension);
188  m_Eigenvalues.clear();
189  m_Eigenvectors.set_size(ImageDimension, ImageDimension);
190  m_Eigenvectors.fill(0);
191  m_AxesLength.Fill(0);
192  m_Eccentricity = 1;
193  m_Elongation = 1;
194  m_Orientation = 0;
195  LabelPointType emptyPoint;
196  emptyPoint.Fill(0);
197  unsigned int numberOfVertices = (unsigned int)vcl_pow( (double)2, (int)ImageDimension );
198  m_OrientedBoundingBoxVertices.resize(numberOfVertices, emptyPoint);
199  m_OrientedBoundingBoxVolume = 0;
200  m_OrientedBoundingBoxSize.Fill(0);
201  m_OrientedLabelImage = LabelImageType::New();
202  m_OrientedIntensityImage = IntensityImageType::New();
203  m_OrientedBoundingBoxOrigin.Fill(0);
204  m_RotationMatrix.set_size(ImageDimension, ImageDimension);
205  m_RotationMatrix.fill(0.0);
206 
207  m_SecondOrderRawMoments.set_size(ImageDimension, ImageDimension);
208  m_SecondOrderCentralMoments.set_size(ImageDimension, ImageDimension);
209  for ( unsigned int i = 0; i < ImageDimension; i++ )
210  {
211  for ( unsigned int j = 0; j < ImageDimension; j++ )
212  {
213  m_SecondOrderRawMoments(i, j) = 0;
214  m_SecondOrderCentralMoments(i, j) = 0;
215  }
216  }
217  }
218 
243  typename LabelImageType::Pointer m_OrientedLabelImage;
244  typename IntensityImageType::Pointer m_OrientedIntensityImage;
247  };
248 
250  // Map from the label to the class storing all of the geometry information.
251  typedef itksys::hash_map< LabelPixelType, LabelGeometry > MapType;
252  typedef typename itksys::hash_map< LabelPixelType, LabelGeometry >::iterator MapIterator;
253  typedef typename itksys::hash_map< LabelPixelType, LabelGeometry >::const_iterator MapConstIterator;
254 
255  // Macros for enabling the calculation of additional features.
256  itkGetMacro(CalculatePixelIndices, bool);
257  itkBooleanMacro(CalculatePixelIndices);
258  void SetCalculatePixelIndices(const bool value)
259  {
260  // CalculateOrientedBoundingBox, CalculateOrientedLabelImage, and
261  // CalculateOrientedIntensityImage all need CalculatePixelIndices to be
262  // turned
263  // on if they are turned on. So, CalculatePixelIndices cannot be
264  // turned off if any of these flags are turned on.
265  if ( value == false )
266  {
267  if ( ( this->m_CalculateOrientedBoundingBox == true )
268  || ( this->m_CalculateOrientedLabelRegions == true )
269  || ( this->m_CalculateOrientedIntensityRegions == true ) )
270  {
271  // We cannot change the value, so return.
272  return;
273  }
274  }
275 
276  if ( this->m_CalculatePixelIndices != value )
277  {
278  this->m_CalculatePixelIndices = value;
279  this->Modified();
280  }
281  }
282 
283  itkGetMacro(CalculateOrientedBoundingBox, bool);
284  itkBooleanMacro(CalculateOrientedBoundingBox);
285  void SetCalculateOrientedBoundingBox(const bool value)
286  {
287  if ( this->m_CalculateOrientedBoundingBox != value )
288  {
289  this->m_CalculateOrientedBoundingBox = value;
290  this->Modified();
291  }
292 
293  // CalculateOrientedBoundingBox needs
294  // CalculatePixelIndices to be turned on.
295  if ( value == true )
296  {
297  this->SetCalculatePixelIndices(true);
298  }
299  }
300 
301  itkGetMacro(CalculateOrientedLabelRegions, bool);
302  itkBooleanMacro(CalculateOrientedLabelRegions);
303  void SetCalculateOrientedLabelRegions(const bool value)
304  {
305  if ( this->m_CalculateOrientedLabelRegions != value )
306  {
307  this->m_CalculateOrientedLabelRegions = value;
308  this->Modified();
309 
310  // CalculateOrientedLabelImage needs
311  // CalculateOrientedBoundingBox to be turned on.
312  if ( value == true )
313  {
314  SetCalculateOrientedBoundingBox(true);
315  }
316  }
317  }
318 
319  itkGetMacro(CalculateOrientedIntensityRegions, bool);
320  itkBooleanMacro(CalculateOrientedIntensityRegions);
321  void SetCalculateOrientedIntensityRegions(const bool value)
322  {
323  if ( this->m_CalculateOrientedIntensityRegions != value )
324  {
325  this->m_CalculateOrientedIntensityRegions = value;
326  this->Modified();
327 
328  // CalculateOrientedIntensityImage needs
329  // CalculateOrientedBoundingBox to be turned on.
330  if ( value == true )
331  {
332  this->SetCalculateOrientedBoundingBox(true);
333  }
334  }
335  }
336 
338  void SetIntensityInput(const TIntensityImage *input)
339  {
340  // Process object is not const-correct so the const casting is required.
341  this->SetNthInput( 1, const_cast< TIntensityImage * >( input ) );
342  }
343 
345  const TIntensityImage * GetIntensityInput() const
346  {
347  return static_cast< TIntensityImage * >( const_cast< DataObject * >( this->ProcessObject::GetInput(1) ) );
348  }
349 
352  bool HasLabel(LabelPixelType label) const
353  {
354  return m_LabelGeometryMapper.find(label) != m_LabelGeometryMapper.end();
355  }
356 
358  SizeValueType GetNumberOfObjects() const
359  {
360  return m_LabelGeometryMapper.size();
361  }
362 
363  SizeValueType GetNumberOfLabels() const
364  {
365  return this->GetNumberOfObjects();
366  }
367 
369  std::vector< LabelPixelType > GetLabels() const
370  {
371  return m_AllLabels;
372  }
373 
375  LabelIndicesType GetPixelIndices(LabelPixelType label) const;
376 
379  SizeValueType GetVolume(LabelPixelType label) const;
380 
382  //std::vector< SizeValueType > GetAllCounts() const;
383 
385  RealType GetIntegratedIntensity(LabelPixelType label) const;
386 
388  LabelPointType GetCentroid(LabelPixelType label) const;
389 
391  LabelPointType GetWeightedCentroid(LabelPixelType label) const;
392 
394  VectorType GetEigenvalues(LabelPixelType label) const;
395 
397  MatrixType GetEigenvectors(LabelPixelType label) const;
398 
400  AxesLengthType GetAxesLength(LabelPixelType label) const;
401 
404  RealType GetMinorAxisLength(LabelPixelType label) const;
405 
408  RealType GetMajorAxisLength(LabelPixelType label) const;
409 
411  RealType GetEccentricity(LabelPixelType label) const;
412 
415  RealType GetElongation(LabelPixelType label) const;
416 
418  RealType GetOrientation(LabelPixelType label) const;
419 
423  BoundingBoxType GetBoundingBox(LabelPixelType label) const;
424 
426  RealType GetBoundingBoxVolume(LabelPixelType label) const;
427 
429  LabelSizeType GetBoundingBoxSize(LabelPixelType label) const;
430 
437  BoundingBoxVerticesType GetOrientedBoundingBoxVertices(LabelPixelType label) const;
438 
440  RealType GetOrientedBoundingBoxVolume(LabelPixelType label) const;
441 
443  LabelPointType GetOrientedBoundingBoxSize(LabelPixelType label) const;
444 
446  LabelPointType GetOrientedBoundingBoxOrigin(LabelPixelType label) const;
447 
450  MatrixType GetRotationMatrix(LabelPixelType label) const;
451 
453  RegionType GetRegion(LabelPixelType label) const;
454 
456  TLabelImage * GetOrientedLabelImage(LabelPixelType label) const;
457 
460  TIntensityImage * GetOrientedIntensityImage(LabelPixelType label) const;
461 
462 #ifdef ITK_USE_CONCEPT_CHECKING
463 
464  itkConceptMacro( InputHasNumericTraitsCheck,
466 
468 #endif
469 
470 protected:
473  void PrintSelf(std::ostream & os, Indent indent) const;
474 
475  void GenerateData();
476 
477 private:
478  LabelGeometryImageFilter(const Self &); //purposely not implemented
479  void operator=(const Self &); //purposely not implemented
480 
481  bool CalculateOrientedBoundingBoxVertices(vnl_symmetric_eigensystem< double > eig, LabelGeometry & m_LabelGeometry);
482 
487 
491 
493 }; // end of class
494 
495 template< class TLabelImage, class TIntensityImage >
497  vnl_symmetric_eigensystem< double > eig);
498 
499 template< class TLabelImage, class TIntensityImage, class TGenericImage >
502  vnl_symmetric_eigensystem< double > eig,
504  bool useLabelImage = true);
505 } // end namespace itk
506 
507 #ifndef ITK_MANUAL_INSTANTIATION
508 #include "itkLabelGeometryImageFilter.hxx"
509 #endif
510 
511 #endif
512