ITK  4.2.0
Insight Segmentation and Registration Toolkit
itkImageBase.h
Go to the documentation of this file.
00001 /*=========================================================================
00002  *
00003  *  Copyright Insight Software Consortium
00004  *
00005  *  Licensed under the Apache License, Version 2.0 (the "License");
00006  *  you may not use this file except in compliance with the License.
00007  *  You may obtain a copy of the License at
00008  *
00009  *         http://www.apache.org/licenses/LICENSE-2.0.txt
00010  *
00011  *  Unless required by applicable law or agreed to in writing, software
00012  *  distributed under the License is distributed on an "AS IS" BASIS,
00013  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00014  *  See the License for the specific language governing permissions and
00015  *  limitations under the License.
00016  *
00017  *=========================================================================*/
00018 /*=========================================================================
00019  *
00020  *  Portions of this file are subject to the VTK Toolkit Version 3 copyright.
00021  *
00022  *  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
00023  *
00024  *  For complete copyright, license and disclaimer of warranty information
00025  *  please refer to the NOTICE file at the top of the ITK source tree.
00026  *
00027  *=========================================================================*/
00028 #ifndef __itkImageBase_h
00029 #define __itkImageBase_h
00030 
00031 #include "itkDataObject.h"
00032 
00033 #include "itkImageRegion.h"
00034 #include "itkMatrix.h"
00035 #include "itkObjectFactory.h"
00036 #include "itkOffset.h"
00037 #include "itkFixedArray.h"
00038 #include "itkImageHelper.h"
00039 //HACK:  vnl/vnl_matrix_fixed.txx is needed here?
00040 //      to avoid undefined symbol vnl_matrix_fixed<double, 8u, 8u>::set_identity()", referenced from
00041 #include "vnl/vnl_matrix_fixed.txx"
00042 
00043 #include "itkImageRegion.h"
00044 #include "itkImageTransformHelper.h"
00045 
00046 /* Forward declaration (ImageTransformHelper include's ImageBase) */
00047 template< unsigned int NImageDimension, unsigned int R, unsigned int C >
00048 class ImageTransformHelper;
00049 
00050 namespace itk
00051 {
00052 //HACK:  Need to remove this function also
00053 #if 1
00054 
00060 template< typename TImage >
00061 struct GetImageDimension {
00062   itkStaticConstMacro(ImageDimension, unsigned int, TImage::ImageDimension);
00063 };
00064 #endif
00065 
00123 template< unsigned int VImageDimension = 2 >
00124 class ITK_EXPORT ImageBase:public DataObject
00125 {
00126 public:
00128   typedef ImageBase                  Self;
00129   typedef DataObject                 Superclass;
00130   typedef SmartPointer< Self >       Pointer;
00131   typedef SmartPointer< const Self > ConstPointer;
00132 
00134   itkNewMacro(Self);
00135 
00137   itkTypeMacro(ImageBase, DataObject);
00138 
00143   itkStaticConstMacro(ImageDimension, unsigned int, VImageDimension);
00144 
00146   typedef Index< VImageDimension >           IndexType;
00147   typedef typename IndexType::IndexValueType IndexValueType;
00148 
00151   typedef Offset< VImageDimension >            OffsetType;
00152   typedef typename OffsetType::OffsetValueType OffsetValueType;
00153 
00155   typedef Size< VImageDimension >          SizeType;
00156   typedef typename SizeType::SizeValueType SizeValueType;
00157 
00159   typedef ImageRegion< VImageDimension > RegionType;
00160 
00165   typedef double                                      SpacingValueType;
00166   typedef Vector< SpacingValueType, VImageDimension > SpacingType;
00167 
00170   typedef double                                   PointValueType;
00171   typedef Point< PointValueType, VImageDimension > PointType;
00172 
00176   typedef Matrix< double, VImageDimension, VImageDimension > DirectionType;
00177 
00179   void Initialize();
00180 
00182   static unsigned int GetImageDimension()
00183   { return VImageDimension; }
00184 
00189   itkSetMacro(Origin, PointType);
00190   virtual void SetOrigin(const double origin[VImageDimension]);
00191   virtual void SetOrigin(const float origin[VImageDimension]);
00193 
00219   virtual void SetDirection(const DirectionType direction);
00220 
00224   itkGetConstReferenceMacro(Direction, DirectionType);
00225 
00229   itkGetConstReferenceMacro(InverseDirection, DirectionType);
00230 
00235   itkGetConstReferenceMacro(Spacing, SpacingType);
00236 
00241   itkGetConstReferenceMacro(Origin, PointType);
00242 
00249   virtual void Allocate() {}
00250 
00257   virtual void SetLargestPossibleRegion(const RegionType & region);
00258 
00265   virtual const RegionType & GetLargestPossibleRegion() const
00266   { return m_LargestPossibleRegion; }
00267 
00271   virtual void SetBufferedRegion(const RegionType & region);
00272 
00276   virtual const RegionType & GetBufferedRegion() const
00277   { return m_BufferedRegion; }
00278 
00286   virtual void SetRequestedRegion(const RegionType & region);
00287 
00295   virtual void SetRequestedRegion( const DataObject *data );
00296 
00301   virtual const RegionType & GetRequestedRegion() const
00302   { return m_RequestedRegion; }
00303 
00307   virtual void SetRegions(const RegionType& region)
00308   {
00309     this->SetLargestPossibleRegion(region);
00310     this->SetBufferedRegion(region);
00311     this->SetRequestedRegion(region);
00312   }
00314 
00315   virtual void SetRegions(const SizeType& size)
00316   {
00317     RegionType region; region.SetSize(size);
00318 
00319     this->SetLargestPossibleRegion(region);
00320     this->SetBufferedRegion(region);
00321     this->SetRequestedRegion(region);
00322   }
00323 
00334   const OffsetValueType * GetOffsetTable() const { return m_OffsetTable; }
00336 
00343   inline OffsetValueType ComputeOffset(const IndexType & ind) const
00344   {
00345     OffsetValueType offset = 0;
00346 
00347     ImageHelper< VImageDimension, VImageDimension >::ComputeOffset(this->GetBufferedRegion().GetIndex(),
00348                                                                    ind,
00349                                                                    m_OffsetTable,
00350                                                                    offset);
00351     return offset;
00352     /* NON TEMPLATE_META_PROGRAMMING_LOOP_UNROLLING data version
00353      * Leaving here for documentation purposes
00354      * OffsetValueType ComputeOffset(const IndexType & ind) const
00355      * {
00356      *   // need to add bounds checking for the region/buffer?
00357      *   OffsetValueType   offset = 0;
00358      *   const IndexType & bufferedRegionIndex = this->GetBufferedRegion().GetIndex();
00359      *   // data is arranged as [][][][slice][row][col]
00360      *   // with Index[0] = col, Index[1] = row, Index[2] = slice
00361      *   for ( int i = VImageDimension - 1; i > 0; i-- )
00362      *     {
00363      *     offset += ( ind[i] - bufferedRegionIndex[i] ) * m_OffsetTable[i];
00364      *     }
00365      *   offset += ( ind[0] - bufferedRegionIndex[0] );
00366      *   return offset;
00367      * }
00368      */
00369   }
00370 
00378   inline IndexType ComputeIndex(OffsetValueType offset) const
00379   {
00380     IndexType         index;
00381     const IndexType & bufferedRegionIndex = this->GetBufferedRegion().GetIndex();
00383 
00384     ImageHelper< VImageDimension, VImageDimension >::ComputeIndex(bufferedRegionIndex,
00385                                                                   offset,
00386                                                                   m_OffsetTable,
00387                                                                   index);
00388     return index;
00389     /* NON TEMPLATE_META_PROGRAMMING_LOOP_UNROLLING data version
00390      * Leaving here for documentation purposes
00391      * IndexType ComputeIndex(OffsetValueType offset) const
00392      * {
00393      *   IndexType         index;
00394      *   const IndexType & bufferedRegionIndex = this->GetBufferedRegion().GetIndex();
00395      *   for ( int i = VImageDimension - 1; i > 0; i-- )
00396      *     {
00397      *     index[i] = static_cast< IndexValueType >( offset / m_OffsetTable[i] );
00398      *     offset -= ( index[i] * m_OffsetTable[i] );
00399      *     index[i] += bufferedRegionIndex[i];
00400      *     }
00401      *   index[0] = bufferedRegionIndex[0] + static_cast< IndexValueType >( offset );
00402      *   return index;
00403      * }
00404     */
00405 
00406   }
00407 
00414   virtual void SetSpacing(const SpacingType & spacing);
00415   virtual void SetSpacing(const double spacing[VImageDimension]);
00416   virtual void SetSpacing(const float spacing[VImageDimension]);
00418 
00423   template< class TCoordRep >
00424   bool TransformPhysicalPointToIndex(
00425     const Point< TCoordRep, VImageDimension > & point,
00426     IndexType & index) const
00427   {
00428     ImageTransformHelper< VImageDimension, VImageDimension - 1, VImageDimension - 1 >::TransformPhysicalPointToIndex(
00429       this->m_PhysicalPointToIndex, this->m_Origin, point, index);
00430 
00431     // Now, check to see if the index is within allowed bounds
00432     const bool isInside = this->GetLargestPossibleRegion().IsInside(index);
00433     return isInside;
00434     /* NON TEMPLATE_META_PROGRAMMING_LOOP_UNROLLING data version
00435      * Leaving here for documentation purposes
00436      * template< class TCoordRep >
00437      * bool TransformPhysicalPointToIndex(
00438      *   const Point< TCoordRep, VImageDimension > & point,
00439      *   IndexType & index) const
00440      * {
00441      *   for ( unsigned int i = 0; i < VImageDimension; i++ )
00442      *     {
00443      *     TCoordRep sum = NumericTraits< TCoordRep >::Zero;
00444      *     for ( unsigned int j = 0; j < VImageDimension; j++ )
00445      *       {
00446      *       sum += this->m_PhysicalPointToIndex[i][j] * ( point[j] - this->m_Origin[j] );
00447      *       }
00448      *     index[i] = Math::RoundHalfIntegerUp< IndexValueType >(sum);
00449      *     }
00450      *   // Now, check to see if the index is within allowed bounds
00451      *   const bool isInside = this->GetLargestPossibleRegion().IsInside(index);
00452      *   return isInside;
00453      * }
00454      */
00455   }
00456 
00461   template< class TCoordRep >
00462   bool TransformPhysicalPointToContinuousIndex(
00463     const Point< TCoordRep, VImageDimension > & point,
00464     ContinuousIndex< TCoordRep, VImageDimension > & index) const
00465   {
00466     Vector< double, VImageDimension > cvector;
00467 
00468     for ( unsigned int k = 0; k < VImageDimension; k++ )
00469       {
00470       cvector[k] = point[k] - this->m_Origin[k];
00471       }
00472     cvector = m_PhysicalPointToIndex * cvector;
00473     for ( unsigned int i = 0; i < VImageDimension; i++ )
00474       {
00475       index[i] = static_cast< TCoordRep >( cvector[i] );
00476       }
00477 
00478     // Now, check to see if the index is within allowed bounds
00479     const bool isInside = this->GetLargestPossibleRegion().IsInside(index);
00480 
00481     return isInside;
00482   }
00483 
00488   template< class TCoordRep >
00489   void TransformContinuousIndexToPhysicalPoint(
00490     const ContinuousIndex< TCoordRep, VImageDimension > & index,
00491     Point< TCoordRep, VImageDimension > & point) const
00492   {
00493     for ( unsigned int r = 0; r < VImageDimension; r++ )
00494       {
00495       TCoordRep sum = NumericTraits< TCoordRep >::Zero;
00496       for ( unsigned int c = 0; c < VImageDimension; c++ )
00497         {
00498         sum += this->m_IndexToPhysicalPoint(r, c) * index[c];
00499         }
00500       point[r] = sum + this->m_Origin[r];
00501       }
00502   }
00504 
00510   template< class TCoordRep >
00511   void TransformIndexToPhysicalPoint(
00512     const IndexType & index,
00513     Point< TCoordRep, VImageDimension > & point) const
00514   {
00515     ImageTransformHelper< VImageDimension, VImageDimension - 1, VImageDimension - 1 >::TransformIndexToPhysicalPoint(
00516       this->m_IndexToPhysicalPoint, this->m_Origin, index, point);
00517     /* NON TEMPLATE_META_PROGRAMMING_LOOP_UNROLLING data version
00518      * Leaving here for documentation purposes
00519      * template< class TCoordRep >
00520      * void TransformIndexToPhysicalPoint(
00521      *   const IndexType & index,
00522      *   Point< TCoordRep, VImageDimension > & point) const
00523      * {
00524      *   for ( unsigned int i = 0; i < VImageDimension; i++ )
00525      *     {
00526      *     point[i] = this->m_Origin[i];
00527      *     for ( unsigned int j = 0; j < VImageDimension; j++ )
00528      *       {
00529      *       point[i] += m_IndexToPhysicalPoint[i][j] * index[j];
00530      *       }
00531      *     }
00532      * }
00533      */
00534   }
00536 
00548   template< class TCoordRep >
00549   void TransformLocalVectorToPhysicalVector(
00550     const FixedArray< TCoordRep, VImageDimension > & inputGradient,
00551     FixedArray< TCoordRep, VImageDimension > & outputGradient) const
00552   {
00553     //
00554     //TODO: This temporary implementation should be replaced with Template
00555     // MetaProgramming.
00556     //
00557     const DirectionType & direction = this->GetDirection();
00558 
00559     for ( unsigned int i = 0; i < VImageDimension; i++ )
00560       {
00561       typedef typename NumericTraits< TCoordRep >::AccumulateType CoordSumType;
00562       CoordSumType sum = NumericTraits< CoordSumType >::Zero;
00563       for ( unsigned int j = 0; j < VImageDimension; j++ )
00564         {
00565         sum += direction[i][j] * inputGradient[j];
00566         }
00567       outputGradient[i] = static_cast< TCoordRep >( sum );
00568       }
00569   }
00570 
00579   template< class TCoordRep >
00580   void TransformPhysicalVectorToLocalVector(
00581     const FixedArray< TCoordRep, VImageDimension > & inputGradient,
00582     FixedArray< TCoordRep, VImageDimension > & outputGradient) const
00583   {
00584     //
00585     //TODO: This temporary implementation should be replaced with Template
00586     // MetaProgramming.
00587     //
00588     const DirectionType & inverseDirection = this->GetInverseDirection();
00589 
00590     for ( unsigned int i = 0; i < VImageDimension; i++ )
00591       {
00592       typedef typename NumericTraits< TCoordRep >::AccumulateType CoordSumType;
00593       CoordSumType sum = NumericTraits< CoordSumType >::Zero;
00594       for ( unsigned int j = 0; j < VImageDimension; j++ )
00595         {
00596         sum += inverseDirection[i][j] * inputGradient[j];
00597         }
00598       outputGradient[i] = static_cast< TCoordRep >( sum );
00599       }
00600   }
00601 
00611   virtual void CopyInformation(const DataObject *data);
00612 
00623   virtual void Graft(const DataObject *data);
00624 
00632   virtual void UpdateOutputInformation();
00633 
00641   virtual void UpdateOutputData();
00642 
00646   virtual void SetRequestedRegionToLargestPossibleRegion();
00647 
00657   virtual bool RequestedRegionIsOutsideOfTheBufferedRegion();
00658 
00667   virtual bool VerifyRequestedRegion();
00668 
00687   virtual unsigned int GetNumberOfComponentsPerPixel() const;
00688   virtual void SetNumberOfComponentsPerPixel(unsigned int);
00690 
00691 protected:
00692   ImageBase();
00693   ~ImageBase();
00694   virtual void PrintSelf(std::ostream & os, Indent indent) const;
00695 
00700   void ComputeOffsetTable();
00701 
00707   virtual void ComputeIndexToPhysicalPointMatrices();
00708 
00709 protected:
00713   SpacingType m_Spacing;
00714   PointType m_Origin;
00715   DirectionType m_Direction;
00716   DirectionType m_InverseDirection;
00717 
00720   DirectionType m_IndexToPhysicalPoint;
00721   DirectionType m_PhysicalPointToIndex;
00722 
00727   virtual void InitializeBufferedRegion(void);
00728 
00729 private:
00730   ImageBase(const Self &);      //purposely not implemented
00731   void operator=(const Self &); //purposely not implemented
00732 
00733   OffsetValueType m_OffsetTable[VImageDimension + 1];
00734 
00735   RegionType m_LargestPossibleRegion;
00736   RegionType m_RequestedRegion;
00737   RegionType m_BufferedRegion;
00738 };
00739 } // end namespace itk
00740 
00741 // Define instantiation macro for this template.
00742 #define ITK_TEMPLATE_ImageBase(_, EXPORT, TypeX, TypeY)         \
00743   namespace itk                                                 \
00744   {                                                             \
00745   _( 1 ( class EXPORT ImageBase< ITK_TEMPLATE_1 TypeX > ) )     \
00746   namespace Templates                                           \
00747   {                                                             \
00748   typedef ImageBase< ITK_TEMPLATE_1 TypeX > ImageBase##TypeY; \
00749   }                                                             \
00750   }
00751 
00752 #if ITK_TEMPLATE_EXPLICIT
00753 //template <unsigned int VImageDimension> const unsigned int
00754 // itk::ImageBase<VImageDimension>::ImageDimension;
00755 #include "Templates/itkImageBase+-.h"
00756 #endif
00757 
00758 #if ITK_TEMPLATE_TXX
00759 #include "itkImageBase.hxx"
00760 #endif
00761 
00762 #endif
00763