ITK  4.1.0
Insight Segmentation and Registration Toolkit
itkImageTransformHelper.h
Go to the documentation of this file.
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 #ifndef __itkImageTransformHelper_h
00019 #define __itkImageTransformHelper_h
00020 
00021 #include "itkConceptChecking.h"
00022 #include "itkImageBase.h"
00023 #include "itkMatrix.h"
00024 #include "vnl/vnl_math.h"
00025 #include "itkImageBase.h"
00026 
00027 namespace itk
00028 {
00033 template< unsigned int NImageDimension, unsigned int R, unsigned int C >
00034 class ImageTransformHelper
00035 {
00036 public:
00037   typedef ImageBase< NImageDimension >                          ImageType;
00038   typedef typename ImageType::IndexType                         IndexType;
00039   typedef typename ImageType::SpacingType                       SpacingType;
00040   typedef Matrix< double, NImageDimension, NImageDimension >    MatrixType;
00041   typedef typename ImageType::PointType                         OriginType;
00042   typedef Point< double, NImageDimension >                      DoublePoint;
00043   typedef Point< float, NImageDimension >                       FloatPoint;
00044   typedef Concept::Detail::UniqueType_bool< false >             UniqueTypeBoolFalse;
00045   typedef Concept::Detail::UniqueType_bool< true >              UniqueTypeBoolTrue;
00046 
00047   //
00048   // Methods with DoublePoint
00049   //
00050 
00051   // IndexToPhysicalPoint with full matrix
00052   //
00053   //
00054   inline static void TransformIndexToPhysicalPoint(
00055     const MatrixType & matrix, const OriginType  & origin,
00056     const IndexType & index, DoublePoint & point)
00057   {
00058     ImageTransformHelper< NImageDimension, R, C >::
00059     TransformIndexToPhysicalPointRow(
00060       matrix, origin,
00061       index, point,
00062       Concept::Detail::UniqueType_bool< ( R + 1 == 0 ) >() );
00063   }
00064 
00065   inline static void TransformIndexToPhysicalPointRow(
00066     const MatrixType & matrix, const OriginType  & origin,
00067     const IndexType & index, DoublePoint & point,
00068     const UniqueTypeBoolFalse &)
00069   {
00070     point[R] = origin[R];
00071 
00072     // Start column
00073     ImageTransformHelper< NImageDimension, R, C >
00074     ::TransformIndexToPhysicalPointCol(
00075       matrix,
00076       index, point,
00077       Concept::Detail::UniqueType_bool< ( C + 1 == 0 ) >() );
00078     // Do Next Row
00079     ImageTransformHelper< NImageDimension, R - 1, C >
00080     ::TransformIndexToPhysicalPointRow(
00081       matrix, origin,
00082       index, point,
00083       Concept::Detail::UniqueType_bool< ( R == 0 ) >() );
00084   }
00085 
00086   inline static void TransformIndexToPhysicalPointRow(
00087     const MatrixType &, const OriginType  &,
00088     const IndexType &, DoublePoint &,
00089     const UniqueTypeBoolTrue &)
00090   {
00091     // Do last row
00092   }
00093 
00094   inline static void TransformIndexToPhysicalPointCol(
00095     const MatrixType & matrix,
00096     const IndexType & index, DoublePoint & point,
00097     const UniqueTypeBoolFalse &)
00098   {
00099     point[R] = point[R] + matrix[R][C] * index[C];
00100 
00101     // Do next dimension
00102     ImageTransformHelper< NImageDimension, R, C - 1 >
00103     ::TransformIndexToPhysicalPointCol(
00104       matrix,
00105       index, point,
00106       Concept::Detail::UniqueType_bool< ( C == 0 ) >() );
00107   }
00108 
00109   inline static void TransformIndexToPhysicalPointCol(
00110     const MatrixType &,
00111     const IndexType &, DoublePoint &,
00112     const UniqueTypeBoolTrue &)
00113   {}
00114 
00115   // PhysicalPointToIndex with full matrix
00116   //
00117   //
00118   inline static void TransformPhysicalPointToIndex(
00119     const MatrixType & matrix, const OriginType  & origin,
00120     const DoublePoint & point, IndexType  & index)
00121   {
00122     DoublePoint rindex;
00123 
00124     ImageTransformHelper< NImageDimension, R, C >::
00125     TransformPhysicalPointToIndexRow(
00126       matrix, origin,
00127       point, rindex, index,
00128       Concept::Detail::UniqueType_bool< ( R + 1 == 0 ) >() );
00129   }
00130 
00131   inline static void TransformPhysicalPointToIndexRow(
00132     const MatrixType & matrix, const OriginType  & origin,
00133     const DoublePoint & point, DoublePoint & rindex, IndexType & index,
00134     const UniqueTypeBoolFalse &)
00135   {
00136     rindex[R] = 0.0;
00137     // Start column
00138     ImageTransformHelper< NImageDimension, R, C >
00139     ::TransformPhysicalPointToIndexCol(
00140       matrix, origin,
00141       point, rindex, index,
00142       Concept::Detail::UniqueType_bool< ( C + 1 == 0 ) >() );
00143     // Do next row
00144     ImageTransformHelper< NImageDimension, R - 1, C >
00145     ::TransformPhysicalPointToIndexRow(
00146       matrix, origin,
00147       point, rindex, index,
00148       Concept::Detail::UniqueType_bool< ( R == 0 ) >() );
00149   }
00150 
00151   inline static void TransformPhysicalPointToIndexRow(
00152     const MatrixType &, const OriginType &,
00153     const DoublePoint &, DoublePoint &, IndexType &,
00154     const UniqueTypeBoolTrue &)
00155   {
00156     // Do last row
00157   }
00158 
00159   inline static void TransformPhysicalPointToIndexCol(
00160     const MatrixType & matrix, const OriginType  & origin,
00161     const DoublePoint & point, DoublePoint & rindex, IndexType & index,
00162     const UniqueTypeBoolFalse &)
00163   {
00164     rindex[R] = rindex[R] + matrix[R][C] * ( point[C] - origin[C] );
00165 
00166     // Do next dimension
00167     ImageTransformHelper< NImageDimension, R, C - 1 >
00168     ::TransformPhysicalPointToIndexCol(
00169       matrix, origin,
00170       point, rindex, index,
00171       Concept::Detail::UniqueType_bool< ( C == 0 ) >() );
00172   }
00173 
00174   inline static void TransformPhysicalPointToIndexCol(
00175     const MatrixType &, const OriginType  &,
00176     const DoublePoint &, DoublePoint & rindex, IndexType & index,
00177     const UniqueTypeBoolTrue &)
00178   {
00179     index[R] = Math::RoundHalfIntegerUp< IndexValueType >(rindex[R]);
00180   }
00181 
00182   //
00183   // Methods with FloatPoint
00184   //
00185 
00186   // IndexToPhysicalPoint with full matrix
00187   //
00188   //
00189   inline static void TransformIndexToPhysicalPoint(
00190     const MatrixType & matrix, const OriginType  & origin,
00191     const IndexType & index, FloatPoint & point)
00192   {
00193     ImageTransformHelper< NImageDimension, R, C >::
00194     TransformIndexToPhysicalPointRow(
00195       matrix, origin,
00196       index, point,
00197       Concept::Detail::UniqueType_bool< ( R + 1 == 0 ) >() );
00198   }
00199 
00200   inline static void TransformIndexToPhysicalPointRow(
00201     const MatrixType & matrix, const OriginType  & origin,
00202     const IndexType & index, FloatPoint & point,
00203     const UniqueTypeBoolFalse &)
00204   {
00205     point[R] = origin[R];
00206 
00207     // Start column
00208     ImageTransformHelper< NImageDimension, R, C >
00209     ::TransformIndexToPhysicalPointCol(
00210       matrix,
00211       index, point,
00212       Concept::Detail::UniqueType_bool< ( C + 1 == 0 ) >() );
00213     // Do Next Row
00214     ImageTransformHelper< NImageDimension, R - 1, C >
00215     ::TransformIndexToPhysicalPointRow(
00216       matrix, origin,
00217       index, point,
00218       Concept::Detail::UniqueType_bool< ( R == 0 ) >() );
00219   }
00220 
00221   inline static void TransformIndexToPhysicalPointRow(
00222     const MatrixType &, const OriginType  &,
00223     const IndexType &, FloatPoint &,
00224     const UniqueTypeBoolTrue &)
00225   {
00226     // Do last row
00227   }
00228 
00229   inline static void TransformIndexToPhysicalPointCol(
00230     const MatrixType & matrix,
00231     const IndexType & index, FloatPoint & point,
00232     const UniqueTypeBoolFalse &)
00233   {
00234     point[R] = point[R] + matrix[R][C] * index[C];
00235 
00236     // Do next dimension
00237     ImageTransformHelper< NImageDimension, R, C - 1 >
00238     ::TransformIndexToPhysicalPointCol(
00239       matrix,
00240       index, point,
00241       Concept::Detail::UniqueType_bool< ( C == 0 ) >() );
00242   }
00243 
00244   inline static void TransformIndexToPhysicalPointCol(
00245     const MatrixType &,
00246     const IndexType &, FloatPoint &,
00247     const UniqueTypeBoolTrue &)
00248   {}
00249 
00250   // PhysicalPointToIndex with full matrix
00251   //
00252   //
00253   inline static void TransformPhysicalPointToIndex(
00254     const MatrixType & matrix, const OriginType  & origin,
00255     const FloatPoint & point, IndexType  & index)
00256   {
00257     FloatPoint rindex;
00258 
00259     ImageTransformHelper< NImageDimension, R, C >::
00260     TransformPhysicalPointToIndexRow(
00261       matrix, origin,
00262       point, rindex, index,
00263       Concept::Detail::UniqueType_bool< ( R + 1 == 0 ) >() );
00264   }
00265 
00266   inline static void TransformPhysicalPointToIndexRow(
00267     const MatrixType & matrix, const OriginType  & origin,
00268     const FloatPoint & point, FloatPoint & rindex, IndexType & index,
00269     const UniqueTypeBoolFalse &)
00270   {
00271     rindex[R] = 0.0;
00272     // Start column
00273     ImageTransformHelper< NImageDimension, R, C >
00274     ::TransformPhysicalPointToIndexCol(
00275       matrix, origin,
00276       point, rindex, index,
00277       Concept::Detail::UniqueType_bool< ( C + 1 == 0 ) >() );
00278     // Do next row
00279     ImageTransformHelper< NImageDimension, R - 1, C >
00280     ::TransformPhysicalPointToIndexRow(
00281       matrix, origin,
00282       point, rindex, index,
00283       Concept::Detail::UniqueType_bool< ( R == 0 ) >() );
00284   }
00285 
00286   inline static void TransformPhysicalPointToIndexRow(
00287     const MatrixType &, const OriginType &,
00288     const FloatPoint &, FloatPoint &, IndexType &,
00289     const UniqueTypeBoolTrue &)
00290   {
00291     // Do last row
00292   }
00293 
00294   inline static void TransformPhysicalPointToIndexCol(
00295     const MatrixType & matrix, const OriginType  & origin,
00296     const FloatPoint & point, FloatPoint & rindex, IndexType & index,
00297     const UniqueTypeBoolFalse &)
00298   {
00299     rindex[R] = rindex[R] + matrix[R][C] * ( point[C] - origin[C] );
00300 
00301     // Do next dimension
00302     ImageTransformHelper< NImageDimension, R, C - 1 >
00303     ::TransformPhysicalPointToIndexCol(
00304       matrix, origin,
00305       point, rindex, index,
00306       Concept::Detail::UniqueType_bool< ( C == 0 ) >() );
00307   }
00308 
00309   inline static void TransformPhysicalPointToIndexCol(
00310     const MatrixType &, const OriginType  &,
00311     const FloatPoint &, FloatPoint & rindex, IndexType & index,
00312     const UniqueTypeBoolTrue &)
00313   {
00314     index[R] = Math::RoundHalfIntegerUp< IndexValueType >(rindex[R]);
00315   }
00316 };
00317 } // end namespace itk
00318 
00319 #endif
00320