11/* =========================================================================
22 *
3- * Copyright SINAPSE: Scalable Informatics for Neuroscience, Processing and Software Engineering
4- * The University of Iowa
3+ * Copyright NumFOCUS
54 *
65 * Licensed under the Apache License, Version 2.0 (the "License");
76 * you may not use this file except in compliance with the License.
1615 * limitations under the License.
1716 *
1817 *=========================================================================*/
19- /*
20- * itkResampleInPlaceImageFilter.h
21- *
22- *
23- * Created by Wei Lu on 10/14/10.
24- *
25- */
2618
27- #ifndef __itkResampleInPlaceImageFilter_h
28- #define __itkResampleInPlaceImageFilter_h
19+ #ifndef itkResampleInPlaceImageFilter_h
20+ #define itkResampleInPlaceImageFilter_h
2921
3022#include " itkImageToImageFilter.h"
3123#include " itkVersorRigid3DTransform.h"
@@ -36,22 +28,19 @@ namespace itk
3628 * \brief Resample an image in place.
3729 *
3830 * The current ITK resample image filter will generate a physical memory-
39- * modified version of the input image if the input transform is not identity. The
40- * abuse use of the filter can be cumbersome in a situation that the image is very
41- * large, and there are lots of transform to be superimposed for the input image, and
42- * we even don't care about those intermediate transformed images.
43- *
44- * If all the transforms are rigid, a far superior way to achieve a similar result
45- * while minimizing the accumulative resampling errors as well as eliminating the expense
46- * on accessing the physical memory of the image is to compose all the
47- * transforms before hand if it is possible, and then we only need to resample the
48- * input image with the final composed transform once.
49- *
50- * Here we present a more compact alternative, all information is stored in the header
51- * of the image and there is no need to maintain the final transform any longer. ITK
52- * image class has innate support for doing this.
53- *
54- * \param RigidTransform -- Currently must be a VersorRigid3D
31+ * modified version of the input image if the input transform is not identity.
32+ * The abuse use of the resample filter can be a source of problems.
33+ * It can exhaust memory if the image is very large.
34+ * It WILL reduce image quality when there are lots of transforms to be
35+ * superimposed for the input image. We usually don't even care
36+ * about those intermediate transformed images!
37+ *
38+ * If all the transforms are rigid, there is a far superior way to achieve a similar result.
39+ * Updating image metadata in-place removes the accumulated resampling errors
40+ * as well as eliminating the expense of accessing the physical memory of the image.
41+ * We need to compose all the transforms beforehand to make use of this filter.
42+ *
43+ * \param RigidTransform -- Currently must be a \class VersorRigid3D
5544 * \param InputImage -- The image to be duplicated and modified to incorporate the
5645 * rigid transform
5746 * \return -- An image with the same voxels values as the input, but with differnt
@@ -60,36 +49,49 @@ namespace itk
6049 * The purpose of this code is to generate the new origin and direction
6150 * that will remove the need for using the transform.
6251 *
63- * Given a set of PhysFixedImagePoints (i.e. from the fixedImage space)
64- * those points are converted to PhysMovingImagePoints = TfmF2M( PhysFixedImagePoints )
65- * and then MovingContinuousIndexPoints = movingImage->TransformPhysicalPointToContinuousIndex( PhysMovingImagePoints )
66- * to get image values.
52+ * Given a set of PhysicalFixedImagePoints (i.e. from the fixedImage space)
53+ * those points are converted to PhysicalMovingImagePoints = TfmF2M( PhysicalFixedImagePoints )
54+ * and then MovingContinuousIndexPoints = movingImage->TransformPhysicalPointToContinuousIndex(
55+ * PhysicalMovingImagePoints ) to get image values.
6756 *
68- * We desire to change the moving image DirectionCosign [DC] and Origin O such that
57+ * We desire to change the moving image DirectionCosine [DC] and Origin [O] such that
6958 * we can compute the:
70- * MovingContinuousIndexPoints = newMovingImage->TransformPhysicalPointToContinuousIndex( PhysFixedImagePoints )
59+ * MovingContinuousIndexPoints = newMovingImage->TransformPhysicalPointToContinuousIndex( PhysicalFixedImagePoints )
60+ *
61+ * Image Notations:
62+ * \f$\mathbf{D}\f$: Direction cosine matrix
63+ * \f$\mathbf{o}\f$: Origin vector
64+ * \f$\mathbf{S}\f$: Spacing
65+ * \f$\mathbf{ci}\f$: Continouos index
66+ * \f$\mathbf{D}^{'}\f$: New direction cosine matrix
67+ * \f$\mathbf{o}^{'}\f$: New origin vector
7168 *
72- *Image Notations:
73- * DC-DirectionCosign
74- * O-Origin
69+ * Rigid Transform Notations:
70+ * \f$\mathbf{R}\f$: Rotation matrix
71+ * \f$\mathbf{c}\f$: Center of rotation vector
72+ * \f$\mathbf{t}\f$: Translation vector
7573 *
76- *Rigid Transform Notations:
77- * R-Rotation
78- * C-Center Of Rotation
79- * T-Translation
74+ * \f$\mathbf{f}_{p}\f$: fixed image points in physical space
75+ * \f$\mathbf{m}_{p}\f$: moving image points in physical space
8076 *
8177 * TransformPhysicalPointToContinuousIndex:
82- * CI = [SP^-1][DC^-1]( PhysMovingImagePoints - O )
83- * PhysMovingImagePoints = [R](PhysFixedImagePoints - C) + C + T
78+ * \f[
79+ * \mathbf{ci} = \mathbf{S}^{-1}\mathbf{D}^{-1}( \mathbf{m}_{p} - \mathbf{o} ) \\
80+ * \mathbf{m}_{p} = \mathbf{R}(\mathbf{f}_{p} - \mathbf{c}) + \mathbf{c} + \mathbf{T}
81+ * \f]
8482 *
8583 * After substitutions:
86- * MovingContinuousIndexPoints = [R^-1][DC][SP] * CI + [R^-1] * O - [R^-1] * C - [R^-1]*T + C
87- * ---------- --------------------------------------
88- * NewDC NewOrigin
89- * NewDC = [R^-1][DC]
90- * NewOrigin = [R^-1] * ( O - C - T ) + C
9184 *
92- * \ingroup GeometricTransforms
85+ * \f[
86+ * \mathbf{m}_{c} = \underbrace{\mathbf{R}^{-1}\mathbf{D}}_\text{new cosine}\mathbf{S} * \mathbf{i} +
87+ * \underbrace{\mathbf{R}^{-1} * \mathbf{o} - \mathbf{R}^{-1} * \mathbf{c} - \mathbf{R}^{-1}*T}_\text{new origin} +
88+ * \mathbf{c} \\
89+ * \\
90+ * \mathbf{D}^{'} = \mathbf{R}^{-1}\mathbf{D} \\
91+ * \mathbf{o}^{'} = \mathbf{R}^{-1} * ( \mathbf{o} - \mathbf{c} - \mathbf{t} ) + \mathbf{c}
92+ * \f]
93+ *
94+ * \ingroup ITKTransform
9395 */
9496template <typename TInputImage, typename TOutputImage>
9597class ResampleInPlaceImageFilter : public ImageToImageFilter <TInputImage, TOutputImage>
@@ -146,9 +148,8 @@ class ResampleInPlaceImageFilter : public ImageToImageFilter<TInputImage, TOutpu
146148 GetInputImage () const ;
147149
148150protected:
149- ResampleInPlaceImageFilter ();
151+ ResampleInPlaceImageFilter () = default ;
150152 ~ResampleInPlaceImageFilter () override = default ;
151- ;
152153
153154 void
154155 GenerateData () override ;
0 commit comments