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 Allocate() {};
00207
00214 virtual void SetLargestPossibleRegion(const RegionType ®ion);
00215
00222 virtual const RegionType& GetLargestPossibleRegion() const
00223 { return m_LargestPossibleRegion;};
00224
00228 virtual void SetBufferedRegion(const RegionType ®ion);
00229
00233 virtual const RegionType& GetBufferedRegion() const
00234 { return m_BufferedRegion;};
00235
00243 virtual void SetRequestedRegion(const RegionType ®ion);
00244
00252 virtual void SetRequestedRegion(DataObject *data);
00253
00258 virtual const RegionType& GetRequestedRegion() const
00259 { return m_RequestedRegion;};
00260
00271 const OffsetValueType *GetOffsetTable() const { return m_OffsetTable; };
00273
00282 #ifdef ITK_USE_TEMPLATE_META_PROGRAMMING_LOOP_UNROLLING
00283 inline OffsetValueType ComputeOffset(const IndexType &ind) const
00284 {
00285 OffsetValueType offset = 0;
00286 ImageHelper<VImageDimension,VImageDimension>::ComputeOffset(this->GetBufferedRegion().GetIndex(),
00287 ind,
00288 m_OffsetTable,
00289 offset);
00290 return offset;
00291 }
00292 #else
00293 OffsetValueType ComputeOffset(const IndexType &ind) const
00294 {
00295
00296 OffsetValueType offset=0;
00297 const IndexType &bufferedRegionIndex = this->GetBufferedRegion().GetIndex();
00298
00299
00300
00301 for (int i=VImageDimension-1; i > 0; i--)
00302 {
00303 offset += (ind[i] - bufferedRegionIndex[i])*m_OffsetTable[i];
00304 }
00305 offset += (ind[0] - bufferedRegionIndex[0]);
00306
00307 return offset;
00308 }
00309 #endif
00310
00317 #ifdef ITK_USE_TEMPLATE_META_PROGRAMMING_LOOP_UNROLLING
00318 inline IndexType ComputeIndex(OffsetValueType offset) const
00319 {
00320 IndexType index;
00321 const IndexType &bufferedRegionIndex = this->GetBufferedRegion().GetIndex();
00322 ImageHelper<VImageDimension,VImageDimension>::ComputeIndex(bufferedRegionIndex,
00323 offset,
00324 m_OffsetTable,
00325 index);
00326 return index;
00327 }
00328 #else
00329 IndexType ComputeIndex(OffsetValueType offset) const
00330 {
00331 IndexType index;
00332 const IndexType &bufferedRegionIndex = this->GetBufferedRegion().GetIndex();
00334
00335 for (int i=VImageDimension-1; i > 0; i--)
00336 {
00337 index[i] = static_cast<IndexValueType>(offset / m_OffsetTable[i]);
00338 offset -= (index[i] * m_OffsetTable[i]);
00339 index[i] += bufferedRegionIndex[i];
00340 }
00341 index[0] = bufferedRegionIndex[0] + static_cast<IndexValueType>(offset);
00342
00343 return index;
00344 }
00345 #endif
00346
00353 virtual void SetSpacing (const SpacingType & spacing);
00354 virtual void SetSpacing (const double spacing[VImageDimension]);
00355 virtual void SetSpacing (const float spacing[VImageDimension]);
00357
00358
00365 #ifdef ITK_USE_TEMPLATE_META_PROGRAMMING_LOOP_UNROLLING
00366 template<class TCoordRep>
00367 bool TransformPhysicalPointToIndex(
00368 const Point<TCoordRep, VImageDimension>& point,
00369 IndexType & index ) const
00370 {
00371 ImageTransformHelper<VImageDimension,VImageDimension-1,VImageDimension-1>::TransformPhysicalPointToIndex(
00372 this->m_PhysicalPointToIndex, this->m_Origin, point, index);
00373
00374
00375 const bool isInside = this->GetLargestPossibleRegion().IsInside( index );
00376 return isInside;
00377 }
00378 #else
00379 template<class TCoordRep>
00380 bool TransformPhysicalPointToIndex(
00381 const Point<TCoordRep, VImageDimension>& point,
00382 IndexType & index ) const
00383 {
00384 for (unsigned int i = 0; i < VImageDimension; i++)
00385 {
00386 TCoordRep sum = NumericTraits<TCoordRep>::Zero;
00387 for (unsigned int j = 0; j < VImageDimension; j++)
00388 {
00389 sum += this->m_PhysicalPointToIndex[i][j] * (point[j] - this->m_Origin[j]);
00390 }
00391 #ifdef ITK_USE_CENTERED_PIXEL_COORDINATES_CONSISTENTLY
00392 index[i] = static_cast< IndexValueType>( itk::Math::RoundHalfIntegerUp( sum ) );
00393 #else
00394 index[i] = static_cast< IndexValueType>( sum );
00395 #endif
00396 }
00397
00398
00399 const bool isInside = this->GetLargestPossibleRegion().IsInside( index );
00400
00401 return isInside;
00402 }
00403 #endif
00404
00409 template<class TCoordRep>
00410 bool TransformPhysicalPointToContinuousIndex(
00411 const Point<TCoordRep, VImageDimension>& point,
00412 ContinuousIndex<TCoordRep, VImageDimension>& index ) const
00413 {
00414 Vector<double, VImageDimension> cvector;
00415
00416 for( unsigned int k = 0; k < VImageDimension; k++ )
00417 {
00418 cvector[k] = point[k] - this->m_Origin[k];
00419 }
00420 cvector = m_PhysicalPointToIndex * cvector;
00421 for( unsigned int i = 0; i < VImageDimension; i++ )
00422 {
00423 index[i] = static_cast<TCoordRep>(cvector[i]);
00424 }
00425
00426
00427 const bool isInside = this->GetLargestPossibleRegion().IsInside( index );
00428
00429 return isInside;
00430 }
00431
00432
00437 template<class TCoordRep>
00438 void TransformContinuousIndexToPhysicalPoint(
00439 const ContinuousIndex<TCoordRep, VImageDimension>& index,
00440 Point<TCoordRep, VImageDimension>& point ) const
00441 {
00442 for( unsigned int r=0; r<VImageDimension; r++)
00443 {
00444 TCoordRep sum = NumericTraits<TCoordRep>::Zero;
00445 for( unsigned int c=0; c<VImageDimension; c++ )
00446 {
00447 sum += this->m_IndexToPhysicalPoint(r,c) * index[c];
00448 }
00449 point[r] = sum + this->m_Origin[r];
00450 }
00451 }
00453
00459 #ifdef ITK_USE_TEMPLATE_META_PROGRAMMING_LOOP_UNROLLING
00460 template<class TCoordRep>
00461 void TransformIndexToPhysicalPoint(
00462 const IndexType & index,
00463 Point<TCoordRep, VImageDimension>& point ) const
00464 {
00465 ImageTransformHelper<VImageDimension,VImageDimension-1,VImageDimension-1>::TransformIndexToPhysicalPoint(
00466 this->m_IndexToPhysicalPoint, this->m_Origin, index, point);
00467 }
00468 #else
00469 template<class TCoordRep>
00470 void TransformIndexToPhysicalPoint(
00471 const IndexType & index,
00472 Point<TCoordRep, VImageDimension>& point ) const
00473 {
00474 for (unsigned int i = 0; i < VImageDimension; i++)
00475 {
00476 point[i] = this->m_Origin[i];
00477 for (unsigned int j = 0; j < VImageDimension; j++)
00478 {
00479 point[i] += m_IndexToPhysicalPoint[i][j] * index[j];
00480 }
00481 }
00482 }
00483 #endif
00484
00485
00486
00504 template<class TCoordRep>
00505 void TransformLocalVectorToPhysicalVector(
00506 const FixedArray<TCoordRep, VImageDimension> & inputGradient,
00507 FixedArray<TCoordRep, VImageDimension> & outputGradient ) const
00508 {
00509
00510
00511
00512 #ifdef ITK_USE_ORIENTED_IMAGE_DIRECTION
00513 const DirectionType & direction = this->GetDirection();
00514 for (unsigned int i = 0; i < VImageDimension; i++)
00515 {
00516 typedef typename NumericTraits<TCoordRep>::AccumulateType CoordSumType;
00517 CoordSumType sum = NumericTraits<CoordSumType>::Zero;
00518 for (unsigned int j = 0; j < VImageDimension; j++)
00519 {
00520 sum += direction[i][j] * inputGradient[j];
00521 }
00522 outputGradient[i] = static_cast<TCoordRep>( sum );
00523 }
00524 #else
00525 for (unsigned int i = 0; i < VImageDimension; i++)
00526 {
00527 outputGradient[i] = inputGradient[i];
00528 }
00529 #endif
00530 }
00532
00542 virtual void CopyInformation(const DataObject *data);
00543
00554 virtual void Graft(const DataObject *data);
00555
00563 virtual void UpdateOutputInformation();
00564
00568 virtual void SetRequestedRegionToLargestPossibleRegion();
00569
00579 virtual bool RequestedRegionIsOutsideOfTheBufferedRegion();
00580
00589 virtual bool VerifyRequestedRegion();
00590
00607 virtual unsigned int GetNumberOfComponentsPerPixel() const;
00608 virtual void SetNumberOfComponentsPerPixel( unsigned int );
00610
00611 protected:
00612 ImageBase();
00613 ~ImageBase();
00614 virtual void PrintSelf(std::ostream& os, Indent indent) const;
00615
00620 void ComputeOffsetTable();
00621
00627 virtual void ComputeIndexToPhysicalPointMatrices();
00628
00629 protected:
00633 SpacingType m_Spacing;
00634 PointType m_Origin;
00635 DirectionType m_Direction;
00636
00639 DirectionType m_IndexToPhysicalPoint;
00640 DirectionType m_PhysicalPointToIndex;
00641
00646 virtual void InitializeBufferedRegion(void);
00647
00648 private:
00649 ImageBase(const Self&);
00650 void operator=(const Self&);
00651
00652 OffsetValueType m_OffsetTable[VImageDimension+1];
00653
00654 RegionType m_LargestPossibleRegion;
00655 RegionType m_RequestedRegion;
00656 RegionType m_BufferedRegion;
00657
00658 };
00659
00660 }
00661
00662
00663 #define ITK_TEMPLATE_ImageBase(_, EXPORT, x, y) namespace itk { \
00664 _(1(class EXPORT ImageBase< ITK_TEMPLATE_1 x >)) \
00665 namespace Templates { typedef ImageBase< ITK_TEMPLATE_1 x > ImageBase##y; } \
00666 }
00667
00668 #if ITK_TEMPLATE_EXPLICIT
00669 # include "Templates/itkImageBase+-.h"
00670 #endif
00671
00672 #if ITK_TEMPLATE_TXX
00673 # include "itkImageBase.txx"
00674 #endif
00675
00676 #endif
00677