ITK  4.13.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 "itkMath.h"
31 
32 namespace itk
33 {
77 template< typename TLabelImage, typename TIntensityImage = TLabelImage >
78 class ITK_TEMPLATE_EXPORT LabelGeometryImageFilter:
79  public ImageToImageFilter< TLabelImage, TIntensityImage >
80 {
81 public:
87 
89  itkNewMacro(Self);
90 
93 
95  typedef TIntensityImage IntensityImageType;
96  typedef typename TIntensityImage::Pointer InputImagePointer;
97  typedef typename TIntensityImage::RegionType RegionType;
100  typedef typename TIntensityImage::PixelType PixelType;
101 
103  typedef TLabelImage LabelImageType;
104  typedef typename TLabelImage::Pointer LabelImagePointer;
105  typedef typename TLabelImage::RegionType LabelRegionType;
108  typedef typename TLabelImage::PixelType LabelPixelType;
110 
112  itkStaticConstMacro(ImageDimension, unsigned int,
113  TLabelImage::ImageDimension);
114 
117 
120 
123 
126  itkGetStaticConstMacro(ImageDimension) *2 > BoundingBoxType;
127  typedef itk::FixedArray< float,
128  itkGetStaticConstMacro(ImageDimension) *2 > BoundingBoxFloatType;
130 
131  //typedef itk::FixedArray<
132  // LabelPointType,std::pow(2.0,itkGetStaticConstMacro(ImageDimension))>
133  // BoundingBoxVerticesType;
134  typedef std::vector< LabelPointType > BoundingBoxVerticesType;
135 
138 
141  itkGetStaticConstMacro(ImageDimension) > IndexArrayType;
142 
144  typedef std::vector< LabelPixelType > LabelsType;
145 
147  typedef std::vector< LabelIndexType > LabelIndicesType;
148 
150  typedef std::vector< double > VectorType;
151 
153  typedef vnl_matrix< double > MatrixType;
154 
160  {
161 public:
162  // default constructor
164  {
165  // initialized to the default values
166  this->m_Label = 0;
167  this->m_Sum = NumericTraits< RealType >::ZeroValue();
168 
169  const unsigned int imageDimension = itkGetStaticConstMacro(ImageDimension);
170 
171  //m_BoundingBox.resize(imageDimension*2);
172  for ( unsigned int i = 0; i < imageDimension * 2; i += 2 )
173  {
176  }
177 
178  m_BoundingBoxVolume = 0;
179  m_BoundingBoxSize.Fill(0);
180  m_PixelIndices.clear();
181  m_Centroid.Fill(0);
182  m_WeightedCentroid.Fill(0);
183  m_ZeroOrderMoment = 0;
184  m_FirstOrderRawMoments.Fill(0);
185  m_FirstOrderWeightedRawMoments.Fill(0);
186  m_Eigenvalues.resize(ImageDimension);
187  m_Eigenvalues.clear();
188  m_Eigenvectors.set_size(ImageDimension, ImageDimension);
189  m_Eigenvectors.fill(0);
190  m_AxesLength.Fill(0);
191  m_Eccentricity = 1;
192  m_Elongation = 1;
193  m_Orientation = 0;
194  LabelPointType emptyPoint;
195  emptyPoint.Fill(0);
196  unsigned int numberOfVertices = 1 << ImageDimension;
197  m_OrientedBoundingBoxVertices.resize(numberOfVertices, emptyPoint);
198  m_OrientedBoundingBoxVolume = 0;
199  m_OrientedBoundingBoxSize.Fill(0);
200  m_OrientedLabelImage = LabelImageType::New();
201  m_OrientedIntensityImage = IntensityImageType::New();
202  m_OrientedBoundingBoxOrigin.Fill(0);
203  m_RotationMatrix.set_size(ImageDimension, ImageDimension);
204  m_RotationMatrix.fill(0.0);
205 
206  m_SecondOrderRawMoments.set_size(ImageDimension, ImageDimension);
207  m_SecondOrderCentralMoments.set_size(ImageDimension, ImageDimension);
208  for ( unsigned int i = 0; i < ImageDimension; i++ )
209  {
210  for ( unsigned int j = 0; j < ImageDimension; j++ )
211  {
212  m_SecondOrderRawMoments(i, j) = 0;
213  m_SecondOrderCentralMoments(i, j) = 0;
214  }
215  }
216  }
217 
242  typename LabelImageType::Pointer m_OrientedLabelImage;
243  typename IntensityImageType::Pointer m_OrientedIntensityImage;
246  };
247 
249  // Map from the label to the class storing all of the geometry information.
250  typedef itksys::hash_map< LabelPixelType, LabelGeometry > MapType;
251  typedef typename itksys::hash_map< LabelPixelType, LabelGeometry >::iterator MapIterator;
252  typedef typename itksys::hash_map< LabelPixelType, LabelGeometry >::const_iterator MapConstIterator;
253 
254  // Macros for enabling the calculation of additional features.
255  itkGetMacro(CalculatePixelIndices, bool);
256  itkBooleanMacro(CalculatePixelIndices);
257  void SetCalculatePixelIndices(const bool value)
258  {
259  // CalculateOrientedBoundingBox, CalculateOrientedLabelImage, and
260  // CalculateOrientedIntensityImage all need CalculatePixelIndices to be
261  // turned
262  // on if they are turned on. So, CalculatePixelIndices cannot be
263  // turned off if any of these flags are turned on.
264  if ( value == false )
265  {
266  if ( ( this->m_CalculateOrientedBoundingBox == true )
267  || ( this->m_CalculateOrientedLabelRegions == true )
268  || ( this->m_CalculateOrientedIntensityRegions == true ) )
269  {
270  // We cannot change the value, so return.
271  return;
272  }
273  }
274 
275  if ( this->m_CalculatePixelIndices != value )
276  {
277  this->m_CalculatePixelIndices = value;
278  this->Modified();
279  }
280  }
281 
282  itkGetMacro(CalculateOrientedBoundingBox, bool);
283  itkBooleanMacro(CalculateOrientedBoundingBox);
284  void SetCalculateOrientedBoundingBox(const bool value)
285  {
286  if ( this->m_CalculateOrientedBoundingBox != value )
287  {
288  this->m_CalculateOrientedBoundingBox = value;
289  this->Modified();
290  }
291 
292  // CalculateOrientedBoundingBox needs
293  // CalculatePixelIndices to be turned on.
294  if ( value == true )
295  {
296  this->SetCalculatePixelIndices(true);
297  }
298  }
299 
300  itkGetMacro(CalculateOrientedLabelRegions, bool);
301  itkBooleanMacro(CalculateOrientedLabelRegions);
302  void SetCalculateOrientedLabelRegions(const bool value)
303  {
304  if ( this->m_CalculateOrientedLabelRegions != value )
305  {
306  this->m_CalculateOrientedLabelRegions = value;
307  this->Modified();
308 
309  // CalculateOrientedLabelImage needs
310  // CalculateOrientedBoundingBox to be turned on.
311  if ( value == true )
312  {
313  SetCalculateOrientedBoundingBox(true);
314  }
315  }
316  }
317 
318  itkGetMacro(CalculateOrientedIntensityRegions, bool);
319  itkBooleanMacro(CalculateOrientedIntensityRegions);
321  {
322  if ( this->m_CalculateOrientedIntensityRegions != value )
323  {
324  this->m_CalculateOrientedIntensityRegions = value;
325  this->Modified();
326 
327  // CalculateOrientedIntensityImage needs
328  // CalculateOrientedBoundingBox to be turned on.
329  if ( value == true )
330  {
331  this->SetCalculateOrientedBoundingBox(true);
332  }
333  }
334  }
335 
337  void SetIntensityInput(const TIntensityImage *input)
338  {
339  // Process object is not const-correct so the const casting is required.
340  this->SetNthInput( 1, const_cast< TIntensityImage * >( input ) );
341  }
342 
344  const TIntensityImage * GetIntensityInput() const
345  {
346  return static_cast< TIntensityImage * >( const_cast< DataObject * >( this->ProcessObject::GetInput(1) ) );
347  }
348 
351  bool HasLabel(LabelPixelType label) const
352  {
353  return m_LabelGeometryMapper.find(label) != m_LabelGeometryMapper.end();
354  }
355 
358  {
359  return m_LabelGeometryMapper.size();
360  }
361 
363  {
364  return this->GetNumberOfObjects();
365  }
366 
368  std::vector< LabelPixelType > GetLabels() const
369  {
370  return m_AllLabels;
371  }
372 
374  LabelIndicesType GetPixelIndices(LabelPixelType label) const;
375 
378  SizeValueType GetVolume(LabelPixelType label) const;
379 
381  //std::vector< SizeValueType > GetAllCounts() const;
382 
384  RealType GetIntegratedIntensity(LabelPixelType label) const;
385 
387  LabelPointType GetCentroid(LabelPixelType label) const;
388 
390  LabelPointType GetWeightedCentroid(LabelPixelType label) const;
391 
393  VectorType GetEigenvalues(LabelPixelType label) const;
394 
396  MatrixType GetEigenvectors(LabelPixelType label) const;
397 
399  AxesLengthType GetAxesLength(LabelPixelType label) const;
400 
403  RealType GetMinorAxisLength(LabelPixelType label) const;
404 
407  RealType GetMajorAxisLength(LabelPixelType label) const;
408 
410  RealType GetEccentricity(LabelPixelType label) const;
411 
414  RealType GetElongation(LabelPixelType label) const;
415 
417  RealType GetOrientation(LabelPixelType label) const;
418 
422  BoundingBoxType GetBoundingBox(LabelPixelType label) const;
423 
425  RealType GetBoundingBoxVolume(LabelPixelType label) const;
426 
428  LabelSizeType GetBoundingBoxSize(LabelPixelType label) const;
429 
436  BoundingBoxVerticesType GetOrientedBoundingBoxVertices(LabelPixelType label) const;
437 
439  RealType GetOrientedBoundingBoxVolume(LabelPixelType label) const;
440 
442  LabelPointType GetOrientedBoundingBoxSize(LabelPixelType label) const;
443 
445  LabelPointType GetOrientedBoundingBoxOrigin(LabelPixelType label) const;
446 
449  MatrixType GetRotationMatrix(LabelPixelType label) const;
450 
452  RegionType GetRegion(LabelPixelType label) const;
453 
455  TLabelImage * GetOrientedLabelImage(LabelPixelType label) const;
456 
459  TIntensityImage * GetOrientedIntensityImage(LabelPixelType label) const;
460 
461 #ifdef ITK_USE_CONCEPT_CHECKING
462  // Begin concept checking
463  itkConceptMacro( InputHasNumericTraitsCheck,
465  // End concept checking
466 #endif
467 
468 protected:
471  void PrintSelf(std::ostream & os, Indent indent) const ITK_OVERRIDE;
472 
473  void GenerateData() ITK_OVERRIDE;
474 
475 private:
476  ITK_DISALLOW_COPY_AND_ASSIGN(LabelGeometryImageFilter);
477 
478  bool CalculateOrientedBoundingBoxVertices(vnl_symmetric_eigensystem< double > eig, LabelGeometry & m_LabelGeometry);
479 
480  bool m_CalculatePixelIndices;
481  bool m_CalculateOrientedBoundingBox;
482  bool m_CalculateOrientedLabelRegions;
483  bool m_CalculateOrientedIntensityRegions;
484 
485  MapType m_LabelGeometryMapper;
486  LabelGeometry m_LabelGeometry;
487  LabelsType m_AllLabels;
488 
490 }; // end of class
491 
492 } // end namespace itk
493 
494 #ifndef ITK_MANUAL_INSTANTIATION
495 #include "itkLabelGeometryImageFilter.hxx"
496 #endif
497 
498 #endif
itk::FixedArray< float, itkGetStaticConstMacro(ImageDimension)*2 > BoundingBoxFloatType
Critical section locking class that can be allocated on the stack.
bool HasLabel(LabelPixelType label) const
Light weight base class for most itk classes.
itksys::hash_map< LabelPixelType, LabelGeometry >::const_iterator MapConstIterator
itk::FixedArray< RealType, itkGetStaticConstMacro(ImageDimension) > AxesLengthType
SimpleDataObjectDecorator< RealType > RealObjectType
void SetCalculateOrientedIntensityRegions(const bool value)
itksys::hash_map< LabelPixelType, LabelGeometry >::iterator MapIterator
signed long IndexValueType
Definition: itkIntTypes.h:150
TIntensityImage::IndexType IndexType
std::vector< LabelIndexType > LabelIndicesType
void SetCalculateOrientedBoundingBox(const bool value)
itksys::hash_map< LabelPixelType, LabelGeometry > MapType
unsigned long SizeValueType
Definition: itkIntTypes.h:143
Simulate a standard C array with copy semnatics.
Definition: itkFixedArray.h:50
TIntensityImage::RegionType RegionType
std::vector< LabelPixelType > LabelsType
itk::FixedArray< typename LabelIndexType::IndexValueType, itkGetStaticConstMacro(ImageDimension) > IndexArrayType
void SetCalculateOrientedLabelRegions(const bool value)
static ITK_CONSTEXPR_FUNC T max(const T &)
Decorates any &quot;simple&quot; data type (data types without smart pointers) with a DataObject API...
void SetCalculatePixelIndices(const bool value)
TIntensityImage::Pointer InputImagePointer
std::vector< LabelPixelType > GetLabels() const
Given a label map and an optional intensity image, compute geometric features.
DataObject * GetInput(const DataObjectIdentifierType &key)
Return an input.
static ITK_CONSTEXPR_FUNC T NonpositiveMin()
void SetIntensityInput(const TIntensityImage *input)
SmartPointer< const Self > ConstPointer
std::vector< LabelPointType > BoundingBoxVerticesType
ImageToImageFilter< TLabelImage, TIntensityImage > Superclass
Base class for filters that take an image as input and produce an image as output.
FixedArray< float, itkGetStaticConstMacro(ImageDimension) > m_AxesLength
const TIntensityImage * GetIntensityInput() const
Control indentation during Print() invocation.
Definition: itkIndent.h:49
Define additional traits for native types such as int or float.
#define itkConceptMacro(name, concept)
itk::FixedArray< typename LabelIndexType::IndexValueType, itkGetStaticConstMacro(ImageDimension)*2 > BoundingBoxType
NumericTraits< PixelType >::RealType RealType
Base class for all data objects in ITK.