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