00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #ifndef __itkOrientedImage_h
00018 #define __itkOrientedImage_h
00019
00020 #include "itkImage.h"
00021 #include "itkImageTransformHelper.h"
00022
00023 namespace itk
00024 {
00025
00035 template <class TPixel, unsigned int VImageDimension>
00036 class ITK_EXPORT OrientedImage : public Image<TPixel, VImageDimension>
00037 {
00038 public:
00040 typedef OrientedImage Self;
00041 typedef Image<TPixel, VImageDimension> Superclass;
00042 typedef SmartPointer<Self> Pointer;
00043 typedef SmartPointer<const Self> ConstPointer;
00044 typedef WeakPointer<const Self> ConstWeakPointer;
00045
00047 itkNewMacro(Self);
00048
00050 itkTypeMacro(OrientedImage, Image);
00051
00053 typedef typename Superclass::IndexType IndexType;
00054
00056 typedef typename Superclass::DirectionType DirectionType;
00057
00060 typedef typename Superclass::SpacingType SpacingType;
00061
00062 typedef typename Superclass::AccessorType AccessorType;
00063 typedef typename Superclass::AccessorFunctorType AccessorFunctorType;
00064 typedef typename Superclass::IOPixelType IOPixelType;
00065
00067 typedef NeighborhoodAccessorFunctor< Self >
00068 NeighborhoodAccessorFunctorType;
00069
00072 NeighborhoodAccessorFunctorType GetNeighborhoodAccessor()
00073 { return NeighborhoodAccessorFunctorType(); }
00074
00077 const NeighborhoodAccessorFunctorType GetNeighborhoodAccessor() const
00078 { return NeighborhoodAccessorFunctorType(); }
00079
00082 virtual void SetSpacing (const SpacingType spacing)
00083 {
00084 Superclass::SetSpacing(spacing);
00085
00086 DirectionType scale;
00087 for (unsigned int i=0; i < VImageDimension; i++)
00088 {
00089 scale[i][i] = this->m_Spacing[i];
00090 }
00091 m_IndexToPhysicalPoint = this->m_Direction * scale;
00092 m_PhysicalPointToIndex = m_IndexToPhysicalPoint.GetInverse();
00093 }
00094
00095 virtual void SetSpacing (const double spacing[VImageDimension])
00096 {
00097 Superclass::SetSpacing(spacing);
00098
00099 DirectionType scale;
00100 for (unsigned int i=0; i < VImageDimension; i++)
00101 {
00102 scale[i][i] = this->m_Spacing[i];
00103 }
00104 m_IndexToPhysicalPoint = this->m_Direction * scale;
00105 m_PhysicalPointToIndex = m_IndexToPhysicalPoint.GetInverse();
00106 }
00107
00108 virtual void SetSpacing (const float spacing[VImageDimension])
00109 {
00110 Superclass::SetSpacing(spacing);
00111
00112 DirectionType scale;
00113 for (unsigned int i=0; i < VImageDimension; i++)
00114 {
00115 scale[i][i] = this->m_Spacing[i];
00116 }
00117 m_IndexToPhysicalPoint = this->m_Direction * scale;
00118 m_PhysicalPointToIndex = m_IndexToPhysicalPoint.GetInverse();
00119 }
00120
00123 virtual void SetDirection (const DirectionType direction)
00124 {
00125 Superclass::SetDirection(direction);
00126
00127 DirectionType scale;
00128 for (unsigned int i=0; i < VImageDimension; i++)
00129 {
00130 scale[i][i] = this->m_Spacing[i];
00131 }
00132 m_IndexToPhysicalPoint = this->m_Direction * scale;
00133 m_PhysicalPointToIndex = m_IndexToPhysicalPoint.GetInverse();
00134 }
00135
00140 template<class TCoordRep>
00141 bool TransformPhysicalPointToContinuousIndex(
00142 const Point<TCoordRep, VImageDimension>& point,
00143 ContinuousIndex<TCoordRep, VImageDimension>& index ) const
00144 {
00145 Vector<double, VImageDimension> cvector;
00146
00147 cvector = m_PhysicalPointToIndex * (point - this->m_Origin);
00148 for (unsigned int i = 0 ; i < VImageDimension ; i++)
00149 {
00150 index[i] = static_cast<TCoordRep>(cvector[i]);
00151 }
00152
00153
00154 const bool isInside =
00155 this->GetLargestPossibleRegion().IsInside( index );
00156
00157 return isInside;
00158 }
00159
00164 #if 1
00165 template<class TCoordRep>
00166 bool TransformPhysicalPointToIndex(
00167 const Point<TCoordRep, VImageDimension>& point,
00168 IndexType & index ) const
00169 {
00170 ImageTransformHelper<VImageDimension,VImageDimension-1,VImageDimension-1>::TransformPhysicalPointToIndex(
00171 this->m_PhysicalPointToIndex, this->m_Origin, point, index);
00172
00173
00174 const bool isInside =
00175 this->GetLargestPossibleRegion().IsInside( index );
00176 return isInside;
00177 }
00178 #else
00179 template<class TCoordRep>
00180 bool TransformPhysicalPointToIndex(
00181 const Point<TCoordRep, VImageDimension>& point,
00182 IndexType & index ) const
00183 {
00184 typedef typename IndexType::IndexValueType IndexValueType;
00185 for (unsigned int i = 0; i < VImageDimension; i++)
00186 {
00187 index[i] = 0.0;
00188 for (unsigned int j = 0; j < VImageDimension; j++)
00189 {
00190 index[i] +=
00191 m_PhysicalPointToIndex[i][j] * (point[j] - this->m_Origin[j]);
00192 }
00193 }
00194
00195
00196 const bool isInside =
00197 this->GetLargestPossibleRegion().IsInside( index );
00198
00199 return isInside;
00200 }
00201 #endif
00202
00206 template<class TCoordRep>
00207 void TransformContinuousIndexToPhysicalPoint(
00208 const ContinuousIndex<TCoordRep, VImageDimension>& index,
00209 Point<TCoordRep, VImageDimension>& point ) const
00210 {
00211 Vector<double,VImageDimension> cvector;
00212 for (unsigned int i = 0 ; i < VImageDimension ; i++)
00213 {
00214 cvector[i] = index[i];
00215 }
00217
00218 point = this->m_Origin + m_IndexToPhysicalPoint * cvector;
00219 }
00220
00226 #if 1
00227 template<class TCoordRep>
00228 void TransformIndexToPhysicalPoint(
00229 const IndexType & index,
00230 Point<TCoordRep, VImageDimension>& point ) const
00231 {
00232 ImageTransformHelper<VImageDimension,VImageDimension-1,VImageDimension-1>::TransformIndexToPhysicalPoint(
00233 this->m_IndexToPhysicalPoint, this->m_Origin, index, point);
00234 }
00235 #else
00236 template<class TCoordRep>
00237 void TransformIndexToPhysicalPoint(
00238 const IndexType & index,
00239 Point<TCoordRep, VImageDimension>& point ) const
00240 {
00241 for (unsigned int i = 0; i < VImageDimension; i++)
00242 {
00243 point[i] = this->m_Origin[i];
00244 for (unsigned int j = 0; j < VImageDimension; j++)
00245 {
00246 point[i] += m_IndexToPhysicalPoint[i][j] * index[j];
00247 }
00248 }
00249 }
00250 #endif
00251
00252
00264 template<class TCoordRep>
00265 void TransformLocalVectorToPhysicalVector(
00266 const FixedArray<TCoordRep, VImageDimension> & inputGradient,
00267 FixedArray<TCoordRep, VImageDimension> & outputGradient ) const
00268 {
00269
00270
00271
00272 #ifdef ITK_USE_ORIENTED_IMAGE_DIRECTION
00273 const DirectionType & direction = this->GetDirection();
00274 for (unsigned int i = 0 ; i < VImageDimension ; i++)
00275 {
00276 typedef typename NumericTraits<TCoordRep>::AccumulateType CoordSumType;
00277 CoordSumType sum = NumericTraits<CoordSumType>::Zero;
00278 for (unsigned int j = 0; j < VImageDimension; j++)
00279 {
00280 sum += direction[i][j] * inputGradient[j];
00281 }
00282 outputGradient[i] = static_cast<TCoordRep>( sum );
00283 }
00284 #else
00285 for (unsigned int i = 0 ; i < VImageDimension ; i++)
00286 {
00287 outputGradient[i] = inputGradient[i];
00288 }
00289 #endif
00290 }
00292
00293 protected:
00294 OrientedImage();
00295 virtual ~OrientedImage() {};
00296
00297 private:
00298 OrientedImage(const Self&);
00299 void operator=(const Self&);
00300
00301 DirectionType m_IndexToPhysicalPoint;
00302 DirectionType m_PhysicalPointToIndex;
00303 };
00304 }
00305
00306
00307 #define ITK_TEMPLATE_OrientedImage(_, EXPORT, x, y) namespace itk { \
00308 _(2(class EXPORT OrientedImage< ITK_TEMPLATE_2 x >)) \
00309 namespace Templates { typedef Image< ITK_TEMPLATE_2 x > OrientedImage##y; } \
00310 }
00311
00312 #if ITK_TEMPLATE_EXPLICIT
00313 # include "Templates/itkOrientedImage+-.h"
00314 #endif
00315
00316 #if ITK_TEMPLATE_TXX
00317 # include "itkOrientedImage.txx"
00318 #endif
00319
00320 #endif
00321