ITK  4.2.0
Insight Segmentation and Registration Toolkit
itkImageBase.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 /*=========================================================================
19  *
20  * Portions of this file are subject to the VTK Toolkit Version 3 copyright.
21  *
22  * Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
23  *
24  * For complete copyright, license and disclaimer of warranty information
25  * please refer to the NOTICE file at the top of the ITK source tree.
26  *
27  *=========================================================================*/
28 #ifndef __itkImageBase_h
29 #define __itkImageBase_h
30 
31 #include "itkDataObject.h"
32 
33 #include "itkImageRegion.h"
34 #include "itkMatrix.h"
35 #include "itkObjectFactory.h"
36 #include "itkOffset.h"
37 #include "itkFixedArray.h"
38 #include "itkImageHelper.h"
39 //HACK: vnl/vnl_matrix_fixed.txx is needed here?
40 // to avoid undefined symbol vnl_matrix_fixed<double, 8u, 8u>::set_identity()", referenced from
41 #include "vnl/vnl_matrix_fixed.txx"
42 
43 #include "itkImageRegion.h"
45 
46 /* Forward declaration (ImageTransformHelper include's ImageBase) */
47 template< unsigned int NImageDimension, unsigned int R, unsigned int C >
48 class ImageTransformHelper;
49 
50 namespace itk
51 {
52 //HACK: Need to remove this function also
53 #if 1
54 
60 template< typename TImage >
62  itkStaticConstMacro(ImageDimension, unsigned int, TImage::ImageDimension);
63 };
64 #endif
65 
123 template< unsigned int VImageDimension = 2 >
124 class ITK_EXPORT ImageBase:public DataObject
125 {
126 public:
128  typedef ImageBase Self;
132 
134  itkNewMacro(Self);
135 
137  itkTypeMacro(ImageBase, DataObject);
138 
143  itkStaticConstMacro(ImageDimension, unsigned int, VImageDimension);
144 
148 
153 
157 
160 
165  typedef double SpacingValueType;
167 
170  typedef double PointValueType;
172 
177 
179  void Initialize();
180 
182  static unsigned int GetImageDimension()
183  { return VImageDimension; }
184 
189  itkSetMacro(Origin, PointType);
190  virtual void SetOrigin(const double origin[VImageDimension]);
191  virtual void SetOrigin(const float origin[VImageDimension]);
193 
219  virtual void SetDirection(const DirectionType direction);
220 
224  itkGetConstReferenceMacro(Direction, DirectionType);
225 
229  itkGetConstReferenceMacro(InverseDirection, DirectionType);
230 
235  itkGetConstReferenceMacro(Spacing, SpacingType);
236 
241  itkGetConstReferenceMacro(Origin, PointType);
242 
249  virtual void Allocate() {}
250 
257  virtual void SetLargestPossibleRegion(const RegionType & region);
258 
265  virtual const RegionType & GetLargestPossibleRegion() const
266  { return m_LargestPossibleRegion; }
267 
271  virtual void SetBufferedRegion(const RegionType & region);
272 
276  virtual const RegionType & GetBufferedRegion() const
277  { return m_BufferedRegion; }
278 
286  virtual void SetRequestedRegion(const RegionType & region);
287 
295  virtual void SetRequestedRegion( const DataObject *data );
296 
301  virtual const RegionType & GetRequestedRegion() const
302  { return m_RequestedRegion; }
303 
307  virtual void SetRegions(const RegionType& region)
308  {
309  this->SetLargestPossibleRegion(region);
310  this->SetBufferedRegion(region);
311  this->SetRequestedRegion(region);
312  }
314 
315  virtual void SetRegions(const SizeType& size)
316  {
317  RegionType region; region.SetSize(size);
318 
319  this->SetLargestPossibleRegion(region);
320  this->SetBufferedRegion(region);
321  this->SetRequestedRegion(region);
322  }
323 
334  const OffsetValueType * GetOffsetTable() const { return m_OffsetTable; }
336 
343  inline OffsetValueType ComputeOffset(const IndexType & ind) const
344  {
345  OffsetValueType offset = 0;
346 
347  ImageHelper< VImageDimension, VImageDimension >::ComputeOffset(this->GetBufferedRegion().GetIndex(),
348  ind,
349  m_OffsetTable,
350  offset);
351  return offset;
352  /* NON TEMPLATE_META_PROGRAMMING_LOOP_UNROLLING data version
353  * Leaving here for documentation purposes
354  * OffsetValueType ComputeOffset(const IndexType & ind) const
355  * {
356  * // need to add bounds checking for the region/buffer?
357  * OffsetValueType offset = 0;
358  * const IndexType & bufferedRegionIndex = this->GetBufferedRegion().GetIndex();
359  * // data is arranged as [][][][slice][row][col]
360  * // with Index[0] = col, Index[1] = row, Index[2] = slice
361  * for ( int i = VImageDimension - 1; i > 0; i-- )
362  * {
363  * offset += ( ind[i] - bufferedRegionIndex[i] ) * m_OffsetTable[i];
364  * }
365  * offset += ( ind[0] - bufferedRegionIndex[0] );
366  * return offset;
367  * }
368  */
369  }
370 
378  inline IndexType ComputeIndex(OffsetValueType offset) const
379  {
380  IndexType index;
381  const IndexType & bufferedRegionIndex = this->GetBufferedRegion().GetIndex();
383 
385  offset,
386  m_OffsetTable,
387  index);
388  return index;
389  /* NON TEMPLATE_META_PROGRAMMING_LOOP_UNROLLING data version
390  * Leaving here for documentation purposes
391  * IndexType ComputeIndex(OffsetValueType offset) const
392  * {
393  * IndexType index;
394  * const IndexType & bufferedRegionIndex = this->GetBufferedRegion().GetIndex();
395  * for ( int i = VImageDimension - 1; i > 0; i-- )
396  * {
397  * index[i] = static_cast< IndexValueType >( offset / m_OffsetTable[i] );
398  * offset -= ( index[i] * m_OffsetTable[i] );
399  * index[i] += bufferedRegionIndex[i];
400  * }
401  * index[0] = bufferedRegionIndex[0] + static_cast< IndexValueType >( offset );
402  * return index;
403  * }
404  */
405 
406  }
407 
414  virtual void SetSpacing(const SpacingType & spacing);
415  virtual void SetSpacing(const double spacing[VImageDimension]);
416  virtual void SetSpacing(const float spacing[VImageDimension]);
418 
423  template< class TCoordRep >
424  bool TransformPhysicalPointToIndex(
426  IndexType & index) const
427  {
429  this->m_PhysicalPointToIndex, this->m_Origin, point, index);
430 
431  // Now, check to see if the index is within allowed bounds
432  const bool isInside = this->GetLargestPossibleRegion().IsInside(index);
433  return isInside;
434  /* NON TEMPLATE_META_PROGRAMMING_LOOP_UNROLLING data version
435  * Leaving here for documentation purposes
436  * template< class TCoordRep >
437  * bool TransformPhysicalPointToIndex(
438  * const Point< TCoordRep, VImageDimension > & point,
439  * IndexType & index) const
440  * {
441  * for ( unsigned int i = 0; i < VImageDimension; i++ )
442  * {
443  * TCoordRep sum = NumericTraits< TCoordRep >::Zero;
444  * for ( unsigned int j = 0; j < VImageDimension; j++ )
445  * {
446  * sum += this->m_PhysicalPointToIndex[i][j] * ( point[j] - this->m_Origin[j] );
447  * }
448  * index[i] = Math::RoundHalfIntegerUp< IndexValueType >(sum);
449  * }
450  * // Now, check to see if the index is within allowed bounds
451  * const bool isInside = this->GetLargestPossibleRegion().IsInside(index);
452  * return isInside;
453  * }
454  */
455  }
456 
461  template< class TCoordRep >
462  bool TransformPhysicalPointToContinuousIndex(
465  {
467 
468  for ( unsigned int k = 0; k < VImageDimension; k++ )
469  {
470  cvector[k] = point[k] - this->m_Origin[k];
471  }
472  cvector = m_PhysicalPointToIndex * cvector;
473  for ( unsigned int i = 0; i < VImageDimension; i++ )
474  {
475  index[i] = static_cast< TCoordRep >( cvector[i] );
476  }
477 
478  // Now, check to see if the index is within allowed bounds
479  const bool isInside = this->GetLargestPossibleRegion().IsInside(index);
480 
481  return isInside;
482  }
483 
488  template< class TCoordRep >
489  void TransformContinuousIndexToPhysicalPoint(
492  {
493  for ( unsigned int r = 0; r < VImageDimension; r++ )
494  {
495  TCoordRep sum = NumericTraits< TCoordRep >::Zero;
496  for ( unsigned int c = 0; c < VImageDimension; c++ )
497  {
498  sum += this->m_IndexToPhysicalPoint(r, c) * index[c];
499  }
500  point[r] = sum + this->m_Origin[r];
501  }
502  }
504 
510  template< class TCoordRep >
511  void TransformIndexToPhysicalPoint(
512  const IndexType & index,
514  {
516  this->m_IndexToPhysicalPoint, this->m_Origin, index, point);
517  /* NON TEMPLATE_META_PROGRAMMING_LOOP_UNROLLING data version
518  * Leaving here for documentation purposes
519  * template< class TCoordRep >
520  * void TransformIndexToPhysicalPoint(
521  * const IndexType & index,
522  * Point< TCoordRep, VImageDimension > & point) const
523  * {
524  * for ( unsigned int i = 0; i < VImageDimension; i++ )
525  * {
526  * point[i] = this->m_Origin[i];
527  * for ( unsigned int j = 0; j < VImageDimension; j++ )
528  * {
529  * point[i] += m_IndexToPhysicalPoint[i][j] * index[j];
530  * }
531  * }
532  * }
533  */
534  }
536 
548  template< class TCoordRep >
549  void TransformLocalVectorToPhysicalVector(
550  const FixedArray< TCoordRep, VImageDimension > & inputGradient,
551  FixedArray< TCoordRep, VImageDimension > & outputGradient) const
552  {
553  //
554  //TODO: This temporary implementation should be replaced with Template
555  // MetaProgramming.
556  //
557  const DirectionType & direction = this->GetDirection();
558 
559  for ( unsigned int i = 0; i < VImageDimension; i++ )
560  {
561  typedef typename NumericTraits< TCoordRep >::AccumulateType CoordSumType;
562  CoordSumType sum = NumericTraits< CoordSumType >::Zero;
563  for ( unsigned int j = 0; j < VImageDimension; j++ )
564  {
565  sum += direction[i][j] * inputGradient[j];
566  }
567  outputGradient[i] = static_cast< TCoordRep >( sum );
568  }
569  }
570 
579  template< class TCoordRep >
580  void TransformPhysicalVectorToLocalVector(
581  const FixedArray< TCoordRep, VImageDimension > & inputGradient,
582  FixedArray< TCoordRep, VImageDimension > & outputGradient) const
583  {
584  //
585  //TODO: This temporary implementation should be replaced with Template
586  // MetaProgramming.
587  //
588  const DirectionType & inverseDirection = this->GetInverseDirection();
589 
590  for ( unsigned int i = 0; i < VImageDimension; i++ )
591  {
592  typedef typename NumericTraits< TCoordRep >::AccumulateType CoordSumType;
593  CoordSumType sum = NumericTraits< CoordSumType >::Zero;
594  for ( unsigned int j = 0; j < VImageDimension; j++ )
595  {
596  sum += inverseDirection[i][j] * inputGradient[j];
597  }
598  outputGradient[i] = static_cast< TCoordRep >( sum );
599  }
600  }
601 
611  virtual void CopyInformation(const DataObject *data);
612 
623  virtual void Graft(const DataObject *data);
624 
632  virtual void UpdateOutputInformation();
633 
641  virtual void UpdateOutputData();
642 
646  virtual void SetRequestedRegionToLargestPossibleRegion();
647 
657  virtual bool RequestedRegionIsOutsideOfTheBufferedRegion();
658 
667  virtual bool VerifyRequestedRegion();
668 
687  virtual unsigned int GetNumberOfComponentsPerPixel() const;
688  virtual void SetNumberOfComponentsPerPixel(unsigned int);
690 
691 protected:
692  ImageBase();
693  ~ImageBase();
694  virtual void PrintSelf(std::ostream & os, Indent indent) const;
695 
700  void ComputeOffsetTable();
701 
707  virtual void ComputeIndexToPhysicalPointMatrices();
708 
709 protected:
717 
722 
727  virtual void InitializeBufferedRegion(void);
728 
729 private:
730  ImageBase(const Self &); //purposely not implemented
731  void operator=(const Self &); //purposely not implemented
732 
733  OffsetValueType m_OffsetTable[VImageDimension + 1];
734 
738 };
739 } // end namespace itk
740 
741 // Define instantiation macro for this template.
742 #define ITK_TEMPLATE_ImageBase(_, EXPORT, TypeX, TypeY) \
743  namespace itk \
744  { \
745  _( 1 ( class EXPORT ImageBase< ITK_TEMPLATE_1 TypeX > ) ) \
746  namespace Templates \
747  { \
748  typedef ImageBase< ITK_TEMPLATE_1 TypeX > ImageBase##TypeY; \
749  } \
750  }
751 
752 #if ITK_TEMPLATE_EXPLICIT
753 //template <unsigned int VImageDimension> const unsigned int
754 // itk::ImageBase<VImageDimension>::ImageDimension;
755 #include "Templates/itkImageBase+-.h"
756 #endif
757 
758 #if ITK_TEMPLATE_TXX
759 #include "itkImageBase.hxx"
760 #endif
761 
762 #endif
763