Image taken from http://cnl.web.arizona.edu/imageprops.htm
For a voxel \(v\), the rigid transformation can be written as:
\[T_{\rm rigid}(v) = Rv + t\] where \(R =\) \[\left[\begin{array}{ccc} \cos\beta\cos\gamma& \cos\alpha\sin\gamma + \sin\alpha\sin\beta\cos\gamma & \sin\alpha\sin\gamma - \cos\alpha\sin\beta\cos\gamma \\ -\cos\beta\sin\gamma & \cos\alpha\cos\gamma - \sin\alpha\sin\beta\sin\gamma & \sin\alpha\cos\gamma + \cos\alpha\sin\beta\sin\gamma \\ \sin\beta & -\sin\alpha\cos\beta & \cos\alpha\cos\beta \end{array}\right]\]
l = list() l[[1]] = c(1, 2, 4, 5) l[[2]] = matrix(1:10, nrow = 2) print(l)
[[1]] [1] 1 2 4 5 [[2]] [,1] [,2] [,3] [,4] [,5] [1,] 1 3 5 7 9 [2,] 2 4 6 8 10
print(l[[1]])
[1] 1 2 4 5
If a vector
has names, you can also put the - Initialize an empty list and add two elements to it
x = c(one = 1, three = 14, two = 5) print(x)
one three two 1 14 5
x[c("three")]
three 14
If a list
has names, you can subset with the $
names(l) = c("V", "m"); l[["V"]]
[1] 1 2 4 5
If a list
has names, you can also subset with the $
l$V
[1] 1 2 4 5
ms.lesion
packageget_image_filenames_list_by_subject
- returns a list, each element is a subject, and each subject has a vector of filenames, named for each modalitylibrary(ms.lesion) all_files = get_image_filenames_list_by_subject() class(all_files); names(all_files)
[1] "list"
[1] "test01" "test02" "test03" "training01" "training02" [6] "training03" "training04" "training05"
files = all_files$training01; class(files); names(files)
[1] "character"
[1] "T1" "T2" "FLAIR"
t1_fname = files["T1"] t1 = readnii(t1_fname) rt1 = robust_window(t1, probs = c(0, 0.975))
The registration
function from extrantsr
can register 2 images. The main arguments are:
filename
- either nifti
object or filename of image to be registered (moving)template.file
- either nifti
object or filename of target image (fixed)typeofTransform
- transformation of moving to fixed image (Rigid/Affine/SyN)interpolator
- how are voxels averaged in fixed
space (Linear/NearestNeighbor/LanczosWindowedSinc)It can also perform bias correction if correct = TRUE
.
For example, if we wanted to register the FLAIR to the T1 image, we would run:
library(extrantsr) reg = registration( filename = files["FLAIR"], template.file = files["T1"], typeofTransform = "Rigid", interpolator = "Linear", verbose = FALSE) names(reg)
[1] "outfile" "fwdtransforms" "invtransforms" [4] "interpolator" "other_interpolator" "invert_interpolator" [7] "typeofTransform" "retimg"
The output in reg
would contain the transformed image and paths to the estimated transformations.
double_ortho(rt1, reg$outfile)
We would like to perform registration within a visit for all modalities. The extrantsr
function within_visit_registration
will do the following steps:
The function within_visit_registration
arguments take in:
fixed
image - the image to be registered tomoving
images - images to register to the fixed
typeofTransform
- transformation of moving to fixed image (Rigid/Affine)interpolator
- how are voxels averaged in fixed
spacecorrect
- should correction be done, if so, specify correction = "N4"
and outputs a list of transformations (fwdtransforms
) and output filenames (outfile
)
lapply
With list
s and vectors, there are apply
functions. These apply a function to every element of the list. In this course, we will use:
lapply
- apply function and return the elements as a list
lapply(LIST, FUNCTION, OTHER_ARGUMENTS_TO_FUNCTION)
sapply
- apply function and return a “simplified” version
vector
list
res = within_visit_registration( fixed = files["T1"], moving = files[c("T2", "FLAIR")], correct = TRUE, correction = "N4", typeofTransform = "Rigid", interpolator = "Linear") output_imgs = lapply(res, function(x) x$outfile) out = c(T1 = list(t1), output_imgs)
# Running Bias-Field Correction on file
# Running Registration of file to template
# Applying Registration output is
$fwdtransforms [1] "/var/folders/1s/wrtqcpxn685_zk570bnx9_rr0000gr/T//RtmpN4MXsP/file12bc91f0b4b400GenericAffine.mat" $invtransforms [1] "/var/folders/1s/wrtqcpxn685_zk570bnx9_rr0000gr/T//RtmpN4MXsP/file12bc91f0b4b400GenericAffine.mat" $prev_transforms character(0)
# Applying Transformations to file
[1] "-d" [2] "3" [3] "-i" [4] "<pointer: 0x7fdb04b572c0>" [5] "-o" [6] "<pointer: 0x7fdb04a70fa0>" [7] "-r" [8] "<pointer: 0x7fdb04b61880>" [9] "-n" [10] "linear" [11] "-t" [12] "/var/folders/1s/wrtqcpxn685_zk570bnx9_rr0000gr/T//RtmpN4MXsP/file12bc91f0b4b400GenericAffine.mat"
# Writing out file
[1] "/var/folders/1s/wrtqcpxn685_zk570bnx9_rr0000gr/T//RtmpN4MXsP/file12bc910bbbbfa.nii.gz"
# Removing Warping images
# Reading data back into R
# Running Bias-Field Correction on file
# Running Registration of file to template
# Applying Registration output is
$fwdtransforms [1] "/var/folders/1s/wrtqcpxn685_zk570bnx9_rr0000gr/T//RtmpN4MXsP/file12bc961de5f840GenericAffine.mat" $invtransforms [1] "/var/folders/1s/wrtqcpxn685_zk570bnx9_rr0000gr/T//RtmpN4MXsP/file12bc961de5f840GenericAffine.mat" $prev_transforms character(0)
# Applying Transformations to file
[1] "-d" [2] "3" [3] "-i" [4] "<pointer: 0x7fdb04959bc0>" [5] "-o" [6] "<pointer: 0x7fdb04b4b650>" [7] "-r" [8] "<pointer: 0x7fdb0493e220>" [9] "-n" [10] "linear" [11] "-t" [12] "/var/folders/1s/wrtqcpxn685_zk570bnx9_rr0000gr/T//RtmpN4MXsP/file12bc961de5f840GenericAffine.mat"
# Writing out file
[1] "/var/folders/1s/wrtqcpxn685_zk570bnx9_rr0000gr/T//RtmpN4MXsP/file12bc9153222ab.nii.gz"
# Removing Warping images
# Reading data back into R
$T2 NULL $FLAIR NULL
double_ortho(out$T1, out$T2 )
The multi_overlay
function takes in a list of images and then plots one slice across modalities (assumes center slice):
multi_overlay(out)
correct = TRUE
or pass in the bias-corrected imagesApplying a Brain mask to all registered images
Now that the images are in the same space as the T1, if we skull-strip the T1 image (we did with MALF), we can apply this mask to those images to extract brain tissues using the neurobase::mask_img
command:
mask = readnii("../output/training01_01_t1_mask.nii.gz") # MALF mask masked_imgs = lapply(out, mask_img, mask)
ortho2(masked_imgs$FLAIR)
ortho2(masked_imgs$T2)
registration
wraps around the reading/writing of images and applying transformations (uses ANTsR
functions)double_ortho
, ortho2
, and multi_overlay
can provide some basic visual checks to assess registration qualitywithin_visit_registration
is a registration wrapper functionpreprocess_mri_within
- wraps multiple steps above (inhomo, reg, extract)We have only done registration within a subject, but many times you want to perform a population-level analysis. This requries registration to a template:
registration
can be done for this as well, just the template.file
is now the template image and filename
is the subject image.
other.files
and other.outfiles
arguments. Or:ants_apply_transforms
can be used to apply this transformations to the other files