ITK
4.1.0
Insight Segmentation and Registration Toolkit
|
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