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