ITK  4.4.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 >
49 
50 namespace itk
51 {
52 
110 template< unsigned int VImageDimension = 2 >
111 class ITK_EXPORT ImageBase:public DataObject
112 {
113 public:
115  typedef ImageBase Self;
119 
121  itkNewMacro(Self);
122 
124  itkTypeMacro(ImageBase, DataObject);
125 
130  itkStaticConstMacro(ImageDimension, unsigned int, VImageDimension);
131 
135 
140 
144 
147 
152  typedef double SpacingValueType;
154 
157  typedef double PointValueType;
159 
164 
166  void Initialize();
167 
169  static unsigned int GetImageDimension()
170  { return VImageDimension; }
171 
176  itkSetMacro(Origin, PointType);
177  virtual void SetOrigin(const double origin[VImageDimension]);
178  virtual void SetOrigin(const float origin[VImageDimension]);
180 
206  virtual void SetDirection(const DirectionType direction);
207 
211  itkGetConstReferenceMacro(Direction, DirectionType);
212 
216  itkGetConstReferenceMacro(InverseDirection, DirectionType);
217 
222  itkGetConstReferenceMacro(Spacing, SpacingType);
223 
228  itkGetConstReferenceMacro(Origin, PointType);
229 
236  virtual void Allocate() {}
237 
244  virtual void SetLargestPossibleRegion(const RegionType & region);
245 
252  virtual const RegionType & GetLargestPossibleRegion() const
253  { return m_LargestPossibleRegion; }
254 
258  virtual void SetBufferedRegion(const RegionType & region);
259 
263  virtual const RegionType & GetBufferedRegion() const
264  { return m_BufferedRegion; }
265 
273  virtual void SetRequestedRegion(const RegionType & region);
274 
282  virtual void SetRequestedRegion( const DataObject *data );
283 
288  virtual const RegionType & GetRequestedRegion() const
289  { return m_RequestedRegion; }
290 
294  virtual void SetRegions(const RegionType& region)
295  {
296  this->SetLargestPossibleRegion(region);
297  this->SetBufferedRegion(region);
298  this->SetRequestedRegion(region);
299  }
301 
302  virtual void SetRegions(const SizeType& size)
303  {
304  RegionType region; region.SetSize(size);
305 
306  this->SetLargestPossibleRegion(region);
307  this->SetBufferedRegion(region);
308  this->SetRequestedRegion(region);
309  }
310 
321  const OffsetValueType * GetOffsetTable() const { return m_OffsetTable; }
323 
330  inline OffsetValueType ComputeOffset(const IndexType & ind) const
331  {
332  OffsetValueType offset = 0;
333 
334  ImageHelper< VImageDimension, VImageDimension >::ComputeOffset(this->GetBufferedRegion().GetIndex(),
335  ind,
336  m_OffsetTable,
337  offset);
338  return offset;
339  /* NON TEMPLATE_META_PROGRAMMING_LOOP_UNROLLING data version
340  * Leaving here for documentation purposes
341  * OffsetValueType ComputeOffset(const IndexType & ind) const
342  * {
343  * // need to add bounds checking for the region/buffer?
344  * OffsetValueType offset = 0;
345  * const IndexType & bufferedRegionIndex = this->GetBufferedRegion().GetIndex();
346  * // data is arranged as [][][][slice][row][col]
347  * // with Index[0] = col, Index[1] = row, Index[2] = slice
348  * for ( int i = VImageDimension - 1; i > 0; i-- )
349  * {
350  * offset += ( ind[i] - bufferedRegionIndex[i] ) * m_OffsetTable[i];
351  * }
352  * offset += ( ind[0] - bufferedRegionIndex[0] );
353  * return offset;
354  * }
355  */
356  }
357 
365  inline IndexType ComputeIndex(OffsetValueType offset) const
366  {
367  IndexType index;
368  const IndexType & bufferedRegionIndex = this->GetBufferedRegion().GetIndex();
370 
372  offset,
373  m_OffsetTable,
374  index);
375  return index;
376  /* NON TEMPLATE_META_PROGRAMMING_LOOP_UNROLLING data version
377  * Leaving here for documentation purposes
378  * IndexType ComputeIndex(OffsetValueType offset) const
379  * {
380  * IndexType index;
381  * const IndexType & bufferedRegionIndex = this->GetBufferedRegion().GetIndex();
382  * for ( int i = VImageDimension - 1; i > 0; i-- )
383  * {
384  * index[i] = static_cast< IndexValueType >( offset / m_OffsetTable[i] );
385  * offset -= ( index[i] * m_OffsetTable[i] );
386  * index[i] += bufferedRegionIndex[i];
387  * }
388  * index[0] = bufferedRegionIndex[0] + static_cast< IndexValueType >( offset );
389  * return index;
390  * }
391  */
392 
393  }
394 
401  virtual void SetSpacing(const SpacingType & spacing);
402  virtual void SetSpacing(const double spacing[VImageDimension]);
403  virtual void SetSpacing(const float spacing[VImageDimension]);
405 
410  template< class TCoordRep >
411  bool TransformPhysicalPointToIndex(
413  IndexType & index) const
414  {
416  this->m_PhysicalPointToIndex, this->m_Origin, point, index);
417 
418  // Now, check to see if the index is within allowed bounds
419  const bool isInside = this->GetLargestPossibleRegion().IsInside(index);
420  return isInside;
421  /* NON TEMPLATE_META_PROGRAMMING_LOOP_UNROLLING data version
422  * Leaving here for documentation purposes
423  * template< class TCoordRep >
424  * bool TransformPhysicalPointToIndex(
425  * const Point< TCoordRep, VImageDimension > & point,
426  * IndexType & index) const
427  * {
428  * for ( unsigned int i = 0; i < VImageDimension; i++ )
429  * {
430  * TCoordRep sum = NumericTraits< TCoordRep >::Zero;
431  * for ( unsigned int j = 0; j < VImageDimension; j++ )
432  * {
433  * sum += this->m_PhysicalPointToIndex[i][j] * ( point[j] - this->m_Origin[j] );
434  * }
435  * index[i] = Math::RoundHalfIntegerUp< IndexValueType >(sum);
436  * }
437  * // Now, check to see if the index is within allowed bounds
438  * const bool isInside = this->GetLargestPossibleRegion().IsInside(index);
439  * return isInside;
440  * }
441  */
442  }
443 
448  template< class TCoordRep >
449  bool TransformPhysicalPointToContinuousIndex(
452  {
454 
455  for ( unsigned int k = 0; k < VImageDimension; k++ )
456  {
457  cvector[k] = point[k] - this->m_Origin[k];
458  }
459  cvector = m_PhysicalPointToIndex * cvector;
460  for ( unsigned int i = 0; i < VImageDimension; i++ )
461  {
462  index[i] = static_cast< TCoordRep >( cvector[i] );
463  }
464 
465  // Now, check to see if the index is within allowed bounds
466  const bool isInside = this->GetLargestPossibleRegion().IsInside(index);
467 
468  return isInside;
469  }
470 
475  template< class TCoordRep >
476  void TransformContinuousIndexToPhysicalPoint(
479  {
480  for ( unsigned int r = 0; r < VImageDimension; r++ )
481  {
482  TCoordRep sum = NumericTraits< TCoordRep >::Zero;
483  for ( unsigned int c = 0; c < VImageDimension; c++ )
484  {
485  sum += this->m_IndexToPhysicalPoint(r, c) * index[c];
486  }
487  point[r] = sum + this->m_Origin[r];
488  }
489  }
491 
497  template< class TCoordRep >
498  void TransformIndexToPhysicalPoint(
499  const IndexType & index,
501  {
503  this->m_IndexToPhysicalPoint, this->m_Origin, index, point);
504  /* NON TEMPLATE_META_PROGRAMMING_LOOP_UNROLLING data version
505  * Leaving here for documentation purposes
506  * template< class TCoordRep >
507  * void TransformIndexToPhysicalPoint(
508  * const IndexType & index,
509  * Point< TCoordRep, VImageDimension > & point) const
510  * {
511  * for ( unsigned int i = 0; i < VImageDimension; i++ )
512  * {
513  * point[i] = this->m_Origin[i];
514  * for ( unsigned int j = 0; j < VImageDimension; j++ )
515  * {
516  * point[i] += m_IndexToPhysicalPoint[i][j] * index[j];
517  * }
518  * }
519  * }
520  */
521  }
523 
535  template< class TCoordRep >
536  void TransformLocalVectorToPhysicalVector(
537  const FixedArray< TCoordRep, VImageDimension > & inputGradient,
538  FixedArray< TCoordRep, VImageDimension > & outputGradient) const
539  {
540  //
541  //TODO: This temporary implementation should be replaced with Template
542  // MetaProgramming.
543  //
544  const DirectionType & direction = this->GetDirection();
545 
546  for ( unsigned int i = 0; i < VImageDimension; i++ )
547  {
548  typedef typename NumericTraits< TCoordRep >::AccumulateType CoordSumType;
549  CoordSumType sum = NumericTraits< CoordSumType >::Zero;
550  for ( unsigned int j = 0; j < VImageDimension; j++ )
551  {
552  sum += direction[i][j] * inputGradient[j];
553  }
554  outputGradient[i] = static_cast< TCoordRep >( sum );
555  }
556  }
557 
566  template< class TCoordRep >
567  void TransformPhysicalVectorToLocalVector(
568  const FixedArray< TCoordRep, VImageDimension > & inputGradient,
569  FixedArray< TCoordRep, VImageDimension > & outputGradient) const
570  {
571  //
572  //TODO: This temporary implementation should be replaced with Template
573  // MetaProgramming.
574  //
575  const DirectionType & inverseDirection = this->GetInverseDirection();
576 
577  for ( unsigned int i = 0; i < VImageDimension; i++ )
578  {
579  typedef typename NumericTraits< TCoordRep >::AccumulateType CoordSumType;
580  CoordSumType sum = NumericTraits< CoordSumType >::Zero;
581  for ( unsigned int j = 0; j < VImageDimension; j++ )
582  {
583  sum += inverseDirection[i][j] * inputGradient[j];
584  }
585  outputGradient[i] = static_cast< TCoordRep >( sum );
586  }
587  }
588 
598  virtual void CopyInformation(const DataObject *data);
599 
610  virtual void Graft(const DataObject *data);
611 
619  virtual void UpdateOutputInformation();
620 
628  virtual void UpdateOutputData();
629 
633  virtual void SetRequestedRegionToLargestPossibleRegion();
634 
644  virtual bool RequestedRegionIsOutsideOfTheBufferedRegion();
645 
654  virtual bool VerifyRequestedRegion();
655 
674  virtual unsigned int GetNumberOfComponentsPerPixel() const;
675  virtual void SetNumberOfComponentsPerPixel(unsigned int);
677 
678 protected:
679  ImageBase();
680  ~ImageBase();
681  virtual void PrintSelf(std::ostream & os, Indent indent) const;
682 
687  void ComputeOffsetTable();
688 
694  virtual void ComputeIndexToPhysicalPointMatrices();
695 
696 protected:
704 
709 
714  virtual void InitializeBufferedRegion(void);
715 
716 private:
717  ImageBase(const Self &); //purposely not implemented
718  void operator=(const Self &); //purposely not implemented
719 
720  OffsetValueType m_OffsetTable[VImageDimension + 1];
721 
725 };
726 } // end namespace itk
727 
728 #ifndef ITK_MANUAL_INSTANTIATION
729 #include "itkImageBase.hxx"
730 #endif
731 
732 #endif
733