Why a new class?
Fastai 2 provides support to read and display medical images using pydicom and pillow; however, only 2D images can be read. Therefore, no direct support of 3D volumes is provided by fastai. Furthermore, fastai only allows to read DICOM 2D images, not volumes, DICOM series or any of the other medical formats such as NIfTI, NRRD etc. For effective work with medical data, all possible formats should be supported. Therefore, in faimed3d
, SimpleITK is used to read images. SimpleITK is a powerfull library which can handle many data formats, including all of the above mentioned and many more. It is widely used for medical applications and very fast, as it is written in pure C++.
To allow specific augmentations, only to 3D data, two new classes are used in faimed3d
: TensorDicom3D
for 3D image volumes and TensorMask3D
for segmentation masks. Both are subclasses to torch.Tensor
. A basic support for header information will be implemented in both classes, as the header sometimes has important information, e.g. for re-scaling of the pixel values, pixel spacing or patient orientation.
fn = '../data/series/radiopaedia_10_85902_1.nii.gz'
im = TensorDicom3D.create(fn, load_header=True)
test_eq(hasattr(im, '_metadata'), True)
test_eq(hasattr(im[0], '_metadata'), True)
im2 = im
test_eq(im._metadata, im2._metadata)
test_eq(isinstance(im[im > 3], Tensor), True)
_ = torch.stack((im, im2))
show_image_3d(im, axis = 0, nrow = 10)
Sometimes multiple 3D images (e.g. a batch) need to be displayed. With a wrapper for show_image_3d
this is possible.
show_images_3d(torch.stack((im,im)), axis = 0, nrow = 31, figsize = (25, 15))
from torch import Tensor # for compatibility with show_docs
im.show()
Rendering 3D objects
Somtimes the mask is better viewed as a 3D object. Rendering is implemented as described in this example: https://scikit-image.org/docs/dev/auto_examples/edges/plot_marching_cubes.html A faster, more flexible way might be using ipyvolume or vtk.
To implement 3D rendering for the mask, the TensorMask3D class needs to be expanded.
im = TensorMask3D.create('../data/masks/radiopaedia_10_85902_1.nii.gz')
im.render_3d(alpha = (0.15,))
im.calc_volume()