ITK  4.0.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 
00094 template< unsigned int VImageDimension = 2 >
00095 class ITK_EXPORT ImageBase:public DataObject
00096 {
00097 public:
00099   typedef ImageBase                  Self;
00100   typedef DataObject                 Superclass;
00101   typedef SmartPointer< Self >       Pointer;
00102   typedef SmartPointer< const Self > ConstPointer;
00103 
00105   itkNewMacro(Self);
00106 
00108   itkTypeMacro(ImageBase, DataObject);
00109 
00114   itkStaticConstMacro(ImageDimension, unsigned int, VImageDimension);
00115 
00117   typedef Index< VImageDimension >           IndexType;
00118   typedef typename IndexType::IndexValueType IndexValueType;
00119 
00122   typedef Offset< VImageDimension >            OffsetType;
00123   typedef typename OffsetType::OffsetValueType OffsetValueType;
00124 
00126   typedef Size< VImageDimension >          SizeType;
00127   typedef typename SizeType::SizeValueType SizeValueType;
00128 
00131   typedef ImageRegion< VImageDimension > RegionType;
00132 
00137   typedef double                                      SpacingValueType;
00138   typedef Vector< SpacingValueType, VImageDimension > SpacingType;
00139 
00142   typedef double                                   PointValueType;
00143   typedef Point< PointValueType, VImageDimension > PointType;
00144 
00148   typedef Matrix< double, VImageDimension, VImageDimension > DirectionType;
00149 
00151   void Initialize();
00152 
00154   static unsigned int GetImageDimension()
00155   { return VImageDimension; }
00156 
00161   itkSetMacro(Origin, PointType);
00162   virtual void SetOrigin(const double origin[VImageDimension]);
00164 
00165   virtual void SetOrigin(const float origin[VImageDimension]);
00166 
00193   virtual void SetDirection(const DirectionType direction);
00194 
00198   itkGetConstReferenceMacro(Direction, DirectionType);
00199 
00203   itkGetConstReferenceMacro(InverseDirection, DirectionType);
00204 
00209   itkGetConstReferenceMacro(Spacing, SpacingType);
00210 
00215   itkGetConstReferenceMacro(Origin, PointType);
00216 
00223   virtual void Allocate() {}
00224 
00231   virtual void SetLargestPossibleRegion(const RegionType & region);
00232 
00239   virtual const RegionType & GetLargestPossibleRegion() const
00240   { return m_LargestPossibleRegion; }
00241 
00245   virtual void SetBufferedRegion(const RegionType & region);
00246 
00250   virtual const RegionType & GetBufferedRegion() const
00251   { return m_BufferedRegion; }
00252 
00260   virtual void SetRequestedRegion(const RegionType & region);
00261 
00269   virtual void SetRequestedRegion( const DataObject *data );
00270 
00275   virtual const RegionType & GetRequestedRegion() const
00276   { return m_RequestedRegion; }
00277 
00288   const OffsetValueType * GetOffsetTable() const { return m_OffsetTable; }
00290 
00297   inline OffsetValueType ComputeOffset(const IndexType & ind) const
00298   {
00299     OffsetValueType offset = 0;
00300 
00301     ImageHelper< VImageDimension, VImageDimension >::ComputeOffset(this->GetBufferedRegion().GetIndex(),
00302                                                                    ind,
00303                                                                    m_OffsetTable,
00304                                                                    offset);
00305     return offset;
00306     /* NON TEMPLATE_META_PROGRAMMING_LOOP_UNROLLING data version
00307      * Leaving here for documentation purposes
00308      * OffsetValueType ComputeOffset(const IndexType & ind) const
00309      * {
00310      *   // need to add bounds checking for the region/buffer?
00311      *   OffsetValueType   offset = 0;
00312      *   const IndexType & bufferedRegionIndex = this->GetBufferedRegion().GetIndex();
00313      *   // data is arranged as [][][][slice][row][col]
00314      *   // with Index[0] = col, Index[1] = row, Index[2] = slice
00315      *   for ( int i = VImageDimension - 1; i > 0; i-- )
00316      *     {
00317      *     offset += ( ind[i] - bufferedRegionIndex[i] ) * m_OffsetTable[i];
00318      *     }
00319      *   offset += ( ind[0] - bufferedRegionIndex[0] );
00320      *   return offset;
00321      * }
00322      */
00323   }
00324 
00332   inline IndexType ComputeIndex(OffsetValueType offset) const
00333   {
00334     IndexType         index;
00335     const IndexType & bufferedRegionIndex = this->GetBufferedRegion().GetIndex();
00337 
00338     ImageHelper< VImageDimension, VImageDimension >::ComputeIndex(bufferedRegionIndex,
00339                                                                   offset,
00340                                                                   m_OffsetTable,
00341                                                                   index);
00342     return index;
00343     /* NON TEMPLATE_META_PROGRAMMING_LOOP_UNROLLING data version
00344      * Leaving here for documentation purposes
00345      * IndexType ComputeIndex(OffsetValueType offset) const
00346      * {
00347      *   IndexType         index;
00348      *   const IndexType & bufferedRegionIndex = this->GetBufferedRegion().GetIndex();
00349      *   for ( int i = VImageDimension - 1; i > 0; i-- )
00350      *     {
00351      *     index[i] = static_cast< IndexValueType >( offset / m_OffsetTable[i] );
00352      *     offset -= ( index[i] * m_OffsetTable[i] );
00353      *     index[i] += bufferedRegionIndex[i];
00354      *     }
00355      *   index[0] = bufferedRegionIndex[0] + static_cast< IndexValueType >( offset );
00356      *   return index;
00357      * }
00358     */
00359 
00360   }
00361 
00368   virtual void SetSpacing(const SpacingType & spacing);
00369 
00370   virtual void SetSpacing(const double spacing[VImageDimension]);
00371 
00372   virtual void SetSpacing(const float spacing[VImageDimension]);
00373 
00378   template< class TCoordRep >
00379   bool TransformPhysicalPointToIndex(
00380     const Point< TCoordRep, VImageDimension > & point,
00381     IndexType & index) const
00382   {
00383     ImageTransformHelper< VImageDimension, VImageDimension - 1, VImageDimension - 1 >::TransformPhysicalPointToIndex(
00384       this->m_PhysicalPointToIndex, this->m_Origin, point, index);
00385 
00386     // Now, check to see if the index is within allowed bounds
00387     const bool isInside = this->GetLargestPossibleRegion().IsInside(index);
00388     return isInside;
00389     /* NON TEMPLATE_META_PROGRAMMING_LOOP_UNROLLING data version
00390      * Leaving here for documentation purposes
00391      * template< class TCoordRep >
00392      * bool TransformPhysicalPointToIndex(
00393      *   const Point< TCoordRep, VImageDimension > & point,
00394      *   IndexType & index) const
00395      * {
00396      *   for ( unsigned int i = 0; i < VImageDimension; i++ )
00397      *     {
00398      *     TCoordRep sum = NumericTraits< TCoordRep >::Zero;
00399      *     for ( unsigned int j = 0; j < VImageDimension; j++ )
00400      *       {
00401      *       sum += this->m_PhysicalPointToIndex[i][j] * ( point[j] - this->m_Origin[j] );
00402      *       }
00403      *     index[i] = Math::RoundHalfIntegerUp< IndexValueType >(sum);
00404      *     }
00405      *   // Now, check to see if the index is within allowed bounds
00406      *   const bool isInside = this->GetLargestPossibleRegion().IsInside(index);
00407      *   return isInside;
00408      * }
00409      */
00410   }
00411 
00416   template< class TCoordRep >
00417   bool TransformPhysicalPointToContinuousIndex(
00418     const Point< TCoordRep, VImageDimension > & point,
00419     ContinuousIndex< TCoordRep, VImageDimension > & index) const
00420   {
00421     Vector< double, VImageDimension > cvector;
00422 
00423     for ( unsigned int k = 0; k < VImageDimension; k++ )
00424       {
00425       cvector[k] = point[k] - this->m_Origin[k];
00426       }
00427     cvector = m_PhysicalPointToIndex * cvector;
00428     for ( unsigned int i = 0; i < VImageDimension; i++ )
00429       {
00430       index[i] = static_cast< TCoordRep >( cvector[i] );
00431       }
00432 
00433     // Now, check to see if the index is within allowed bounds
00434     const bool isInside = this->GetLargestPossibleRegion().IsInside(index);
00435 
00436     return isInside;
00437   }
00438 
00443   template< class TCoordRep >
00444   void TransformContinuousIndexToPhysicalPoint(
00445     const ContinuousIndex< TCoordRep, VImageDimension > & index,
00446     Point< TCoordRep, VImageDimension > & point) const
00447   {
00448     for ( unsigned int r = 0; r < VImageDimension; r++ )
00449       {
00450       TCoordRep sum = NumericTraits< TCoordRep >::Zero;
00451       for ( unsigned int c = 0; c < VImageDimension; c++ )
00452         {
00453         sum += this->m_IndexToPhysicalPoint(r, c) * index[c];
00454         }
00455       point[r] = sum + this->m_Origin[r];
00456       }
00457   }
00459 
00465   template< class TCoordRep >
00466   void TransformIndexToPhysicalPoint(
00467     const IndexType & index,
00468     Point< TCoordRep, VImageDimension > & point) const
00469   {
00470     ImageTransformHelper< VImageDimension, VImageDimension - 1, VImageDimension - 1 >::TransformIndexToPhysicalPoint(
00471       this->m_IndexToPhysicalPoint, this->m_Origin, index, point);
00472     /* NON TEMPLATE_META_PROGRAMMING_LOOP_UNROLLING data version
00473      * Leaving here for documentation purposes
00474      * template< class TCoordRep >
00475      * void TransformIndexToPhysicalPoint(
00476      *   const IndexType & index,
00477      *   Point< TCoordRep, VImageDimension > & point) const
00478      * {
00479      *   for ( unsigned int i = 0; i < VImageDimension; i++ )
00480      *     {
00481      *     point[i] = this->m_Origin[i];
00482      *     for ( unsigned int j = 0; j < VImageDimension; j++ )
00483      *       {
00484      *       point[i] += m_IndexToPhysicalPoint[i][j] * index[j];
00485      *       }
00486      *     }
00487      * }
00488      */
00489   }
00491 
00509   template< class TCoordRep >
00510   void TransformLocalVectorToPhysicalVector(
00511     const FixedArray< TCoordRep, VImageDimension > & inputGradient,
00512     FixedArray< TCoordRep, VImageDimension > & outputGradient) const
00513   {
00514     //
00515     //TODO: This temporary implementation should be replaced with Template
00516     // MetaProgramming.
00517     //
00518     const DirectionType & direction = this->GetDirection();
00519 
00520     for ( unsigned int i = 0; i < VImageDimension; i++ )
00521       {
00522       typedef typename NumericTraits< TCoordRep >::AccumulateType CoordSumType;
00523       CoordSumType sum = NumericTraits< CoordSumType >::Zero;
00524       for ( unsigned int j = 0; j < VImageDimension; j++ )
00525         {
00526         sum += direction[i][j] * inputGradient[j];
00527         }
00528       outputGradient[i] = static_cast< TCoordRep >( sum );
00529       }
00530   }
00531 
00540   template< class TCoordRep >
00541   void TransformPhysicalVectorToLocalVector(
00542     const FixedArray< TCoordRep, VImageDimension > & inputGradient,
00543     FixedArray< TCoordRep, VImageDimension > & outputGradient) const
00544   {
00545     //
00546     //TODO: This temporary implementation should be replaced with Template
00547     // MetaProgramming.
00548     //
00549     const DirectionType & inverseDirection = this->GetInverseDirection();
00550 
00551     for ( unsigned int i = 0; i < VImageDimension; i++ )
00552       {
00553       typedef typename NumericTraits< TCoordRep >::AccumulateType CoordSumType;
00554       CoordSumType sum = NumericTraits< CoordSumType >::Zero;
00555       for ( unsigned int j = 0; j < VImageDimension; j++ )
00556         {
00557         sum += inverseDirection[i][j] * inputGradient[j];
00558         }
00559       outputGradient[i] = static_cast< TCoordRep >( sum );
00560       }
00561   }
00562 
00572   virtual void CopyInformation(const DataObject *data);
00573 
00584   virtual void Graft(const DataObject *data);
00585 
00593   virtual void UpdateOutputInformation();
00594 
00602   virtual void UpdateOutputData();
00603 
00607   virtual void SetRequestedRegionToLargestPossibleRegion();
00608 
00618   virtual bool RequestedRegionIsOutsideOfTheBufferedRegion();
00619 
00628   virtual bool VerifyRequestedRegion();
00629 
00646   virtual unsigned int GetNumberOfComponentsPerPixel() const;
00647 
00648   virtual void SetNumberOfComponentsPerPixel(unsigned int);
00649 
00650 protected:
00651   ImageBase();
00652   ~ImageBase();
00653   virtual void PrintSelf(std::ostream & os, Indent indent) const;
00654 
00659   void ComputeOffsetTable();
00660 
00666   virtual void ComputeIndexToPhysicalPointMatrices();
00667 
00668 protected:
00672   SpacingType m_Spacing;
00673 
00674   PointType m_Origin;
00675 
00676   DirectionType m_Direction;
00677   DirectionType m_InverseDirection;
00678 
00681   DirectionType m_IndexToPhysicalPoint;
00682   DirectionType m_PhysicalPointToIndex;
00683 
00688   virtual void InitializeBufferedRegion(void);
00689 
00690 private:
00691   ImageBase(const Self &);      //purposely not implemented
00692   void operator=(const Self &); //purposely not implemented
00693 
00694   OffsetValueType m_OffsetTable[VImageDimension + 1];
00695 
00696   RegionType m_LargestPossibleRegion;
00697   RegionType m_RequestedRegion;
00698   RegionType m_BufferedRegion;
00699 };
00700 } // end namespace itk
00701 
00702 // Define instantiation macro for this template.
00703 #define ITK_TEMPLATE_ImageBase(_, EXPORT, TypeX, TypeY)         \
00704   namespace itk                                                 \
00705   {                                                             \
00706   _( 1 ( class EXPORT ImageBase< ITK_TEMPLATE_1 TypeX > ) )     \
00707   namespace Templates                                           \
00708   {                                                             \
00709   typedef ImageBase< ITK_TEMPLATE_1 TypeX > ImageBase##TypeY; \
00710   }                                                             \
00711   }
00712 
00713 #if ITK_TEMPLATE_EXPLICIT
00714 //template <unsigned int VImageDimension> const unsigned int
00715 // itk::ImageBase<VImageDimension>::ImageDimension;
00716 #include "Templates/itkImageBase+-.h"
00717 #endif
00718 
00719 #if ITK_TEMPLATE_TXX
00720 #include "itkImageBase.hxx"
00721 #endif
00722 
00723 #endif
00724