Note: Throughout this post, I will refer to an image on hard disk as a NIfTI, which is a file that generally has the extension “.nii” or “.nii.gz”. I will refer to the object in R as a
nifti (note the change of font and case).
In this tutorial we will discuss the basics of reading the
nifti object in R. There are many objects in R that represent imaging data. The Neuroconductor project chose the
nifti object from the
oro.nifti package as one of the the basic building blocks because it has been widely used in other packages, has been tested over a period of time, and inherits the properties of an
array in R.
Let’s say you have a T1-weighted NIfTI on your machine. If you do not, we can download one. We are downloading this to a temporary file since we don’t need it after the session is over:
= tempfile(fileext = ".nii.gz") t1_file = paste0("https://johnmuschelli.com/", url "open_ms_data/", "cross_sectional/", "raw/patient01/T1W.nii.gz") download.file(url, destfile = t1_file) t1_file#>  "/var/folders/1s/wrtqcpxn685_zk570bnx9_rr0000gr/T//Rtmpq8CrQ4/fileef5e5b48fb90.nii.gz"
Here we will use the
readnii function to read in the image to an object called
library(neurobase) = readnii(t1_file) img img#> NIfTI-1 format #> Type : nifti #> Data Type : 4 (INT16) #> Bits per Pixel : 16 #> Slice Code : 0 (Unknown) #> Intent Code : 0 (None) #> Qform Code : 2 (Aligned_Anat) #> Sform Code : 1 (Scanner_Anat) #> Dimension : 408 x 512 x 152 #> Pixel Dimension : 0.43 x 0.43 x 0.82 #> Voxel Units : mm #> Time Units : Unknown
We see the output is a
nifti object. We can think of this as an array with additional information (called a header). We can do simple operations on the image, such as
sum(img) #>  4073996312 sum(img > 1000) #>  278650
Let’s say we want to set all values greater than 1000 to 1000 and then write the image out. We will use the
writenii function. We will copy
img2 because we want to keep
img as is. Again we will write the image to a temporary file because we don’t need this after the session:
= img img2 > 1000] = 1000 img2[ img2 = tempfile(fileext = ".nii.gz") outfile writenii(img2, outfile) file.exists(outfile) #>  TRUE
nifti object is not a standard R object, you can perform standard operations on these objects, such as addition/subtraction and logic. This is referred to “overloaded” operators.
For example, if we want to create a
nifti object with binary values, where the values are
TRUE if the values in
img are greater than 0, we can simply write:
= img > 0 above_zero class(above_zero) #>  "nifti" #> attr(,"package") #>  "oro.nifti" img_data(above_zero) #>  FALSE
We will refer to binary images/
nifti objects as “masks”.
We can combine multiple operators, such as creating a binary mask for value greater than 0 and less than 2.
class(img > 0 & img < 2) #>  "nifti" #> attr(,"package") #>  "oro.nifti"
We can also show the
class(img * 2) #>  "nifti" #> attr(,"package") #>  "oro.nifti" class(img + (img / 4)) #>  "nifti" #> attr(,"package") #>  "oro.nifti" class(img * img) #>  "nifti" #> attr(,"package") #>  "oro.nifti" class(img^2) #>  "nifti" #> attr(,"package") #>  "oro.nifti"
neurobase::ortho2 function expands the
oro.nifti::orthographic function for displaying
nifti objects in 3 different planes:
We see that in
ortho2 there are annotations of the orientation of the image. Again, if the image was not reoriented, then these many not be correct. You can turn these off with the
::ortho2(img, add.orient = FALSE)neurobase
We may want to view a single slice of an image. The
oro.nifti::slice function can be used here.
::slice(img, z = 45)oro.nifti
We can also get a view of multiple slices:
::slice(img, z = c(45, 50))oro.nifti
We can specify
z the same way but change the
plane to be different to get a different slice of the brain:
::slice(img, z = 52, plane = "sagittal")oro.nifti
We can similarly do the same for “coronal” slices.
We can also overlay one slice of an image upon another using the
oro.nifti::overlay function. Here we must specify
plot.type for only one slice.
overlay(img, y = img > quantile(img, 0.9), z = 45, plot.type = "single", NA.y = TRUE)