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 double SpacingValueType;
00129 typedef Vector<SpacingValueType, VImageDimension> SpacingType;
00130
00133 typedef double PointValueType;
00134 typedef Point<PointValueType, VImageDimension> PointType;
00135
00139 typedef Matrix<double, VImageDimension, VImageDimension> DirectionType;
00140
00142 void Initialize();
00143
00145 static unsigned int GetImageDimension()
00146 { return VImageDimension; }
00147
00152 itkSetMacro(Origin, PointType);
00153 virtual void SetOrigin( const double origin[VImageDimension] );
00154 virtual void SetOrigin( const float origin[VImageDimension] );
00156
00183 virtual void SetDirection( const DirectionType direction );
00184
00188 itkGetConstReferenceMacro(Direction, DirectionType);
00189
00194 itkGetConstReferenceMacro(Spacing, SpacingType);
00195
00200 itkGetConstReferenceMacro(Origin, PointType);
00201
00208 virtual void Allocate() {};
00209
00216 virtual void SetLargestPossibleRegion(const RegionType ®ion);
00217
00224 virtual const RegionType& GetLargestPossibleRegion() const
00225 { return m_LargestPossibleRegion;};
00226
00230 virtual void SetBufferedRegion(const RegionType ®ion);
00231
00235 virtual const RegionType& GetBufferedRegion() const
00236 { return m_BufferedRegion;};
00237
00245 virtual void SetRequestedRegion(const RegionType ®ion);
00246
00254 virtual void SetRequestedRegion(DataObject *data);
00255
00260 virtual const RegionType& GetRequestedRegion() const
00261 { return m_RequestedRegion;};
00262
00273 const OffsetValueType *GetOffsetTable() const { return m_OffsetTable; };
00275
00284 #ifdef ITK_USE_TEMPLATE_META_PROGRAMMING_LOOP_UNROLLING
00285 inline OffsetValueType ComputeOffset(const IndexType &ind) const
00286 {
00287 OffsetValueType offset = 0;
00288 ImageHelper<VImageDimension,VImageDimension>::ComputeOffset(this->GetBufferedRegion().GetIndex(),
00289 ind,
00290 m_OffsetTable,
00291 offset);
00292 return offset;
00293 }
00294 #else
00295 OffsetValueType ComputeOffset(const IndexType &ind) const
00296 {
00297
00298 OffsetValueType offset=0;
00299 const IndexType &bufferedRegionIndex = this->GetBufferedRegion().GetIndex();
00300
00301
00302
00303 for (int i=VImageDimension-1; i > 0; i--)
00304 {
00305 offset += (ind[i] - bufferedRegionIndex[i])*m_OffsetTable[i];
00306 }
00307 offset += (ind[0] - bufferedRegionIndex[0]);
00308
00309 return offset;
00310 }
00311 #endif
00312
00319 #ifdef ITK_USE_TEMPLATE_META_PROGRAMMING_LOOP_UNROLLING
00320 inline IndexType ComputeIndex(OffsetValueType offset) const
00321 {
00322 IndexType index;
00323 const IndexType &bufferedRegionIndex = this->GetBufferedRegion().GetIndex();
00324 ImageHelper<VImageDimension,VImageDimension>::ComputeIndex(bufferedRegionIndex,
00325 offset,
00326 m_OffsetTable,
00327 index);
00328 return index;
00329 }
00330 #else
00331 IndexType ComputeIndex(OffsetValueType offset) const
00332 {
00333 IndexType index;
00334 const IndexType &bufferedRegionIndex = this->GetBufferedRegion().GetIndex();
00336
00337 for (int i=VImageDimension-1; i > 0; i--)
00338 {
00339 index[i] = static_cast<IndexValueType>(offset / m_OffsetTable[i]);
00340 offset -= (index[i] * m_OffsetTable[i]);
00341 index[i] += bufferedRegionIndex[i];
00342 }
00343 index[0] = bufferedRegionIndex[0] + static_cast<IndexValueType>(offset);
00344
00345 return index;
00346 }
00347 #endif
00348
00355 virtual void SetSpacing (const SpacingType & spacing);
00356 virtual void SetSpacing (const double spacing[VImageDimension]);
00357 virtual void SetSpacing (const float spacing[VImageDimension]);
00359
00360
00367 #ifdef ITK_USE_TEMPLATE_META_PROGRAMMING_LOOP_UNROLLING
00368 template<class TCoordRep>
00369 bool TransformPhysicalPointToIndex(
00370 const Point<TCoordRep, VImageDimension>& point,
00371 IndexType & index ) const
00372 {
00373 ImageTransformHelper<VImageDimension,VImageDimension-1,VImageDimension-1>::TransformPhysicalPointToIndex(
00374 this->m_PhysicalPointToIndex, this->m_Origin, point, index);
00375
00376
00377 const bool isInside = this->GetLargestPossibleRegion().IsInside( index );
00378 return isInside;
00379 }
00380 #else
00381 template<class TCoordRep>
00382 bool TransformPhysicalPointToIndex(
00383 const Point<TCoordRep, VImageDimension>& point,
00384 IndexType & index ) const
00385 {
00386 for (unsigned int i = 0; i < VImageDimension; i++)
00387 {
00388 TCoordRep sum = NumericTraits<TCoordRep>::Zero;
00389 for (unsigned int j = 0; j < VImageDimension; j++)
00390 {
00391 sum += this->m_PhysicalPointToIndex[i][j] * (point[j] - this->m_Origin[j]);
00392 }
00393 #ifdef ITK_USE_CENTERED_PIXEL_COORDINATES_CONSISTENTLY
00394 index[i] = Math::RoundHalfIntegerUp< IndexValueType>( sum );
00395 #else
00396 index[i] = static_cast< IndexValueType>( sum );
00397 #endif
00398 }
00399
00400
00401 const bool isInside = this->GetLargestPossibleRegion().IsInside( index );
00402
00403 return isInside;
00404 }
00405 #endif
00406
00411 template<class TCoordRep>
00412 bool TransformPhysicalPointToContinuousIndex(
00413 const Point<TCoordRep, VImageDimension>& point,
00414 ContinuousIndex<TCoordRep, VImageDimension>& index ) const
00415 {
00416 Vector<double, VImageDimension> cvector;
00417
00418 for( unsigned int k = 0; k < VImageDimension; k++ )
00419 {
00420 cvector[k] = point[k] - this->m_Origin[k];
00421 }
00422 cvector = m_PhysicalPointToIndex * cvector;
00423 for( unsigned int i = 0; i < VImageDimension; i++ )
00424 {
00425 index[i] = static_cast<TCoordRep>(cvector[i]);
00426 }
00427
00428
00429 const bool isInside = this->GetLargestPossibleRegion().IsInside( index );
00430
00431 return isInside;
00432 }
00433
00434
00439 template<class TCoordRep>
00440 void TransformContinuousIndexToPhysicalPoint(
00441 const ContinuousIndex<TCoordRep, VImageDimension>& index,
00442 Point<TCoordRep, VImageDimension>& point ) const
00443 {
00444 for( unsigned int r=0; r<VImageDimension; r++)
00445 {
00446 TCoordRep sum = NumericTraits<TCoordRep>::Zero;
00447 for( unsigned int c=0; c<VImageDimension; c++ )
00448 {
00449 sum += this->m_IndexToPhysicalPoint(r,c) * index[c];
00450 }
00451 point[r] = sum + this->m_Origin[r];
00452 }
00453 }
00455
00461 #ifdef ITK_USE_TEMPLATE_META_PROGRAMMING_LOOP_UNROLLING
00462 template<class TCoordRep>
00463 void TransformIndexToPhysicalPoint(
00464 const IndexType & index,
00465 Point<TCoordRep, VImageDimension>& point ) const
00466 {
00467 ImageTransformHelper<VImageDimension,VImageDimension-1,VImageDimension-1>::TransformIndexToPhysicalPoint(
00468 this->m_IndexToPhysicalPoint, this->m_Origin, index, point);
00469 }
00470 #else
00471 template<class TCoordRep>
00472 void TransformIndexToPhysicalPoint(
00473 const IndexType & index,
00474 Point<TCoordRep, VImageDimension>& point ) const
00475 {
00476 for (unsigned int i = 0; i < VImageDimension; i++)
00477 {
00478 point[i] = this->m_Origin[i];
00479 for (unsigned int j = 0; j < VImageDimension; j++)
00480 {
00481 point[i] += m_IndexToPhysicalPoint[i][j] * index[j];
00482 }
00483 }
00484 }
00485 #endif
00486
00487
00488
00506 template<class TCoordRep>
00507 void TransformLocalVectorToPhysicalVector(
00508 const FixedArray<TCoordRep, VImageDimension> & inputGradient,
00509 FixedArray<TCoordRep, VImageDimension> & outputGradient ) const
00510 {
00511
00512
00513
00514 #ifdef ITK_USE_ORIENTED_IMAGE_DIRECTION
00515 const DirectionType & direction = this->GetDirection();
00516 for (unsigned int i = 0; i < VImageDimension; i++)
00517 {
00518 typedef typename NumericTraits<TCoordRep>::AccumulateType CoordSumType;
00519 CoordSumType sum = NumericTraits<CoordSumType>::Zero;
00520 for (unsigned int j = 0; j < VImageDimension; j++)
00521 {
00522 sum += direction[i][j] * inputGradient[j];
00523 }
00524 outputGradient[i] = static_cast<TCoordRep>( sum );
00525 }
00526 #else
00527 for (unsigned int i = 0; i < VImageDimension; i++)
00528 {
00529 outputGradient[i] = inputGradient[i];
00530 }
00531 #endif
00532 }
00534
00544 virtual void CopyInformation(const DataObject *data);
00545
00556 virtual void Graft(const DataObject *data);
00557
00565 virtual void UpdateOutputInformation();
00566
00574 virtual void UpdateOutputData();
00575
00579 virtual void SetRequestedRegionToLargestPossibleRegion();
00580
00590 virtual bool RequestedRegionIsOutsideOfTheBufferedRegion();
00591
00600 virtual bool VerifyRequestedRegion();
00601
00618 virtual unsigned int GetNumberOfComponentsPerPixel() const;
00619 virtual void SetNumberOfComponentsPerPixel( unsigned int );
00621
00622 protected:
00623 ImageBase();
00624 ~ImageBase();
00625 virtual void PrintSelf(std::ostream& os, Indent indent) const;
00626
00631 void ComputeOffsetTable();
00632
00638 virtual void ComputeIndexToPhysicalPointMatrices();
00639
00640 protected:
00644 SpacingType m_Spacing;
00645 PointType m_Origin;
00646 DirectionType m_Direction;
00647
00650 DirectionType m_IndexToPhysicalPoint;
00651 DirectionType m_PhysicalPointToIndex;
00652
00657 virtual void InitializeBufferedRegion(void);
00658
00659 private:
00660 ImageBase(const Self&);
00661 void operator=(const Self&);
00662
00663 OffsetValueType m_OffsetTable[VImageDimension+1];
00664
00665 RegionType m_LargestPossibleRegion;
00666 RegionType m_RequestedRegion;
00667 RegionType m_BufferedRegion;
00668
00669 };
00670
00671 }
00672
00673
00674 #define ITK_TEMPLATE_ImageBase(_, EXPORT, x, y) namespace itk { \
00675 _(1(class EXPORT ImageBase< ITK_TEMPLATE_1 x >)) \
00676 namespace Templates { typedef ImageBase< ITK_TEMPLATE_1 x > ImageBase##y; } \
00677 }
00678
00679 #if ITK_TEMPLATE_EXPLICIT
00680 # include "Templates/itkImageBase+-.h"
00681 #endif
00682
00683 #if ITK_TEMPLATE_TXX
00684 # include "itkImageBase.txx"
00685 #endif
00686
00687 #endif
00688