Try   HackMD

Here we consider the problem of applying susceptibility distortion correction to EPI imaging data. We derive an efficient algorithm for simultaneously correcting for head motion and susceptibility distortions.

Background

Consider a collection of MRI scans of a human brain. When collected, each image is in the "scanner space", which is to say that the elements of the data arrays (voxels) correspond to locations inside an MR scanner. When comparing images for the same subject, this space is generally unhelpful, as subjects may move within the scanner, and the scanner operator may select a different location within the scanner to consider the origin

(0,0,0).

Therefore images must be brought into register with one another. Generally, one uses successive approximations of transformations, such as rotations and translations, to minimize a cost function. The resulting transformation may be used to transform coordinates in one image to the equivalent coordinates in another.

Images contain an internal affine transformation that translates from indices in the data matrix into world coordinates, conventionally in millimeters (mm) right, anterior and superior of some origin. Because the world coordinate space is abstracted from the details of the data array, it is convenient to represent transformations between images as transformations between their world coordinates, not their array indices.

Head motion

During a sequence of scans, such as functional or diffusion MRI (fMRI, dMRI), subjects' brains generally move slightly due to a combination of breathing or other movements of the head and neck, as well as pulsing of the vasculature of the brain. Head motion correction is a series of registrations from each volume in a series to a single reference volume, which may be the first volume, a separately acquired reference volume, or any other convenient target.

Head motion correction is typically modeled as rigid transformations, with three translational and three rotational degrees of freedom per volume.

Susceptibility distortion

fMRI and dMRI sequences generally take advantage of magnetic susceptibility differences in tissues, such as oxygenated and deoxygenated blood, to measure the signals of interest. As a result, the sequences also suffer from distortion in macroscopic susceptibility differences, most notably in air passages. This distortion appears as stretching and compression of the image along the phase-encoding direction, and it scales with a parameter called the total readout time and the inhomogeneity of the primary magnetic field

B0.

Susceptibility distortions are an interaction of the tissues, a property of the subject, and the magnetic field of the immobile scanner. Therefore, a subject in motion can produce susceptibility artifacts that are constant in direction relative to the scanner while different in direction relative to the principal axes of the brain.

It is therefore potentially problematic to correct for head motion and then susceptibility distortion, even with concatenated transformations. The susceptibility distortion must be calculated with respect to the rotation of the brain in the magnetic field

Terminology and conventions

In this section I introduce notation and terminology. The concepts, if not the specific notation should be familiar to those who have previously read a mathematical treatment of susceptibility distortion correction. The only (possibly) new concept is that of a readout field.

Spaces, indices, coordinates

Here a space is defined by an image, which contains a 3-dimensional data array and an affine matrix that map indices into world coordinates. The world coordinates and the space may sometimes be used interchangeably; the indices into the data array will always be specified when intended.

We have the following spaces:

  • F
    Fieldmap space
  • B
    BOLD reference space
  • Vt
    BOLD volume space for the volume at time
    t

The problem at hand is to resample the voxel data in

Vt to
B
, taking into account distortions that are known to scale with a parameter sampled in
F
.

For a given space

S, there is an affine matrix that transforms a discrete index
iS
to a "world coordinate"
cS=ASiS
.

cB=ABiBcVt=AViVtcF=AFiF

Without loss of generality, the BOLD volumes share a common affine, but not a common space. If a term with the

V subscript omits the
t
superscript, the value of the term in that context does not change with
t
.

Affine transformations

By assumption, the subject moves between volumes, so volumes have been registered to one another. In this case, the BOLD reference space

B acts as a common registration target. Only affine registrations are considered here, and for simplicity they may be assumed to be rigid (rotation and translation) transforms.

A transform

TXY is the affine transform from coordinates in space
X
to
Y
. Assume we have invertible transforms:

TBF:BFTVBt:VtBcF=TBFcBcB=TVBtcVt

To invert a transform, we may either use the

1 superscript or swap the subscripts to indicate from/to.

TVBt and its inverse
TBVt
vary by
t
. This is in fact the only source of variation between volumes
Vt
, and what permits
cVt
and
iVt
to be meaningfully superscripted.

B0
inhomogeneity maps ("fieldmaps")

MRI acquisitions in general are sensitive to to inhomogeneities in the scanner magnetic field (

B0), which are induced by inhomogeneous materials, such as the human head. A fieldmap is a measure of
ΔB0
, with the unit of Hz (radians/sec), and when we estimate this value (by any technique), we can describe the result as a discretely sampled field in the space
F
:

ϕF(iF)

More usefully, we will consider the function over the world coordinates, which will be interpolated over the discrete field:

Φ(cF)

Readout vector

Echo-planar images are acquired with phase-encoding and frequency-encoding directions. Importantly the phase-encoding direction has a polarity, indicating which end of the data matrix is collected at an early or late phase.

BOLD volumes share a phase-encoding direction that corresponds to an (oriented) axis in the data matrix, for example j- indicates that readout will occur in the negative direction in the second dimension, which we can indicate with an orientation vector field:

oV=[010]

Phase-encoding directions may be i, j or k and may have positive or negative polarity. See Algorithm for a Python implementation.

The readout field is a vector field over the voxel space of the BOLD image, and it scales with the total readout time (

τro) of the BOLD image:

rV=τrooV

This readout field is an orientation vector in voxel-seconds. If scaled by a fieldmap in Hz, it would provide a displacement map in voxels along the direction of the phase encoding axis.

Per-volume distortion correction

The problem is to correct a bold volume in

Vt simultaneously accounting for motion and distortion to resample in
B
.

First, let's review resampling. When resampling from a source space

X to a target space
Y
, we select a grid of indices
iY
in the target space, and find values in
X
to place in each array element (voxel). Assuming we have an affine transform
TYX
from
Y
to
X
, we can map our new indices into our source data:

iX=AX1cX=AX1TYXcY=AX1TYXAYiY

We are looking to resample a volume

Vt into the the BOLD reference volume
B
, given a transform
TBVt
:

iVt=AV1TBVtABiB

We would like to find an additional displacement

ΔiVt that would account for distortion induced shift. At each index
iVt
, we can find a corresponding shift by mapping into the volume world space, then reference, and finally fieldmap space, and multiplying the scalar result by our readout vector:

ΔiVt=Φ(TBFTVBtAViVt)rV

Taken over all indices, this is the fieldmap, resampled into the volume space

Vt, multiplied the readout vector to get a voxel shift map. Using our earlier calculations, we can decompose this into the fieldmap resampled into the reference space
B
and the orientation vector:

ΔiVt=Φ(TBFTVBtAVAV1TBVtABiB)τrooV=Φ(TBFABiB)τrooV

Hence, by resampling

Φ once into
B
,

ϕB(iB)=Φ(TBFABiB)

We are able to fully calculate the index-to-index mapping:

iVt=AV1TBVtABiB+ϕB(iB)τrooV

Somewhat surprisingly, the fieldmap does not need to be resampled into the individual

Vt spaces in order to fully account for the effect of distortions, because it is a shift in indices based on the geometry of the target space
B
.

What is novel is that the shift applies to indices in

Vt and not in
B
where they seem to naturally occur.

Let recap the components of this final equation:

  • iB
    represents any index in the target image we are trying to compute
  • AV1TBVtAB
    is an affine transform from the indices of an image in the reference space
    B
    to the indices of our source image in
    Vt
  • ϕB
    is a precomputed fieldmap sampled in
    B
    and
    ϕB(iB)
    is a particular value in Hz
  • τro
    is the total readout time of the images in
    Vt
  • oV
    is a constant orientation vector that encodes phase-encoding direction of
    Vt

Note that there is no requirement for

B to be the BOLD reference space, nor must the transformations be affine. The critical features are that the fieldmap be resampled into the target space and used to calculate voxel shifts in the source space.

Comparison with naive composition

The final equation we derived was:

iVt=AV1TBVtABiB+ϕB(iB)τrooV

The standard way of combining head motion and distortion corrections is to concatenate transforms, which composes index mapping functions. Here, applying the voxel shift map to

iB and then applying the motion correction to yield
iVt
would yield:

iVt=AV1TBVtAB(iB+ϕB(iB)τrooV)

The difference in source voxel selection is

(AV1TBVtABI)oV, which intuitively measures the degree of rotation of phase-encoding axis encoded in the
TBVt
. For small rotations or rotations about the phase-encoding axis, the difference is minimal.

Extension to nonlinear transforms

In the previous section, we assumed transformations were affine for conceptual and notational simplicity.
We will now show that invertibility is sufficient, and demonstrate that any target space may be used, and not merely an intermediate BOLD reference space.

Let

TXY be an invertible mapping from
X
to
Y
:

iX=AX1cX=AX1TYX(cY)=AX1TYX(AYiY)

Let's consider the following common spaces:

  • F
    Fieldmap space
  • B
    BOLD reference space
  • Vt
    BOLD volume space for the volume at time
    t
  • P
    "Physical" space, as measured by a T1-weighted image, or similar
  • G
    Group space, for comparing data across subjects, such as MNI152

The following transforms (and their inverses) have been calculated:

TBF:BFTBVt:BVtTPB:PBTGP:GP

For notational convenience, the following compositions are defined, which map group coordinates into the fieldmap and individual BOLD coordinate spaces:

TGVt=TBVtTPBTGPTGF=TBFTPBTGP

To resample to

G from each volume, we need:

iVt=AV1TBVt(TPB(TGP(AGiG)))=AV1TGVt(AGiG)

We again seek a displacement based on the fieldmap, which has been registered to the BOLD reference space, as above:

ΔiVt=Φ(TBF(TVBt(AViVt)))rV

Substituting

iVt:

ΔiVt=Φ(TBF(TVBt(AVAV1TBVt(TPB(TGP(AGiG))))))τrooV=Φ(TBF(TPB(TGP(AGiG))))τrooV=Φ(TGF(AGiG))τrooV

The first term resamples the fieldmap, in Hz, onto the target space:

ϕG(iG)=Φ(TGF(AGiG))

Hence, the final index-to-index mapping is:

iVt=AV1TGVt(AGiG)+ϕG(iG)τrooV

We have now shown that all that is required to use this algorithm is some sequence of transforms that can map both the fieldmap and the individual BOLD volumes to a target space. The BOLD reference volume is a convenient space, but any other intermediate spaces may be used.

For example, if it is simpler to register the fieldmap to the physical space, it remains possible to find a target space. However, typically fieldmap correction is used to improve the anatomical fidelity of the EPI prior to registration to the anatomical scan. The above analysis suggests that a fieldmap registered to the anatomical space could be used when computing the cost function during coregistration.

A note on the interchangeability of spaces

The above analysis establishes that we may resample a fieldmap into
a convenient space, and we use the target space as the most clearly
convenient space. However, the exact same logic can produce any of
the following mappings:

iVt=AV1TGVt(AGiG)+ϕG(iG)τrooV=AV1TGVt(AGiG)+ϕP(AP1TGP(AGiG))τrooV=AV1TGVt(AGiG)+ϕB(AB1TGB(AGiG))τrooV=AV1TGVt(AGiG)+ϕV(AV1TGV(AGiG))τrooV

In all cases, we are mapping indices in

G onto indices in
Vt
. The only condition is that the fieldmap must be
interpolated at a high enough resolution to make these terms equivalent.

Here we make explicit the notion of a BOLD reference space with an
identical affine and index grid as each individual volume.
This is typically true of the space

B, but rather than
require
AB=AV
, we will simply use
AV
.

iVt=AV1TVVtAVAV1TGV(AGiG)+ϕV(AV1TGV(AGiG))τrooV

Finally, let us abstract from any particular target space. We will
consider

V,
X
and if an intermediate space is needed
we will use
W
.

Therefore:

iVt=AV1TXVt(AXiX)+ϕX(iX)τrooV=AV1TVVtAVAV1TXV(AXiX)+ϕV(AV1TXV(AXiX))τrooV=AV1TVVtAVAV1TWV(TXW(AXiX))+ϕV(AV1TWV(TXW(AXiX)))τrooV

Derivatives of transforms

The derivative of the affine transformation

dT_XY

Letting

TGV=AV1TGV(AGiG) be the voxel-to-voxel warp,

diVtdiG=TGV(iG)+ϕV(TGV(iG))TGV(iG)τrooV=TGV(iG)(1+ϕV(TGV(iG))τrooV)=TGV(iG)(1+ϕVoV(TGV(iG))τro)

Note that

oV is a positive or negative unit vector
along one of the dimensions of
V
,
so the gradient simplifies to the partial derivative in the direction of
oV
.

We also neglect

TVVt

Resampling and intensity rescaling

To this point, we have considered the problem of mapping coordinates
from a target grid onto a source grid.
Resampling an image, however, uses mapped coordinates to interpolate
intensity values from the source image into the target grid.

We will use the symbol

IXt to indicate the image intensity
at a location in space
X
at time
t
.

IX(iX)=IVt(AV1TXVt(AXiX)+ϕX(iX)τrooV)

For any neighborhood in

X, we would like the average intensity
of
IX
to match the average intensity of the
corresponding region of
IVt
.
So we need some per-voxel scaling parameter
SXV
, which
we would apply after resampling:

IX(iX)=SXV(iX)IVt(AV1TXVt(AXiX)+ϕX(iX)τrooV)


IX(iX)=SXV(iX)IVt(AV1TXVt(AXiX)+ϕV(AV1TXV(AXiX))τrooV)


We will show that the scale factor is the product of the Jacobian
determinants of the

TXV transformation and the
transformation described by the fieldmap.

SXV(iX)=|JXV(iX)||JΦ(AV1TXV(AXiX))|=|JXV(iX)|(1+τroϕVoV(AV1TXV(AXiX)))

More generally, we can accumulate Jacobians

|JXY(iX)|=S=XY|JXS(AS1TXSAXiX)|

Jacobian determinant modulation

Consider a differentiable transform

T:R3R3, and let
D
be the displacement field of
T
, such that:

T(x,y,z)=[xyz]+D(x,y,z)=[x+Dx(x,y,z)y+Dy(x,y,z)z+Dz(x,y,z)]

At each point we can compute the Jacobian of the transformation:

JT=[TxxTxyTxzTyxTyyTyzTzxTzyTzz]=[1+DxxDxyDxzDyx1+DyyDyzDzxDzy1+Dzz]

The Jacobian determinant describes the proportional change in volume of
a unit cube in the source coordinate space when transformed into the
target coordinate space.

We now consider the specific case of the voxel shift map in the BOLD
reference space

B. This is a displacement field where the
coordinates are voxel indices:

DΦ(iB)=ϕB(iB)τrooV

Without loss of generality, suppose that the phase-encoding direction
is i, and therefore:

DΦ(i,j,k)=ϕB(i,j,k)τrooV=[ϕB(i,j,k)τro00]

Therefore, the Jacobian determinant at each voxel index is

|JΦ|=|1+τroiϕB00010001|=1+τroϕBi

This is simply one plus the gradient of the voxel shift map in the phase-encoding direction. Resampling with scaling becomes:

IB(iB)=|JΦ(iB)|IV(iVt)=|JΦ(iB)|IV(AV1TBVtABiB+ϕB(iB)τrooV)

Note that

TBVt is affine and will thus scale all voxels equally. We are here concerned with relative changes in brightness, and can ignore any scaling effects of this term.

Note also that this Jacobian does not simplify to this trivial form as
soon as

Algorithm

Assume an interpolation function interpolate3D:

def interpolate3D(
    data: Array,
    index0: int,
    index1: int,
    index2: int,
) -> float: ...

We define a resampling function that accepts a transformation from
voxel indices to voxel indices in addition to a 4D displacement map,
such that the value at a 3D voxel index is a 3-vector.
Because the transformed indices may not be integers, we use
interpolate3D to interpolate the source data:

def resample(
    source: Array,
    target: Array,
    transformTS: Affine,
    voxel_shift_map: Array,
) -> Array:
    I, J, K = target.shape
    output = Array((I, J, K))
    for iT in range(I):
        for jT in range(J):
            for kT in range(K):
                iS, jS, kS, _ = transformTS @ [iT, jT, kT, 1]
                d_iS, d_jS, d_kS = voxel_shift_map[iT, jT, kT]
                output[i, j, k] = interpolate3D(
                    source, iS + d_iS, jS + d_jS, kS + d_kS
                )
    return output
import numpy as np

def orientation_vector(
    phase_encoding_direction: OneOf["i", "j", "k", "i-", "j-", "k-"],
) -> Vector:
    vector = np.zeros((3,))
    polarity = 1 if phase_encoding_direction[1:] != '-' else -1
    vector['ijk'.index(phase_encoding_direction[0])] = polarity
    return vector

The final algorithm to correct the volume is as follows:

def correct_volume(
    imageV: (Array, Affine),
    imageB: (Array, Affine),
    imageF: (Array, Affine),
    transformVB: Affine,
    transformBF: Affine,
    total_readout_time: float,
    phase_encoding_direction: OneOf["i", "j", "k", "i-", "j-", "k-"],
) -> Array:
    reference_fieldmap = resample(
        source=imageF.array,
        target=imageB.array,
        transformTS=inv(imageF.affine) @ transformBF @ imageB.affine,
        voxel_shift_map=Array(imageB.shape + (1,)) * 0,
    )
    orientV = orientation_vector(phase_encoding_direction)
    delta_i_V = (reference_fieldmap * total_readout_time) @ orientV
    corrected = resample(
        source=imageV.array,
        target=imageB.array,
        transformTS=inv(imageV.affine) @ inv(transformVB) @ imageB.affine,
        voxel_shift_map=delta_i_V,
    )
    return corrected