Quick start guide

Installation

To install the ITK Python package:

$ pip install itk

Usage

Basic example

Here is a simple python script that reads an image, applies a median image filter (radius of 2 pixels), and writes the resulting image in a file.

#!/usr/bin/env python3

import itk
import sys

input_filename = sys.argv[1]
output_filename = sys.argv[2]

image = itk.imread(input_filename)

median = itk.median_image_filter(image, radius=2)

itk.imwrite(median, output_filename)

ITK and NumPy

A common use case for using ITK in Python is to mingle NumPy and ITK operations on raster data. ITK provides a large number of I/O image formats and several sophisticated image processing algorithms not available in any other packages. The ability to intersperse that with the SciPy ecosystem provides a great tool for rapid prototyping.

The following script shows how to integrate NumPy and ITK:

import itk
import numpy as np

# Read input image
itk_image = itk.imread(input_filename)

# Run filters on itk.Image

# View only of itk.Image, pixel data is not copied
np_view = itk.array_view_from_image(itk_image)

# Copy of itk.Image, pixel data is copied
np_copy = itk.array_from_image(itk_image)
# Equivalent
np_copy = np.asarray(itk_image)


# Do NumPy stuff...


# Convert back to ITK, view only, data is not copied
itk_np_view = itk.image_view_from_array(np_copy)

# Convert back to ITK, data is copied
itk_np_copy = itk.image_from_array(np_copy)

Similar functions are available to work with itk.Matrix, VNL vectors and matrices:

itk.imwrite(itk_np_view, output_filename)

# VNL matrix from np.ndarray
arr = np.zeros([3,3], np.uint8)
matrix = itk.vnl_matrix_from_array(arr)

# Array from VNL matrix
arr = itk.array_from_vnl_matrix(matrix)

# VNL vector from np.ndarray
vec = np.zeros([3], np.uint8)
vnl_vector = itk.vnl_vector_from_array(vec)

# Array from VNL vector
vec = itk.array_from_vnl_vector(vnl_vector)

# itk.Matrix from np.ndarray
mat = itk.matrix_from_array(np.eye(3))

# np.ndarray from itk.Matrix
arr = itk.array_from_matrix(mat)

ITK and Xarray

An itk.Image can be converted to and from an xarray.DataArray while preserving metadata:

da = itk.xarray_from_image(image)

image = itk.image_from_xarray(da)

ITK and VTK

An itk.Image can be converted to and from a vtk.vtkImageData while preserving metadata:

vtk_image = itk.vtk_image_from_image(image)

image = itk.image_from_vtk_image(vtk_image)

ITK and napari

An itk.Image can be converted to and from a napari.layers.Image while preserving metadata with the itk-napari-conversion package.

ITK Python types

C++ type Python type NumPy dtype
float itk.F np.float32
double itk.D np.float64
unsigned char itk.UC np.uint8
std::complex<float> itk.complex[itk.F] np.complex64

This list is not exhaustive and is only presented to illustrate the type names. The complete list of types can be found in the ITK Software Guide.

Types can also be obtained from their name in the C programming language:

itk.F == itk.ctype('float') # True

To cast the pixel type of an image, use .astype:

image = itk.imread(input_filename)

# Cast to an unsigned char pixel type
cast_image = image.astype(itk.UC)

# Equivalent
cast_image = image.astype(np.uint8)

itk.imwrite(cast_image, output_filename)

Metadata dictionary

An itk.Image has a metadata dict of key: value pairs.

The metadata dictionary can be retrieved with:

meta_dict = dict(image)

For example:

In [3]: dict(image)
Out[3]:
{'0008|0005': 'ISO IR 100',
 '0008|0008': 'ORIGINAL\\PRIMARY\\AXIAL',
 '0008|0016': '1.2.840.10008.5.1.4.1.1.2',
 '0008|0018': '1.3.12.2.1107.5.8.99.484849.834848.79844848.2001082217554549',
 '0008|0020': '20010822',

Individual dictionary items can be accessed or assigned:

print(image['0008|0008'])

image['origin'] = [4.0, 2.0, 2.0]

In the Python dictionary interface to image metadata, keys for the spatial metadata, the ‘origin’, ‘spacing’, and ‘direction’, are reversed in order from image.GetOrigin(), image.GetSpacing(), image.GetDirection() to be consistent with the NumPy array index order resulting from pixel buffer array views on the image.

Access pixel data with NumPy indexing

Array views of an itk.Image provide a way to set and get pixel values with NumPy indexing syntax, e.g.:

In [6]: image[0,:2,4] = [5,5]

In [7]: image[0,:4,4:6]
Out[7]:
NDArrayITKBase([[    5,  -997],
                [    5, -1003],
                [ -993,  -999],
                [ -996,  -994]], dtype=int16)

Input/Output (IO)

Convenient functions are provided read and write from ITK’s many supported file formats:

image = itk.imread('image.tif')

# Read in with a specific pixel type.
image = itk.imread('image.tif', itk.F)

# Read in an image series.
# Pass a sorted list of files.
image = itk.imread(['image1.png', 'image2.png', 'image3.png'])

# Read in a volume from a DICOM series.
# Pass a directory.
# Only a single series, sorted spatially, will be returned.
image = itk.imread('/a/dicom/directory/')

# Write an image.
itk.imwrite(image, 'image.tif')


# Read a mesh.
mesh = itk.meshread('mesh.vtk')

# Write a mesh.
itk.meshwrite(mesh, 'mesh.vtk')


# Read a spatial transform.
transform = itk.transformread('transform.h5')

# Write a spatial transform.
itk.transformwrite(transform, 'transform.h5')

Image filters and Image-like inputs and outputs

All itk functional image filters operate on an itk.Image but also:

  • Preserves image metadata

Filter parameters

ITK filter parameters can be specified in the following ways:

# Pythonic snake case keyword arguments:
#
#   number_of_iterations
#
smoothed = itk.anti_alias_binary_image_filter(image, number_of_iterations=3)

# CamelCase keyword arguments:
#
#   NumberOfIterations
#
smoother = itk.AntiAliasBinaryImageFilter.New(image, NumberOfIterations=3)
smoother.Update()
smoothed = smoother.GetOutput()

# CamelCase Set method:
#
#   SetNumberOfIterations
#
smoother = itk.AntiAliasBinaryImageFilter.New(image)
smoother.SetNumberOfIterations(3)
smoother.Update()
smoothed = smoother.GetOutput()

Filter types

In itk, filters are optimized at compile time for each image pixel type and image dimension. There are two ways to instantiate these filters with the itk Python wrapping:

  • Implicit (recommended): Type information is automatically detected from the data. Typed filter objects and images are implicitly created.
image = itk.imread(input_filename)

# Use ITK's functional, Pythonic interface. The filter type is implied by the
# type of the input image. The filter is eagerly executed, and the output image
# is directly returned.
smoothed = itk.median_image_filter(image)

# Alternatively, create filter objects. These filter objects can be connected in
# a pipeline to stream-process large datasets. To generate the output of the
# pipeline, .Update() must explicitly be called on the last filter of the
# pipeline.
#
# We can implicitly instantiate the filter object based on the type
# of the input image in multiple ways.

# Use itk.ImageFileReader instead of the wrapping function,
# itk.imread to illustrate this example.
ImageType = itk.Image[itk.UC, 2]
reader = itk.ImageFileReader[ImageType].New(FileName=input_filename)
# Here we specify the filter input explicitly
median = itk.MedianImageFilter.New(reader.GetOutput())
# Same as above but shortened. Input does not have to be specified.
median = itk.MedianImageFilter.New(reader.GetOutput())
# Same as above. .GetOutput() does not have to be specified.
median = itk.MedianImageFilter.New(reader)

median.Update()
smoothed = median.GetOutput()
  • Explicit: This can be useful if an appropriate type cannot be determined implicitly or when a different filter type than the default is desired.

To specify the type of the filter, use the ttype keyword argument. Explicit instantiation of a median image filter:

# An apriori ImageType
PixelType = itk.F
ImageType = itk.Image[PixelType,2]
image = itk.imread(input_filename, PixelType)

# An image type dynamically determined from the type on disk
image = itk.imread(input_filename)
ImageType = type(image)

# Functional interface
# The `ttype` keyword argument specifies the filter type.
smoothed = itk.median_image_filter(image, ttype=(ImageType, ImageType))

# Object-oriented interface
reader = itk.ImageFileReader[ImageType].New(file_name=input_filename)
median = itk.MedianImageFilter[ImageType, ImageType].New()
median.SetInput(reader.GetOutput())
median.Update()
smoothed = median.GetOutput()

Instantiate an ITK object

There are two types of ITK objects. Most ITK objects, such as images, filters, or adapters, are instantiated the following way:

InputType = itk.Image[itk.F,3]
OutputType = itk.Image[itk.F,3]
median = itk.MedianImageFilter[InputType, OutputType].New()

Some objects, like a Matrix, Vector, or RGBPixel, do not require the attribute .New() to be added to instantiate them:

pixel = itk.RGBPixel[itk.UC]()

In case of doubt, look at the attributes of the object you are trying to instantiate.

Examples

Examples can be found in the ITKSphinxExamples project.