Welcome to the first SimpleITK Notebook demo:

SimpleITK Image Basics

This document will give a brief orientation to the SimpleITK Image class.

First we import the SimpleITK Python module. By convention our module is imported into the shorter and more pythonic "sitk" local name.


In [ ]:
import matplotlib.pyplot as plt
%matplotlib inline
import SimpleITK as sitk

Image Construction

There are a variety of ways to create an image. All images' initial value is well defined as zero.


In [ ]:
image = sitk.Image(256, 128, 64, sitk.sitkInt16)
image_2D = sitk.Image(64, 64, sitk.sitkFloat32)
image_2D = sitk.Image([32,32], sitk.sitkUInt32)
image_RGB = sitk.Image([128,128], sitk.sitkVectorUInt8, 3)

Pixel Types

The pixel type is represented as an enumerated type. The following is a table of the enumerated list.

sitkUInt8Unsigned 8 bit integer
sitkInt8Signed 8 bit integer
sitkUInt16Unsigned 16 bit integer
sitkInt16Signed 16 bit integer
sitkUInt32Unsigned 32 bit integer
sitkInt32Signed 32 bit integer
sitkUInt64Unsigned 64 bit integer
sitkInt64Signed 64 bit integer
sitkFloat3232 bit float
sitkFloat6464 bit float
sitkComplexFloat32complex number of 32 bit float
sitkComplexFloat64complex number of 64 bit float
sitkVectorUInt8Multi-component of unsigned 8 bit integer
sitkVectorInt8Multi-component of signed 8 bit integer
sitkVectorUInt16Multi-component of unsigned 16 bit integer
sitkVectorInt16Multi-component of signed 16 bit integer
sitkVectorUInt32Multi-component of unsigned 32 bit integer
sitkVectorInt32Multi-component of signed 32 bit integer
sitkVectorUInt64Multi-component of unsigned 64 bit integer
sitkVectorInt64Multi-component of signed 64 bit integer
sitkVectorFloat32Multi-component of 32 bit float
sitkVectorFloat64Multi-component of 64 bit float
sitkLabelUInt8RLE label of unsigned 8 bit integers
sitkLabelUInt16RLE label of unsigned 16 bit integers
sitkLabelUInt32RLE label of unsigned 32 bit integers
sitkLabelUInt64RLE label of unsigned 64 bit integers

There is also sitkUnknown, which is used for undefined or erroneous pixel ID's. It has a value of -1.

The 64-bit integer types are not available on all distributions. When not available the value is sitkUnknown.

More Information about the Image class be obtained in the Docstring

SimpleITK classes and functions have the Docstrings derived from the C++ definitions and the Doxygen documentation.


In [ ]:
help(image)

Accessing Attributes

If you are familliar with ITK, then these methods will follow your expectations:


In [ ]:
print image.GetSize()
print image.GetOrigin()
print image.GetSpacing()
print image.GetDirection()
print image.GetNumberOfComponentsPerPixel()

Note: The starting index of a SimpleITK Image is always 0. If the output of an ITK filter has non-zero starting index, then the index will be set to 0, and the origin adjusted accordingly.

The size of the image's dimensions have explicit accessors:


In [ ]:
print image.GetWidth()
print image.GetHeight()
print image.GetDepth()

Since the dimension and pixel type of a SimpleITK image is determined at run-time accessors are needed.


In [ ]:
print image.GetDimension()
print image.GetPixelIDValue()
print image.GetPixelIDTypeAsString()

What is the depth of a 2D image?


In [ ]:
print image_2D.GetSize()
print image_2D.GetDepth()

What is the dimension and size of a Vector image?


In [ ]:
print image_RGB.GetDimension()
print image_RGB.GetSize()

In [ ]:
print image_RGB.GetNumberOfComponentsPerPixel()

For certain file types such as DICOM, additional information about the image is contained in the meta-data dicitonary.


In [ ]:
for key in image.GetMetaDataKeys():
        print "\"{0}\":\"{1}\"".format(key, image.GetMetaData(key))

Accessing Pixels

There are the member functions GetPixel and SetPixel which provides an ITK-like interface for pixel access.


In [ ]:
help(image.GetPixel)

In [ ]:
print image.GetPixel(0, 0, 0)
image.SetPixel(0, 0, 0, 1)
print image.GetPixel(0, 0, 0)

In [ ]:
print image[0,0,0]
image[0,0,0] = 10
print image[0,0,0]

Conversion between numpy and SimpleITK


In [ ]:
nda = sitk.GetArrayFromImage(image)
print nda

In [ ]:
help(sitk.GetArrayFromImage)

In [ ]:
nda = sitk.GetArrayFromImage(image_RGB)
img = sitk.GetImageFromArray(nda)
img.GetSize()

In [ ]:
help(sitk.GetImageFromArray)

In [ ]:
img = sitk.GetImageFromArray(nda, isVector=True)
print img

The order of index and dimensions need careful attention during conversion

ITK's Image class does not have a bracket operator. It has a GetPixel which takes an ITK Index object as an argument, which is an array ordered as (x,y,z). This is the convention that SimpleITK's Image class uses for the GetPixel method as well.

While in numpy, an array is indexed in the opposite order (z,y,x).


In [ ]:
print img.GetSize()
print nda.shape
print nda.shape[::-1]

Are we still dealing with Image, because I haven't seen one yet...

While SimpleITK does not do visualization, it does contain a built in Show method. This function writes the image out to disk and than launches a program for visualization. By default it is configured to use ImageJ, because it is readily supports all the image types which SimpleITK has and load very quickly. However, it's easily customizable by setting enviroment variables.


In [ ]:
sitk.Show(image)

In [ ]:
sitk.Show?

By converting into a numpy array, matplotlob can be used for visualization for integration into the scientifc python enviroment.


In [ ]:
%matplotlib inline
import matplotlib.pyplot as plt

In [ ]:
z = 0
slice = sitk.GetArrayFromImage(image)[z,:,:]
plt.imshow(slice)