Last updated:
0 purchases
medio 0.4.2
medio
Medical images I/O python package
This package unifies the io engines of itk, nibabel, and pydicom (including dicom-numpy) packages
in a simple and comprehensive interface.
It includes conversion between the metadata conventions, reorientations, affine matrix computation
for itk and pydicom and saving dicom series or file.
Installation
First, make sure you have the latest pip version (better to close PyCharm or any other program that
uses the environments):
(<env-name>) >pip install -U pip
Install medio with:
(<env-name>) >pip install -U medio
This will install the medio python package and its dependencies in your environment.
Requirements
The dependencies are:
python (at least 3.6)
numpy
itk
nibabel
pydicom
dicom-numpy
A conda environment .yml file is in the project's root.
Some dicom images may require installation of additional packages, gdcm for example.
Usage
There are 3 main functions in medio: read_img, save_img and save_dir.
from medio import read_img, save_img
# read a dicom series from a folder
array, metadata = read_img('data/dicom-folder/', desired_ornt='IAR')
# do your stuff and save in any format
save_img('ct.nii.gz', array, metadata, backend='nib')
Documentation
Reading and Saving Images
read_img
medio.read_img(input_path, desired_ornt=None, backend=None, dtype=None, header=False, channels_axis=-1, coord_sys='itk', **kwargs)
input_path: path-like
Path for the data to be read (str or pathlib.Path object for example). It can be a file or a
folder (in the case of a dicom series). It is the only required parameter.
If the input path is a folder, it should contain a single dicom series.
If there is more than a single series, the optional parameter series can help.
Returns: array, metadata
array of type numpy.ndarray and metadata of type medio.MetaData. The first is a numpy array
of the image, and the second is a metadata object of the image (see MetaData class
documentation).
Optional parameters:
desired_ornt: orientation string or None
The desired orientation of the returned image array, e.g. 'RAI'. If None, no reorientation is
performed.
The desired orientation is in the standard defined by coord_sys (itk by default).
See also Orientation).
If desired_ornt is the same as the original image's orientation, no reorientation is performed.
backend: 'nib', 'itk', 'pydicom', 'pdcm', or None
The backend IO engine to use: 'nib' (nibabel), 'itk' or 'pydicom' (also 'pdcm'). If None, the
backend is chosen automatically: 'nib' for nifti files (e.g. '.nii' or '.nii.gz' suffix),
otherwise 'itk'.
dtype: numpy data-type or None
If not None, equivalent to array.astype(dtype) on the returned image array.
header: bool
If True, the returned metadata includes also a metadata.header attribute that stores the raw
metadata of the file as a dictionary.
This is not implemented for series of files (folder input_path), and not used during saving.
channels_axis: int or None
If not None and the image has more than a single channel / component (e.g. RGB or RGBA), the
channels axis is channels_axis. If None, the backend's original convention is used.
coord_sys: 'itk', 'nib', or None
The coordinate system (or convention) of the desired_ornt parameter and the returned metadata.
None means that the backend will determine coord_sys, but it can lead to a backend-dependent
array and metadata.
**kwargs are additional per-backend optional parameters:
'itk' backend:
pixel_type=itk.SS: itk pixel-type or None
Itk pixel type of the image file/folder. The default value is int16 (itk.SS - Signed Short).
Other common pixel types are: itk.UC - uint8, itk.US - uint16.
You can use the function itk.ctype in order to convert C-types to itk types. For example:
itk.ctype('unsigned short') == itk.US
fallback_only=True: bool
If True, the pixel type is automatically found and if failed then pixel_type is used
(pixel_type must not be None in this case).
Note: if itk.imread(input_path) fails, using fallback_only=True will result in a slightly
inferior performance. If you know what is pixel-type of the image beforehand, you can set it
with pixel_type and use fallback_only=False.
series=None: str, int or None
If input_path is a directory that contains multiple dicom series, selecting a specific one is
possible with the series argument. It can be the exact series instance UID (str), an int
between 0 and n-1, where n is the number of series in the directory, or None.
If series is None and there are multiple series in the directory, a detailed error message
is raised.
'pydicom' backend
globber='*': str
Relevant for a directory - glob pattern for selecting the series files (all the files in the
directory by default).
allow_default_affine=False: bool
Relevant for a multiframe dicom file - if True and the dicom misses some physical tags for the
affine calculation, use a default affine value.
series=None: str, int or None
The counterpart of series in itk backend, see the explanation above.
save_img
medio.save_img(filename, np_image, metadata, use_original_ornt=True, backend=None, dtype=None, channels_axis=None, mkdir=False, parents=False, **kwargs)
filename: path-like
The file to be saved, including the format suffix.
np_image: numpy.ndarray
The image array.
metadata: medio.MetaData
The corresponding metadata, from medio.read_img for example. In the absence of a known
metadata, a default one can be constructed with medio.MetaData(np.eye(4)).
Optional parameters:
use_original_ornt: bool
Whether to save in the original orientation stored in metadata.orig_ornt or not.
backend: 'nib', 'itk' or None
The backend to use: 'nib' or 'itk'. If None, 'nib' is chosen for nifti files and 'itk' otherwise.
dtype: numpy data-type or None
If not None, equivalent to passing np_image.astype(dtype). Note that not every dtype is
supported in saving, so make sure what is the dtype of the image array you want to save.
channels_axis: int or None
If not None, the image has channels (e.g. RGB) along the axis channels_axis of np_image.
mkdir: bool
If True, creates the directory of filename.
parents: bool
To be used with mkdir=True. If True, creates also the parent directories.
'itk' backend optional parameters (**kwargs):
allow_dcm_reorient=False: bool
When saving a dicom file ('.dcm' or '.dicom' suffix) the image orientation should be right-handed.
If it is left-handed, the image can be reoriented to a right-handed orientation by setting this
parameter to True, which flips the last axis direction.
compression=False: bool
Whether to use compression in itk writer. Using a '.nii.gz' suffix in filename also compresses
the image.
save_dir
medio.save_dir(dirname, np_image, metadata, use_original_ornt=True, dtype=None, channels_axis=None, parents=False, exist_ok=False, allow_dcm_reorient=False, **kwargs)
Save a 3d numpy array np_image as a dicom series of 2d slices in the directory dirname (itk
backend).
dirname: path-like
The directory to save the files in (str or pathlib.Path). If it exists, it must be empty (unless
exist_ok is True).
The other parameters: np_image, metadata, use_original_ornt, dtype, channels_axis,
parents and allow_dcm_reorient are equivalent to those of save_img.
Additional optional parameters (**kwargs):
exist_ok: bool
If True, non-empty existing directory will not raise an error.
pattern='IM{}.dcm': str
Pattern for the filenames to save, including a placeholder ('{}') for the slice number.
For example, one can use: pattern={:03d}.
metadata_dict=None: dict or None
Dictionary of metadata for adding tags or overriding the default values. For example,
metadata_dict={'0008|0060': 'US'} will override the default 'CT' modality and set it to 'US'
(ultrasound).
Metadata Objects
Affine
medio.Affine
The affine of an image is a transformation between the index space of the array to the physical 3d
space. The Affine class is a subclass of numpy.ndarray with some special properties (attributes):
spacing, origin, and direction, which can be accessed and set. The method index2coord maps
the indices to the physical space, clone clones the affine.
This class includes also some static methods for affine construction from its components (spacing,
origin and direction) and also the inverse methods for getting the spacing, origin and direction
matrix from a general affine matrix.
For a mathematical explanation about the affine matrix see
NiBabel's affine documentation.
Some usage examples:
>>> import numpy as np
>>> from medio import Affine
>>> affine1 = Affine(np.eye(4))
>>> affine2 = Affine(direction=np.eye(3), spacing=[0.33, 1, 0.33], origin=[-90.3, 10, 1.44])
>>> index = [4, 0, 9]
>>> coord = affine2.index2coord(index)
>>> print(coord)
[-88.98 10. 4.41]
MetaData
medio.MetaData
Together with the image's numpy array, the MetaData object is a necessary component for the I/O
functions.
A MetaData object 'metadata' is mainly comprised of:
metadata.affine: the affine (of class Affine)
metadata.coord_sys: coordinate system ('itk' or 'nib')
metadata.orig_ornt: the original orientation of the image (used for saving)
metadata.header: a dictionary that includes additional metadata properties when header=True
in read_img, otherwise None
Other properties of the metadata are derived from the affine:
metadata.spacing: voxels spacing (a reference to metadata.affine.spacing)
metadata.ornt: the current image orientation (depends on the coordinate system coord_sys)
All these properties can be viewed easily in the console:
>>> import medio
>>> array, metadata = medio.read_img('avg152T1_LR_nifti.nii.gz', header=False)
>>> print(metadata)
Affine:
[[ -2. 0. 0. 90.]
[ 0. 2. 0. -126.]
[ 0. 0. 2. -72.]
[ 0. 0. 0. 1.]]
Spacing: [2. 2. 2.]
Coordinate system: nib
Orientation: LAS
Original orientation: LAS
Header: None
The MetaData method metadata.is_right_handed_ornt() checks for a right handed orientation
according to the determinant of the direction matrix (metadata.affine.direction). This method can
be useful before saving a dicom file or series, which should have a right-handed orientation.
The method clone clones the metadata object, convert converts the metadata in-place to the
given coordinate system.
Orientation
The orientation of a 3d image is string of length 3 that is derived from its affine and coordinate
system (the convention). It denotes along which physical axis we move when we increase a single
index out of i, j, k in the expression np_image[i, j, k].
For example, 'RAS' orientation in itk:
Right to Left, Anterior to Posterior, Superior to Inferior
'RAS' in nib - also 'RAS+':
Left to Right, Posterior to Anterior, Inferior to Superior
Note that the conventions are opposite. For stability reasons, we use itk convention by default
for read_img's argument desired_ornt, although one can choose otherwise with the parameter
coord_sys.
For further discussion see
NiBabel's image orientation documentation.
Array and Metadata Operations
Some operations on an image affect also its metadata, for example resizing, rotations and cropping.
The class MedImg (medio.medimg.medimg.MedImg) holds an image array with its metadata, and
supports some of these operations through the indexing syntax:
>>> from medio.medimg.medimg import MedImg
>>> mimg = MedImg(np_image, metadata)
>>> new_mimg = mimg[:, 4:-4, ::3]
>>> print(new_mimg.metadata)
Ellipsis ('...') syntax is also supported. This indexing allows cropping and basic down-sampling,
along with correct metadata update.
For personal and professional use. You cannot resell or redistribute these repositories in their original state.
There are no reviews.