Creating GIFs from MRI Scans (nii.gz)

Sam Dedes
4 min readFeb 21, 2021

This article is intended for those proficient in Python with image data in the neuroimaging data format nii.gz looking to convert into an animated gif.

Those who deal with MRI imaging data are likely to encountered the nii.gz file type. I know, a nasty looking extension, though it is very useful for those interested in analyzing MRI scan data, like detecting the presence of brain tumors. In this case, the image files are organized by directory, with different folders identifying different scan types. The following will outline the steps to retrieve the paths to the files organized like this, in addition to gif creation.

To begin, there are several packages that need to be imported.

# imports
import os
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d.art3d import Poly3DCollection
import cv2
from glob import glob
import nibabel as nib

For any packages that do not import, simply conda install or pip installfollowed by the [package name] into your command prompt/ bash. Several of these are familiar packages, like numpy and matplotlib, though some are highly specialized. For instance, nibabel was created specifically for handling neuroimaging data. See documentation here.

Moving forward, it’s wise to create a function that will fetch the desired files from the given directory for ease of use. This assumes all files are children of given directory and may be edited to filter out non nii.gz files.

def get_dir_folders(directory):
'''
Input: list-like directory containing the folder names / file
names within a given parent folder
Returns: list clean_directory containing only folder names
within the parent folder
'''
# create list copy of directory
clean_directory = list(directory)

# iterate through directory
for name in directory:

# remove all names with file extensions
print('path: ', name)

filename = name.split('/')[-1]

if '.' in filename:
print(f'remove {name} from list')
directory.remove(name)

return clean_directory

The way the function above works is it collects all the children from the given path, and returns those which do not contain ., indicative of file extensions.

Before getting the paths to your files, it may be necessary to join the path of the parent directory. This is when the files of interest are not contained within the same folder as the python file.

Using the absolute path of the parent folder that contains the folders of interest, a base path may be established.

# establish base path
absolute_path = 'C:\user\example\images'
base_path = os.path.join(absolute_path)

Using glob, all children of the parent directory may be retrieved, then the custom function will filter all but the folder names.

# get full directory and filter results 
full_directory = glob(os.path.join(base_path, '*'))
image_folders = get_dir_folders(full_directory)

A naming convention must be used to avoid including folders which do not contain desired files. I did this simply by including 'image' as part of the folder name, and filtered results from above with a simple list comprehension. However, if all files are contained in one folder simply use the folder name in place of 'image' .

image_folders =\
[folder for folder in image_folders if 'image' in folder]

Finally, to retrieve paths of all files from the desired folder, use glob and osin tandem with another list comprehension. In this case the folder of interest contains those of “T2” scan type, and is named accordingly.

image_files = glob(os.path.join(\
[folder for folder in image_folders if 'T2' in folder][0], '*'))

As mentioned above, NiBabel is a package specific to neuroimaging and will be utilized here.

img_T2 = nib.load(image_files_T2[17])
img_T2.shape
####################################################################
Returns:
(256, 256, 130)

The output above tells us that the file contains information for 130 images that are 256 x 256 pixels.

Now that the file data has been loaded into memory, a function to create a gif can be defined and used.

# define function to create gif from image data
def create_gif(input_image, title='.gif', filename='test.gif'):
# see example from matplotlib documentation
import imageio
import matplotlib.animation as animate
images = []
input_image_data = input_image.get_fdata()
fig = plt.figure() for i in range(len(input_image_data)):
im = plt.imshow(input_image_data[i], animated=True)
images.append([im])

ani = animate.ArtistAnimation(fig, images, interval=25,\
blit=True, repeat_delay=500)
plt.title(title, fontsize=20)
plt.axis('off')
ani.save(filename)
plt.show()

This function gets the array-form data from the image using the .get_fdata() method, creates a figure, adds all images to a list for safe keeping, and uses animiate.ArtistAnimation to create the .gif. There are some additional matplotlib steps done for aesthetic purposes, though they are not necessary for simple .gif creation.

Finally, use the function on image data!

create_gif(nib.load(bd_image_files_T1[0]), title=None, filename="figures/T1_MRI.gif")####################################################################
Returns:
See figure below
Gif crated from MRI data in nii.gz format

This method used may be refined or perhaps even refactored into a single function for more narrow applications. Also, the create_gif() function may be altered to create gifs from more widely used image files, perhaps even taking portions from a .mp4. In any case, this is one way to load images and create gif visualizations from the highly specialized nii.gz file type.

--

--