00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #ifndef __itkImageBase_h
00021 #define __itkImageBase_h
00022
00023 #include "itkDataObject.h"
00024
00025 #include "itkImageRegion.h"
00026 #include "itkIndex.h"
00027 #include "itkObjectFactory.h"
00028 #include "itkOffset.h"
00029 #include "itkPoint.h"
00030 #include "itkSize.h"
00031 #include "itkFixedArray.h"
00032 #include "itkPoint.h"
00033 #include "itkMatrix.h"
00034 #include "itkContinuousIndex.h"
00035 #include "itkImageHelper.h"
00036 #include <vnl/vnl_matrix_fixed.txx>
00037
00038 #include "itkImageRegion.h"
00039
00040 #ifdef ITK_USE_TEMPLATE_META_PROGRAMMING_LOOP_UNROLLING
00041 #include "itkImageTransformHelper.h"
00042 #endif
00043
00044 namespace itk
00045 {
00046
00053 template <typename TImage>
00054 struct GetImageDimension
00055 {
00056 itkStaticConstMacro(ImageDimension, unsigned int, TImage::ImageDimension);
00057 };
00058
00086 template<unsigned int VImageDimension=2>
00087 class ITK_EXPORT ImageBase : public DataObject
00088 {
00089 public:
00091 typedef ImageBase Self;
00092 typedef DataObject Superclass;
00093 typedef SmartPointer<Self> Pointer;
00094 typedef SmartPointer<const Self> ConstPointer;
00095
00097 itkNewMacro(Self);
00098
00100 itkTypeMacro(ImageBase, DataObject);
00101
00106 itkStaticConstMacro(ImageDimension, unsigned int, VImageDimension );
00107
00109 typedef Index<VImageDimension> IndexType;
00110 typedef typename IndexType::IndexValueType IndexValueType;
00111
00114 typedef Offset<VImageDimension> OffsetType;
00115 typedef typename OffsetType::OffsetValueType OffsetValueType;
00116
00118 typedef Size<VImageDimension> SizeType;
00119 typedef typename SizeType::SizeValueType SizeValueType;
00120
00122 typedef ImageRegion<VImageDimension> RegionType;
00123
00128 typedef Vector<double, VImageDimension> SpacingType;
00129
00132 typedef Point<double, VImageDimension> PointType;
00133
00137 typedef Matrix<double, VImageDimension, VImageDimension> DirectionType;
00138
00140 void Initialize();
00141
00143 static unsigned int GetImageDimension()
00144 { return VImageDimension; }
00145
00150 itkSetMacro(Origin, PointType);
00151 virtual void SetOrigin( const double origin[VImageDimension] );
00152 virtual void SetOrigin( const float origin[VImageDimension] );
00154
00181 virtual void SetDirection( const DirectionType direction );
00182
00186 itkGetConstReferenceMacro(Direction, DirectionType);
00187
00192 itkGetConstReferenceMacro(Spacing, SpacingType);
00193
00198 itkGetConstReferenceMacro(Origin, PointType);
00199
00206 virtual void SetLargestPossibleRegion(const RegionType ®ion);
00207
00214 virtual const RegionType& GetLargestPossibleRegion() const
00215 { return m_LargestPossibleRegion;};
00216
00220 virtual void SetBufferedRegion(const RegionType ®ion);
00221
00225 virtual const RegionType& GetBufferedRegion() const
00226 { return m_BufferedRegion;};
00227
00235 virtual void SetRequestedRegion(const RegionType ®ion);
00236
00244 virtual void SetRequestedRegion(DataObject *data);
00245
00250 virtual const RegionType& GetRequestedRegion() const
00251 { return m_RequestedRegion;};
00252
00263 const OffsetValueType *GetOffsetTable() const { return m_OffsetTable; };
00265
00274 #ifdef ITK_USE_TEMPLATE_META_PROGRAMMING_LOOP_UNROLLING
00275 inline OffsetValueType ComputeOffset(const IndexType &ind) const
00276 {
00277 OffsetValueType offset = 0;
00278 ImageHelper<VImageDimension,VImageDimension>::ComputeOffset(this->GetBufferedRegion().GetIndex(),
00279 ind,
00280 m_OffsetTable,
00281 offset);
00282 return offset;
00283 }
00284 #else
00285 OffsetValueType ComputeOffset(const IndexType &ind) const
00286 {
00287
00288 OffsetValueType offset=0;
00289 const IndexType &bufferedRegionIndex = this->GetBufferedRegion().GetIndex();
00290
00291
00292
00293 for (int i=VImageDimension-1; i > 0; i--)
00294 {
00295 offset += (ind[i] - bufferedRegionIndex[i])*m_OffsetTable[i];
00296 }
00297 offset += (ind[0] - bufferedRegionIndex[0]);
00298
00299 return offset;
00300 }
00301 #endif
00302
00309 #ifdef ITK_USE_TEMPLATE_META_PROGRAMMING_LOOP_UNROLLING
00310 inline IndexType ComputeIndex(OffsetValueType offset) const
00311 {
00312 IndexType index;
00313 const IndexType &bufferedRegionIndex = this->GetBufferedRegion().GetIndex();
00314 ImageHelper<VImageDimension,VImageDimension>::ComputeIndex(bufferedRegionIndex,
00315 offset,
00316 m_OffsetTable,
00317 index);
00318 return index;
00319 }
00320 #else
00321 IndexType ComputeIndex(OffsetValueType offset) const
00322 {
00323 IndexType index;
00324 const IndexType &bufferedRegionIndex = this->GetBufferedRegion().GetIndex();
00326
00327 for (int i=VImageDimension-1; i > 0; i--)
00328 {
00329 index[i] = static_cast<IndexValueType>(offset / m_OffsetTable[i]);
00330 offset -= (index[i] * m_OffsetTable[i]);
00331 index[i] += bufferedRegionIndex[i];
00332 }
00333 index[0] = bufferedRegionIndex[0] + static_cast<IndexValueType>(offset);
00334
00335 return index;
00336 }
00337 #endif
00338
00345 virtual void SetSpacing (const SpacingType & spacing);
00346 virtual void SetSpacing (const double spacing[VImageDimension]);
00347 virtual void SetSpacing (const float spacing[VImageDimension]);
00349
00350
00355 #ifdef ITK_USE_TEMPLATE_META_PROGRAMMING_LOOP_UNROLLING
00356 template<class TCoordRep>
00357 bool TransformPhysicalPointToIndex(
00358 const Point<TCoordRep, VImageDimension>& point,
00359 IndexType & index ) const
00360 {
00361 ImageTransformHelper<VImageDimension,VImageDimension-1,VImageDimension-1>::TransformPhysicalPointToIndex(
00362 this->m_PhysicalPointToIndex, this->m_Origin, point, index);
00363
00364
00365 const bool isInside = this->GetLargestPossibleRegion().IsInside( index );
00366 return isInside;
00367 }
00368 #else
00369 template<class TCoordRep>
00370 bool TransformPhysicalPointToIndex(
00371 const Point<TCoordRep, VImageDimension>& point,
00372 IndexType & index ) const
00373 {
00374 for (unsigned int i = 0; i < VImageDimension; i++)
00375 {
00376 TCoordRep sum = NumericTraits<TCoordRep>::Zero;
00377 for (unsigned int j = 0; j < VImageDimension; j++)
00378 {
00379 sum += this->m_PhysicalPointToIndex[i][j] * (point[j] - this->m_Origin[j]);
00380 }
00381 index[i] = static_cast< IndexValueType>( sum );
00382 }
00383
00384
00385 const bool isInside = this->GetLargestPossibleRegion().IsInside( index );
00386
00387 return isInside;
00388 }
00389 #endif
00390
00395 template<class TCoordRep>
00396 bool TransformPhysicalPointToContinuousIndex(
00397 const Point<TCoordRep, VImageDimension>& point,
00398 ContinuousIndex<TCoordRep, VImageDimension>& index ) const
00399 {
00400 Vector<double, VImageDimension> cvector;
00401
00402 for( unsigned int k = 0; k < VImageDimension; k++ )
00403 {
00404 cvector[k] = point[k] - this->m_Origin[k];
00405 }
00406 cvector = m_PhysicalPointToIndex * cvector;
00407 for( unsigned int i = 0; i < VImageDimension; i++ )
00408 {
00409 index[i] = static_cast<TCoordRep>(cvector[i]);
00410 }
00411
00412
00413 const bool isInside = this->GetLargestPossibleRegion().IsInside( index );
00414
00415 return isInside;
00416 }
00417
00418
00423 template<class TCoordRep>
00424 void TransformContinuousIndexToPhysicalPoint(
00425 const ContinuousIndex<TCoordRep, VImageDimension>& index,
00426 Point<TCoordRep, VImageDimension>& point ) const
00427 {
00428 for( unsigned int r=0; r<VImageDimension; r++)
00429 {
00430 TCoordRep sum = NumericTraits<TCoordRep>::Zero;
00431 for( unsigned int c=0; c<VImageDimension; c++ )
00432 {
00433 sum += this->m_IndexToPhysicalPoint(r,c) * index[c];
00434 }
00435 point[r] = sum + this->m_Origin[r];
00436 }
00437 }
00439
00445 #ifdef ITK_USE_TEMPLATE_META_PROGRAMMING_LOOP_UNROLLING
00446 template<class TCoordRep>
00447 void TransformIndexToPhysicalPoint(
00448 const IndexType & index,
00449 Point<TCoordRep, VImageDimension>& point ) const
00450 {
00451 ImageTransformHelper<VImageDimension,VImageDimension-1,VImageDimension-1>::TransformIndexToPhysicalPoint(
00452 this->m_IndexToPhysicalPoint, this->m_Origin, index, point);
00453 }
00454 #else
00455 template<class TCoordRep>
00456 void TransformIndexToPhysicalPoint(
00457 const IndexType & index,
00458 Point<TCoordRep, VImageDimension>& point ) const
00459 {
00460 for (unsigned int i = 0; i < VImageDimension; i++)
00461 {
00462 point[i] = this->m_Origin[i];
00463 for (unsigned int j = 0; j < VImageDimension; j++)
00464 {
00465 point[i] += m_IndexToPhysicalPoint[i][j] * index[j];
00466 }
00467 }
00468 }
00469 #endif
00470
00471
00472
00490 template<class TCoordRep>
00491 void TransformLocalVectorToPhysicalVector(
00492 const FixedArray<TCoordRep, VImageDimension> & inputGradient,
00493 FixedArray<TCoordRep, VImageDimension> & outputGradient ) const
00494 {
00495
00496
00497
00498 #ifdef ITK_USE_ORIENTED_IMAGE_DIRECTION
00499 const DirectionType & direction = this->GetDirection();
00500 for (unsigned int i = 0; i < VImageDimension; i++)
00501 {
00502 typedef typename NumericTraits<TCoordRep>::AccumulateType CoordSumType;
00503 CoordSumType sum = NumericTraits<CoordSumType>::Zero;
00504 for (unsigned int j = 0; j < VImageDimension; j++)
00505 {
00506 sum += direction[i][j] * inputGradient[j];
00507 }
00508 outputGradient[i] = static_cast<TCoordRep>( sum );
00509 }
00510 #else
00511 for (unsigned int i = 0; i < VImageDimension; i++)
00512 {
00513 outputGradient[i] = inputGradient[i];
00514 }
00515 #endif
00516 }
00518
00528 virtual void CopyInformation(const DataObject *data);
00529
00540 virtual void Graft(const DataObject *data);
00541
00549 virtual void UpdateOutputInformation();
00550
00554 virtual void SetRequestedRegionToLargestPossibleRegion();
00555
00565 virtual bool RequestedRegionIsOutsideOfTheBufferedRegion();
00566
00575 virtual bool VerifyRequestedRegion();
00576
00593 virtual unsigned int GetNumberOfComponentsPerPixel() const;
00594 virtual void SetNumberOfComponentsPerPixel( unsigned int );
00596
00597 protected:
00598 ImageBase();
00599 ~ImageBase();
00600 virtual void PrintSelf(std::ostream& os, Indent indent) const;
00601
00606 void ComputeOffsetTable();
00607
00613 virtual void ComputeIndexToPhysicalPointMatrices();
00614
00615 protected:
00619 SpacingType m_Spacing;
00620 PointType m_Origin;
00621 DirectionType m_Direction;
00622
00625 DirectionType m_IndexToPhysicalPoint;
00626 DirectionType m_PhysicalPointToIndex;
00627
00628 private:
00629 ImageBase(const Self&);
00630 void operator=(const Self&);
00631
00632 OffsetValueType m_OffsetTable[VImageDimension+1];
00633
00634 RegionType m_LargestPossibleRegion;
00635 RegionType m_RequestedRegion;
00636 RegionType m_BufferedRegion;
00637
00638 };
00639
00640 }
00641
00642
00643 #define ITK_TEMPLATE_ImageBase(_, EXPORT, x, y) namespace itk { \
00644 _(1(class EXPORT ImageBase< ITK_TEMPLATE_1 x >)) \
00645 namespace Templates { typedef ImageBase< ITK_TEMPLATE_1 x > ImageBase##y; } \
00646 }
00647
00648 #if ITK_TEMPLATE_EXPLICIT
00649 # include "Templates/itkImageBase+-.h"
00650 #endif
00651
00652 #if ITK_TEMPLATE_TXX
00653 # include "itkImageBase.txx"
00654 #endif
00655
00656 #endif
00657