In [1]:
import SimpleITK as sitk
import os
import pandas as pd
from matplotlib import pyplot as plt
from dltk.io.augmentation import *
from dltk.io.preprocessing import *
%matplotlib inline
Fetch a single MRI image using part of the reader function defined in the data io notebook
In [2]:
# Read subject information and data paths
data_path = '../../data/IXI_HH/1mm'
all_filenames = pd.read_csv(
'../../data/IXI_HH/demographic_HH.csv',
dtype=object,
keep_default_na=False,
na_values=[]).as_matrix()
# Keep the first subject
first_subject = all_filenames[0]
# Here, we parse the `subject_id` to construct a file path to read
# an image from.
subject_id = first_subject[0]
data_path = '../../data/IXI_HH/1mm'
t1_fn = os.path.join(data_path, '{}/T1_1mm.nii.gz'.format(subject_id))
# Read the .nii image containing a brain volume with SimpleITK and get
# the numpy array:
sitk_t1 = sitk.ReadImage(t1_fn)
t1 = sitk.GetArrayFromImage(sitk_t1)
In [3]:
# Normalise the image to zero mean/unit std dev using volume statistics:
t1_white = whitening(t1)
# Normalise the image to fit [0, 1] range:
t1_norm_zo = normalise_zero_one(t1)
# Normalise the image to fit [-1, 1] range:
t1_norm_oo = normalise_one_one(t1)
In [4]:
# Visualise using matplotlib.
center_slices = [s//2 for s in t1.shape]
f, axarr = plt.subplots(1, 4, figsize=(20,5));
f.suptitle('Different intensity normalisation methods on a T1-weighted brain MR image')
img = axarr[0].imshow(np.squeeze(t1[center_slices[0], :, :]), cmap='gray');
axarr[0].axis('off')
axarr[0].set_title('Original image')
f.colorbar(img, ax=axarr[0])
img = axarr[1].imshow(np.squeeze(t1_white[center_slices[0], :, :]), cmap='gray');
axarr[1].axis('off')
axarr[1].set_title('Zero mean/unit stdev')
f.colorbar(img, ax=axarr[1])
img = axarr[2].imshow(np.squeeze(t1_norm_zo[center_slices[0], :, :]), cmap='gray');
axarr[2].axis('off')
axarr[2].set_title('[0,1] rescaling')
f.colorbar(img, ax=axarr[2])
img = axarr[3].imshow(np.squeeze(t1_norm_oo[center_slices[0], :, :]), cmap='gray');
axarr[3].axis('off')
axarr[3].set_title('[-1,1] rescaling')
f.colorbar(img, ax=axarr[3])
f.subplots_adjust(wspace=0.05, hspace=0, top=0.8)
plt.show();
In [5]:
# Crop to [64, 64, 64]
t1_cropped = resize_image_with_crop_or_pad(t1, [64, 64, 64], mode='symmetric')
# Resizing image to [128, 256, 256] required padding
t1_padded = resize_image_with_crop_or_pad(t1, [128, 256, 256], mode='symmetric')
# Visualise using matplotlib.
f, axarr = plt.subplots(1, 3, figsize=(15,5));
f.suptitle('Automatically crop or pad a volume image')
axarr[0].imshow(np.squeeze(t1[t1.shape[0]//2, :, :]), cmap='gray');
axarr[0].axis('off')
axarr[0].set_title('Original image {}'.format(t1.shape))
axarr[1].imshow(np.squeeze(t1_cropped[t1_cropped.shape[0]//2, :, :]), cmap='gray');
axarr[1].axis('off')
axarr[1].set_title('Cropped to {}'.format(t1_cropped.shape))
axarr[2].imshow(np.squeeze(t1_padded[t1_padded.shape[0]//2, :, :]), cmap='gray');
axarr[2].axis('off')
axarr[2].set_title('Padded to {}'.format(t1_padded.shape))
f.subplots_adjust(wspace=0.05, hspace=0, top=0.8)
plt.show();
Below we apply different augmentation techniques, which are commonly used for enriching the training dataset and training more robust models. These are applied to the whitened normalised image computed above.
In [6]:
# For demo purposes, extract a 2D slice from the image volume. This is just to better
# demonstrate the Gaussian offset augmentation. To demonstrate, that this works on
# volumes, we ensure that the slice is a 3D volume:
center_slices = [s//2 for s in t1.shape]
t1_slice = t1[center_slices[0]:center_slices[0]+1,:,:].copy()
print(t1_slice.shape)
# Add a feature dimension and normalise
t1_norm = np.expand_dims(normalise_one_one(t1_slice), axis=-1)
# Randomly flip the image along axis 1
t1_flipped = flip(t1_norm.copy(), axis=1)
# Add a Gaussian offset (independently for each channel)
t1_offset = add_gaussian_offset(t1_norm.copy(), sigma=0.5)
# Add Gaussian noise
t1_noise = add_gaussian_noise(t1_norm.copy(), sigma=0.25)
# Elastic transforms according to:
# [1] Simard, Steinkraus and Platt, "Best Practices for Convolutional
# Neural Networks applied to Visual Document Analysis", in Proc. of the
# International Conference on Document Analysis and Recognition, 2003.
t1_trans_low_s = elastic_transform(t1_norm.copy(), alpha=[1, 1e5, 1e5], sigma=[1, 10, 10])
t1_trans_high_s = elastic_transform(t1_norm.copy(), alpha=[10, 2e6, 2e6], sigma=[1, 25, 25])
Plot results of the different augmentations techniques
In [7]:
# Visualise using matplotlib
f, axarr = plt.subplots(2, 3, figsize=(15,10));
f.suptitle('Different augmentation methods on a T1-weighted brain MR image')
axarr[0,0].imshow(np.squeeze(t1_norm), cmap='gray', vmin=-1, vmax=1);
axarr[0,0].axis('off')
axarr[0,0].set_title('Original image')
axarr[0,1].imshow(np.squeeze(t1_flipped), cmap='gray', vmin=-1, vmax=1);
axarr[0,1].axis('off')
axarr[0,1].set_title('Flipped')
axarr[0,2].imshow(np.squeeze(t1_noise), cmap='gray', vmin=-1, vmax=1);
axarr[0,2].axis('off')
axarr[0,2].set_title('Gaussian noise')
axarr[1,0].imshow(np.squeeze(t1_offset), cmap='gray', vmin=-1, vmax=1);
axarr[1,0].axis('off')
axarr[1,0].set_title('Gaussian offset')
axarr[1,1].imshow(np.squeeze(t1_trans_low_s), cmap='gray', vmin=-1, vmax=1);
axarr[1,1].axis('off')
axarr[1,1].set_title('Deformed (low sigma)')
axarr[1,2].imshow(np.squeeze(t1_trans_high_s), cmap='gray', vmin=-1, vmax=1);
axarr[1,2].axis('off')
axarr[1,2].set_title('Deformed (high sigma)')
f.subplots_adjust(wspace=0.05, top=0.8)
plt.show();
Plot difference between elastic transformed images and original whitened image
In [8]:
f, axarr = plt.subplots(1, 2, figsize=(10,5));
f.suptitle('Difference images for random deformations with high and low sigma')
axarr[0].imshow(np.squeeze(t1_norm-t1_trans_low_s), cmap='jet');
axarr[0].axis('off')
axarr[0].set_title('sigma=10')
axarr[1].imshow(np.squeeze(t1_norm-t1_trans_high_s), cmap='jet');
axarr[1].axis('off')
axarr[1].set_title('sigma=25')
f.subplots_adjust(wspace=0.05, top=0.8)
plt.show();