Simpleitk Prototype
Simpleitk Prototype
Release 0.11
1 Contents 3
1.1 Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
1.2 Installing SimpleITK . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
1.3 Build Instructions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
1.4 User Guide . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33
1.5 Gallery . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 94
1.6 Frequently Asked Questions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 96
1.7 API Reference . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 102
i
ii
SimpleITK Documentation, Release 0.11
SimpleITK is an image analysis toolkit with a large number of components supporting general filtering operations,
image segmentation and registration. It provides a simplified interface to ITK in a variety of languages.
Contents 1
SimpleITK Documentation, Release 0.11
2 Contents
CHAPTER 1
Contents
1.1 Overview
SimpleITK is an image analysis toolkit with a large number of components supporting general filtering operations,
image segmentation and registration. It is built on top of the Insight Segmentation and Registration Toolkit ITK with
the intent of providing a simplified interface to ITK. SimpleITK itself is written in C++ but is available for a large
number of programming languages. Currently these include:
• Python
• R
• Java
• C#
• Lua
• TCL
• Ruby
Wrapping of the C++ code is accomplished through SWIG, in principle, any language wrapped by SWIG should be
applicable to SimpleITK.
Unlike ITK’s support of n-dimensional spatio-temporal images, SimpleITK supports 2D, 3D and optionally 3D+time.
The dimensionality refers to spatio-temporal dimensions, the voxels can be n-dimensional vectors.
SimpleITK is licensed under the Apache License in the same way as ITK.
Typically, you don’t need to build SimpleITK to use it. You can simply download the binaries and get started right
away!
Currently, Python binaries are available on Windows, Linux and Mac OS X. C# and Java binaries are available for
Windows. We are also working towards supporting R packaging.
1.2.1 Python
Virtual environments are highly recommended. They allow you to elegantly deal with package compatibility issues.
3
SimpleITK Documentation, Release 0.11
You can always manually download the wheels for your operating system and Python version directly from source-
forge. You might need to update your pip using pip install -U pip.
The pip package manager should automatically find the correct package for MS Windows and GNU Linux if your
version is supported. For Apple OS X you need to manually specify:
pip install https://sourceforge.net/projects/simpleitk/files/SimpleITK/0.10.0/Python/SimpleITK-0.10.0
Beta and release candidate packages are also available on Anaconda cloud under the dev label
conda install -c https://conda.anaconda.org/simpleitk/label/dev SimpleITK
Binaries for select C# platform can be found on SimpleITK’s SourceForge page. Installing the library should only
involve importing the unzipped files into you C# environment.
The files have the following naming convention:
SimpleITK-version-CSharp-buildplatform-targetplatform.zip
A guide describing how to set up a C# Visual Studio project with SimpleITK can be found here. For platforms other
than Windows, you might have to build manually as described in Building SimpleITK.
1.2.3 Java
Binaries for select Java platforms can be found on SimpleITK’s SourceForge page.
Following files are currently available:
SimpleITK-0.10.0-Java-win64.zip
SimpleITK-0.10.0-Java-win32.zip
Detailed instructions are available at Visual guide to SimpleITK with Java. For platforms other than Windows, you
might have to build manually as described in Building SimpleITK.
4 Chapter 1. Contents
SimpleITK Documentation, Release 0.11
The latest binaries for the current development version of SimpleITK are also generally available. Binary packages
are built as part of the nightly regression testing system. The download links are available from the CDash dashboard
in the “Nightly Packages” section.
Each row on the dashboard is a SimpleITK build on a particular system, and if the build was successful there will be
a package icon: package.png which links to the packages build by the system. A user may directly download the built
package from such a link.
In many cases, you do not need to build SimpleITK because of the pre-built binaries available (see Installing Sim-
pleITK). However there are several reasons you might prefer to build SimpleITK from source:
• The binary files for your programming language of choice are not (yet) distributed
• You want the live on the bleeding edge by using the latest-and-greatest version of SimpleITK
• You want to wrap your own filters using the SimpleITK infrastructure
• You want to contribute to the development of SimpleITK
• To use the SimpleITK’s C++ interface and/or use ITK directly
On this page
• Prerequisites
• Recipes/ Formulas/ Short Cuts
– Mac
– Anaconda Python
– R
– Lua
• Building
– Obtaining Source Code
– Building using SuperBuild
– Building manually
– Testing
– Python installation
– R installation
• Recommended Software
– Fiji (Fiji is Just ImageJ)
* ImageJ
– iPython and Jupyter
Prerequisites
• To use the latest developmental version, source code can be downloaded with git >= 1.65
– Git is required if building SimpleITK using “SuperBuild” (see below) to automatically download the
matching version of ITK and SWIG
– Windows users may prefer msysGit
It is recommended to have numpy installed when testing Python bindings.
For some environments we have short cuts, scripts, for automated building of SimpleITK.
Mac
On the Mac, with the Homebrew package manager, a SimpleITK formula is available:
https://github.com/Homebrew/homebrew-science/blob/master/simpleitk.rb for multiple language wrappings.
# available install options can be listed using
brew options homebrew/science/simpleitk
# for example, you can install with java and lua support as follows
brew install homebrew/science/simpleitk --with-java --with-lua
Anaconda Python
For the Anaconda Python distribution: The recipe for the SimpleITK build is in the official conda-recipe repository.
# get the recipe
git clone https://github.com/conda/conda-recipes.git
cd conda-recipes/python
# build with your default Python (likely 2.7)
conda build simpleitk
# or build with 3.x
CONDA_PY=34 conda build simpleitk
For the R language you can use the devtools installer (currently only for Linux/OS X): This script will download, build
and install SimpleITK into your R environment. Please modify the number of processors to use based on your system
(in our example below we set it to six)
devtools::install_github("SimpleITK/SimpleITKRInstaller", args=c('--configure-vars="MAKEJ=6"'))
Lua
For the Lua language with the Luarocks module deployment system, a SimpleITK rockspec is available on github.
# get the rock spec
git clone https://github.com/SimpleITK/SimpleITKLuaRock.git
cd SimpleITKLuaRock
# build and install the SimpleITK Lua module
luarocks install simpleitk-1.0-0.rockspec
6 Chapter 1. Contents
SimpleITK Documentation, Release 0.11
Building
After downloading SimpleITK’s source code we STRONGLY recommend to run cmake on the SuperBuild subdirec-
tory of SimpleITK. Execute the following commands in the parent of the SimpleITK source directory to configure the
SuperBuild:
mkdir SimpleITK-build
cd SimpleITK-build
cmake ../SimpleITK/SuperBuild
The SuperBuild will automatically download and build the matching version of ITK and SWIG needed to compile
SimpleITK. Additionally, it will set recommended compilation flags to minimize the size of the library and enable
support for large libraries. This is the recommended way to build SimpleITK and is easiest.
Note: If you get an error message saying that ITK_DIR is not set then, you did not correctly point cmake to the
SuperBuild sub-directory. Please erase your binary directory, and point cmake to the SimpleITK/SuperBuild sub-
directory.
The cmake configuration process should automatically find supported languages and enable SimpleITK wrapping for
them. To manually enable a language toggle the appropriate WRAP_LANGUAGE cmake variable to ON. Verify
and/or correct the advanced cmake variables to the language specific executable, libraries and include directories. For
example if you have multiple Python installations ensure that all related Python variable refer to the same versions.
Then use your make utility or your cmake chosen build utility to build SimpleITK. SimpleITK takes a while to build.
Building manually
This is not the recommended way of building SimpleITK, but it can be useful if you want to use a system version of
ITK and/or SWIG, or if you do not want to (or can not) use git (due to firewall, etc).
1. Setup the prerequisites as described above (i.e. CMake and supported compiler)
2. Install the matching version of SWIG >= 3.0.5 e.g. Windows users may install swigwin-3.0.5
3. Download the SimpleITK source code from the SourceForge page
4. Download the matching version of ITK e.g. SimpleITK 0.10.0 uses ITK 4.10.0 (tag v4.10.0)
5. Configure ITK using CMake BUILD_EXAMPLES=OFF, BUILD_TESTING=OFF,
BUILD_SHARED_LIBS=OFF, ITK_USE_REVIEW=ON
6. Build ITK Be sure to note the build settings e.g. Release x64
7. Configure SimpleITK using CMake Set ITK_DIR to the location of the ITK build location from the previous
steps
8. Build SimpleITK Be sure to configure the build settings exactly the same as ITK e.g. Release x64 and
CXX_FLAGS
Testing
After compilation the prudent thing to due is to test SimpleITK to ensure your build is stable and suitable for use and
installation. The following commands execute the SimpleITK tests.
cd SimpleITK-build/SimpleITK-build
ctest
On Windows you will need to specify configuration. Typically that would be the Release configuration, as such:
cd SimpleITK-build/SimpleITK-build
ctest -C Release
If all tests fail, verify that you have the testing data in your source tree (the reason for the “–recursive” flag in the git
command) AND that you have added the correct path to your *_LIBRARY_PATH.
Python installation
To install a built python package into the system Python, as root run:
cd SimpleITK-build/Wrapping/Python
python Packaging/setup.py install
Alternatively, a Python virtual environment can be created and the distribution installed there. If you build the “dist”
target a Python Wheel file (.whl) will be created in the “Wrapping/Python/dist” directory.
R installation
This will install the R package “SimpleITK” in /usr/local as root or your local R installation directory.
If you are working in a multi-user environment, and are considerate of your fellow users you can install the package
in a local directory:
1. Create a local directory where you will install your R packages mkdir my_R_libs
2. Add an environment variable to your .bashrc export R_LIBS="/path_to/my_R_libs"
3. source your .bashrc and check the R library path, in an R shell >.libPaths()
4. install
cd SimpleITK-build/Wrapping/R/Packaging
R CMD INSTALL -l /path_to/my_R_libs SimpleITK
8 Chapter 1. Contents
SimpleITK Documentation, Release 0.11
Recommended Software
SimpleITK has a built in function, itk::simple::Show(), which can be used for viewing images in an interactive session.
Currently, this function by default Show invokes Fiji then ImageJ to display images. ImageJ was chosen because it
can handle all the image types that SimpleITK supports, even 3D vector images with n components.
The Show function first searches the “PATH” environment variable, then additional standard locations are examined,
if problems are encountered the correct path can be added to this environment variable and the “debugOn” option to
“Show” flag set.
ImageJ If ImageJ is used then we recommend downloading a recent version of ImageJ from the official home page.
Recent versions come with support for the Nifti ( *.nii ) file format, which SimpleITK uses to export to ImageJ.
Note: Linux installation requires an additional step. The Show function searches for an executable named ImageJ
or imagej, however the default tarball does not come with this file. Instead it comes with a file names script. This file
contains the installation instructions. In short the file should be renamed to “imagej” and the site specific variables
for the installation location, and java must be set. Also consider the “newwindow” variable... Do you really want a
new instance of ImageJ launched each time you use Show? Lastly, as the installation instructions indicate, the imagej
wrapper should be in your path.
If you are using python, ipython with Jupyter is terrific environment to perform interactive computing for image
processing. With the addition of numpy and scipy, you’ll have a powerful interactive environment.
We have instructional SimpleITK Jupyter Notebooks which can help you get started.
This guide gives detailed instructions for building SimpleITK on Linux. It is written for beginners getting started with
SimpleITK. There are examples of how to develop and execute simple programs in C Sharp and Lua.
On this page
• Why Linux?
• Get Linux
• Install build tools
• Get SimpleITK source code
• Build SimpleITK
• Use SimpleITK
– A simple C# program
– A simple lua program
Why Linux?
Get Linux
The first step is to install a Linux distribution. Some popular ones are:
• Ubuntu
• Linux Mint
• Debian
And here is a comparison of those distributions.
There are many online tutorials explaining how to install your chosen Linux distribution:
• Ubuntu
– Ubuntu Installation guide
– Learn How to Install Ubuntu Linux in 5 Minutes (youtube)
– The Ubuntu Installation Guide (with pictures)
• Mint
– Linux Mint User Guide (English)
– Install Linux Mint on your Windows computer (howtogeek)
– How to Install Linux Mint (youtube)
• Debian
– Debian 7 Installation (youtube)
– Install Debian
If you are a Windows user, you may consider running Linux on a virtual machine. Some popular virtual machine
environments are:
• VirtualBox
• VMWare
If you are a Mac OS X user, you can also run Linux in a virtual machine. Two virtual machine environments for OS X
are:
• Parallels
• VMWare Fusion
Again, there are heaps of tutorials:
• Installing Ubuntu inside Windows using VirtualBox
• How to Install Ubuntu on VirtualBox
• Install Mint 16 on VirtualBox
• How to Install Linux Mint in Virtualbox (youtube)
This guide uses Debian 7, but the steps are very similar for other Linux distributions.
10 Chapter 1. Contents
SimpleITK Documentation, Release 0.11
Open a terminal window (Application Menu > Terminal Emulator) and run the following command:
sudo apt-get install cmake cmake-curses-gui gcc g++ git
Confirm that you want to install the packages (press “y”), then wait for the installation to complete.
Alternatively, you could manually select each software package from the Synaptic Package Manager (Application
Menu > Settings > Synaptic Package Manager).
By default building SimpleITK produces the SimpleITK C++ libraries and the SimpleITK Lua interpreter. It also sup-
ports bindings for other languages. To build this support, additional packages need to be installed. The following table
shows the supported language bindings and the corresponding command to install the additional packages required for
each language.
Programming Command to install the build tools
Language
C# sudo apt-get install monodevelop
Java sudo apt-get install eclipse
R sudo apt-get install r-base r-base-dev
Ruby sudo apt-get install ruby
Python sudo apt-get install python python-dev
Tcl sudo apt-get install tcl tcl-dev tk tk-dev
All languages sudo apt-get install monodevelop eclipse r-base r-base-dev ruby python python-dev tcl
tcl-dev tk tk-dev
Fig. 1.2: In the terminal, use apt-get to install the build tools
12 Chapter 1. Contents
SimpleITK Documentation, Release 0.11
Fig. 1.3: Build tools could also be installed using the software manager
The next step is to get the SimpleITK source code using git. Decide where you want to put the source code. I’m
putting mine in my home directory:
cd ~
Now download the SimpleITK source code, by entering the following command in the Terminal:
git clone --recursive http://itk.org/SimpleITK.git
Build SimpleITK
The SuperBuild generates make files which takes care of downloading and building ITK, SWIG, and Lua, as well as
SimpleITK.
14 Chapter 1. Contents
SimpleITK Documentation, Release 0.11
On my test system, a 4 core virtual machine with 16 GB of RAM, the build took just over an hour.
After the build is finished, you need to add SimpleITK to your LD_LIBRARY_PATH:
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:~/SimpleITK-build/lib
You can now (optionally) check whether the build was successful:
cd ~/SimpleITK-build
ctest
Use SimpleITK
SimpleITK is available to a variety of languages. In this section we give simple example programs demonstrating the
SimpleITK API in C Sharp and Lua.
A simple C# program
This sub-section will describe how to create a simple C# application using SimpleITK from MonoDevelop. To start
launch the C# development environment, MonoDevelop (Application Menu > Development > MonoDevelop).
Then create our new Solution (Select File > New > Solution).
Select a C# console project (C# > Console Project). Enter a suitable name e.g. “sitk” and uncheck “Create directory
for directory”. Select “Forward” and then “OK”.
namespace itk.simple
{
class MainClass
{
16 Chapter 1. Contents
SimpleITK Documentation, Release 0.11
18 Chapter 1. Contents
SimpleITK Documentation, Release 0.11
Note that in the example, the derivative image’s intensities are scaled mathematically to illustrate SimpleITK’s over-
loading of the mathematically operators. The image intensities could also be scaled using SimpleITK’s RescaleIntesity
function.
To build the project press “F8” or select Build > Build All from the menu.
To debug the project, add a breakpoint at a desired location and press “F5”.
The Gaussian Derivative image below shows the results of the C# example program.
Lua is a fast, portable, lightweight scripting language that is included with the SimpleITK source code. Because the
entire source code for Lua is less than 600kb, it takes very little space relative to large projects such as SimpleITK.
That makes Lua very popular as an embedded scripting language.
In this SimpleITK/Lua example we show how to use a text editor to produce a SimpleITK example in Lua and execute
the program.
By default, Debian with the Xfce user interface, comes with Mousepad (Application Menu > Accessories >
Mousepad), a simple text editor. Other possible editors include gedit with Gnome or kedit with KDE.
The following is a simple Lua example similar to the C# example in the previous section. This program creates an
20 Chapter 1. Contents
SimpleITK Documentation, Release 0.11
image of a Gaussian blob, computes a derivative image of the Gaussian, rescales the floating point image to 0-255,
casts it to a unsigned char image, and writes the result to a PNG file.
local sitk = {}
sitk = SimpleITK
size = sitk.VectorUInt32();
size:push_back(128);
size:push_back(128);
sigma = sitk.VectorDouble();
sigma:push_back(32.0);
sigma:push_back(32.0);
center = sitk.VectorDouble();
center:push_back(64.0);
center:push_back(64.0);
deriv = sitk.Derivative(gauss);
sitk.WriteImage(result, "sitk-lua-test.png");
building/image/linux/SimpleITK_visual_guide_step05_lua_02
The script is slightly different than the C# example in that the RescaleIntensity filter is used. In C# mathematical op-
erators are overloaded for SimpleITK images. This is not the case for Lua, so mathematical operations on SimpleITK
images are a bit more complicated. Therefore I chose to use a built in filter.
To try out the program, copy the code and paste it into Mousepad. Then Save it as “DerivativeExample.lua” and enter
the following command in a Terminal window.
~/SimpleITK-build/SimpleITK-build/bin/SimpleITKLua DerivativeExample.lua
The Lua Derivative image below shows the output of the our SimpleITK Lua example. The result is similar to,
although not the same as the C Sharp produced image. They are different because the image intensities are not scaled
in the same manner.
Java and SimpleITK are a natural fit. Like the bindings of other languages wrapped by SimpleITK, SimpleITK’s Java
bindings have a language-specific component (traditional Jar file), and a native component (native shared library).
This combination requires a little more setup, but is largely transparent to the developer.
On this page
• Eclipse Setup
• GaussianExample
• Adding SimpleITK to the Build Path
• Configure the Build Path for our Eclipse project
– Source attachment
– Javdoc location
– Native library location
• SimpleITK Java Conventions
Eclipse Setup
Download Eclipse and install it on the platform of your choice. Eclipse is a commonly used integrated development
environment (IDE) for Java, and makes development, debugging and deployment particularly streamlined.
The first step in developing for SimpleITK’s Java bindings is to create a new project in Eclipse. Simply choose File
–> New –> Project..., choosing Java Project in the Eclipse project wizard dialog, and name the project as you like. In
this example, our project is called SimpleITK Demo. Create a new class by choosing File –> New –> Class, or simply
copy the code below and paste into the project item in the Package Explorer view and Eclipse will automatically create
the class and hierarchy for you.
GaussianExample
import org.itk.simple.Image;
import org.itk.simple.SimpleITK;
/**
* @param args
*/
public static void main(String[] args) {
22 Chapter 1. Contents
SimpleITK Documentation, Release 0.11
if (args.length < 2) {
System.err.println("Usage: 'Gaussian <input> <output>'");
System.exit(1);
}
System.out.println("Starting to blur " + args[0]);
// Grab a file
Image image = SimpleITK.readImage(args[0]);
Image output = SimpleITK.discreteGaussian(image);
SimpleITK.writeImage(output, args[1]);
System.out.println("Finished blurring, writing to " + args[1]);
If Eclipse is working as expected, you should see errors on lines 19-21. These errors occurs because we have not told
Eclipse where to find SimpleITK’s jar file.
Right click on the project in the Package Explorer view and choose Build Path –> Configure Build Path....
In the Properties dialog, click on Add External JARs... and navigate to the SimpleITK jar file. When selected, click
the down arrow to expose the options for the jar.
The three options of interest are: Source attachment, Javdoc location and Native library location.
Source attachment
The Source attachment specifies where the source code for the SimpleITK jar file resides. In our case, it is distributed
as simpleitk-source.x.x.x.jar where x.x.x is the version number of SimpleITK. The source attachment
is useful for debugging the SimpleITK library, if necessary, because it allows the debugger to step through classes
provided in the SimpleITK jar file. This setting is optional.
Javdoc location
The Javadoc location is also optional, but extremely helpful in developing with Java. Having Javadoc available pro-
vides Eclipse with in-line documentation for each function, if provided. We highly recommend supplying the Javadoc
location to Eclipse.
The last option, Native library location is required. Because SimpleITK is a C++ library, all functionality is provided
through the JNI (Java Native Interface) specification. When the SimpleITK classes are loaded, a static block loads the
native library to provide all the functionality to Java. This option tells Eclipse where to search for the library; without
it a UnsatisfiedLinkError is thrown:
24 Chapter 1. Contents
SimpleITK Documentation, Release 0.11
Set the Native library location to the directory containing the platform specific JNI library, i.e.
libSimpleITKJava.jnilib on Mac OSX, libSimpleITKJava.so on Linux and SimpleITKJava.dll
on Windows. After providing the library location, our example code runs correctly. When running
this example from the command line, the native library location needs to be specified to the JVM, e.g.
-Djava.library.path=/path/to/SimpleITKRuntime.
The SimpleITK Java bindings closely follow the C++ conventions, i.e. each class contains the public member func-
tions. However, the functional interface is handled differently in Java. In particular, every static Java function must
belong to a class, unlike C++.
In SimpleITK, the functional interface is contained in a class called org.itk.simple.SimpleITK. This class
contains the functional interfaces as static member functions, i.e. org.itk.simple.SimpleITK.readImage
as shown in the example.
The naming conventions for all SimpleITK classes follows the C++ conventions, but member functions and the func-
tion interface follow the Java conventions of using CamelCase with the first letter lowercase. In Java, the C++ function
itk::simple::ReadImage becomes org.itk.simple.SimpleITK.readImage.
In this guide we will show how to setup a C# project in Microsoft Visual Studio 2012 which uses the available built
binaries for SimpleITK. The same steps and options are needed for the other versions of Visual Studio.
On this page
• Download
• Adding C# SimpleITK to a Project
• Selecting Architecture
• Adding Managed Library
• Adding Native Library
• Building an Example
Download
Binary downloads are readily available for C# for Microsoft Visual Studio. They are available on SourceForge.
Download the correct binary for you architecture you are going to target. C# for SimpleITK has two compo-
nents: Native and Managed. The native code contains the SimpleITK C++ library and is compiled for the
particular architecture. There is the “win32” for the Intel x86 32-bit architecture, and the “win64” for the Intel
x64 architecture. The correct architecture needs to be chosen.
Unzip the downloaded zip file into your “Documents” folder. Inside you will find two “dll” files: “SimpleITKC-
SharpManaged.dll” and “SimpleITKCSharpNative.dll”, as well as some documentation files.
26 Chapter 1. Contents
SimpleITK Documentation, Release 0.11
Selecting Architecture
The SimpleITK binary only supports a single architecture platform. Your project should be configured to match that
same platform.
By default, in the Toolbar “Debug” is selected for the Solution Configuration and “Any CPU” is selected for the
Solution Platform, this needs to be changed.
Bring up the “Configuration Manager” dialog from the menu “BUILD->Configuration Manger...”.
The architecture of the SimpleITK binary needs to be added, and the “Any CPU” architecture needs to be removed.
This needs to be done for both the “Active solution platforms” and the “Platform”.
28 Chapter 1. Contents
SimpleITK Documentation, Release 0.11
From the menu bar select “PROJECT->Add Reference...” to bring up the Reference Manager. Click “Browse...” and
navigate the file system to unzip “SimpleITKCSharpManaged.dll” from the binary download, then click OK to add.
From the menu bar select “PROJECT->Add Existing Item...”. Select “Executable Files” for the extension type. Then
navigate the file system to the unzipped “SimpleITKCSharpNative.dll” file from the binary download. Important: In
the “Add” button’s pull down menu select “Add As Link”.
In the Solution Explorer right click on the “SimpleITKCSharpNative.dll”, and select “Properties”.
Then for “Build Action”, choose “Content”, and “Copy to OutputDirectory” choose “Copy always”.
Building an Example
Now that we have configured the project, let up copy a basic SimpleITK example to compile and run. The Simple-
Gaussian in C# is a simple one to test our configuration. This can just be copied and pasted into the code editor.
Then from the file menu “BUILD->Build Solution” can be selected.
If all the steps were followed correctly you should now have an executable which can be run from the command line
or from within Visual Studio with the appropriate arguments provided.
30 Chapter 1. Contents
SimpleITK Documentation, Release 0.11
32 Chapter 1. Contents
SimpleITK Documentation, Release 0.11
Image Basics
Image class is basic container for image data in SimpleITK. It can hold 2 or 3 dimensional images and pixel can be
either be a scalar or a vector. A RGB image for example, is a 2 dimensional image with 3 component vector pixel.
Contents
• Construction
• Pixel Types
• Images and Physical Space
– Transform voxels to physical space
• Accessing Pixels
– Arrays/Tensors
– Slicing
• Image Operations
Construction
There are a variety of ways to create an image. All images’ initial value is well defined as zero
Image(width, height, pixelID)
Image(width, height, depth, pixelID)
Image(sizeVector, pixelID)
Image(sizeVector, pixelID, numberOfComponents)
For example, in python you can create a RGB image of size 128x64 as
import SimpleITK as sitk
image_RGB = sitk.Image([128,64], sitk.sitkVectorUInt8, 3)
Pixel Types
The pixel type is represented as an enumerated type PixelIDValueEnum . The following is a table of the enumer-
ated list.
EnumValue Description
sitkUInt8 Unsigned 8 bit integer
sitkInt8 Signed 8 bit integer
sitkUInt16 Unsigned 16 bit integer
sitkInt16 Signed 16 bit integer
sitkUInt32 Unsigned 32 bit integer
sitkInt32 Signed 32 bit integer
sitkUInt64 Unsigned 64 bit integer
sitkInt64 Signed 64 bit integer
sitkFloat32 32 bit float
sitkFloat64 64 bit float
sitkComplexFloat32 complex number of 32 bit float
sitkComplexFloat64 complex number of 64 bit float
sitkVectorUInt8 Multi-component of unsigned 8 bit integer
sitkVectorInt8 Multi-component of signed 8 bit integer
sitkVectorUInt16 Multi-component of unsigned 16 bit integer
sitkVectorInt16 Multi-component of signed 16 bit integer
sitkVectorUInt32 Multi-component of unsigned 32 bit integer
sitkVectorInt32 Multi-component of signed 32 bit integer
sitkVectorUInt64 Multi-component of unsigned 64 bit integer
sitkVectorInt64 Multi-component of signed 64 bit integer
sitkVectorFloat32 Multi-component of 32 bit float
sitkVectorFloat64 Multi-component of 64 bit float
sitkLabelUInt8 RLE label of unsigned 8 bit integers
sitkLabelUInt16 RLE label of unsigned 16 bit integers
sitkLabelUInt32 RLE label of unsigned 32 bit integers
sitkLabelUInt64 RLE 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.
You can get the type of pixel using Image::GetPixelID() and its string representation using
Image::GetPixelIDTypeAsString()
The unique feature of SimpleITK (derived from ITK) as a toolkit for image manipulation and analysis is that it views
images as physical objects occupying a bounded region in physical space. In addition images can have different
spacing between pixels along each axis, and the axes are not necessarily orthogonal. The following figure illustrates
these concepts.
34 Chapter 1. Contents
SimpleITK Documentation, Release 0.11
Note: All the transformations like rotation or affine transform are done on the underlying physical space. You can
think of image of a view of this physical space.
Out:
Fetching nac-hncma-atlas2013-Slicer4Version/Data/A1_grayT1.nrrd
Pixel Type 8
Size (288, 320, 208)
Origin (-77.625, -107.625, 119.625)
Spacing (0.75, 0.75, 0.75)
Direction (0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, -1.0, 0.0)
Transform voxels to physical space Following equation can be used to convert voxel coordinates/indices to physical
coordinates:
𝑥 = 𝐷.𝑆.𝑣 + 𝑜
where x is coordinate of the voxel in physical space, v is voxel index, o is origin, D is direction matrix and S is diag
(spacing).
These functions can be directly used to transform between voxel and physical space:
• Image::TransformContinuousIndexToPhysicalPoint()
• Image::TransformIndexToPhysicalPoint()
• Image::TransformPhysicalPointToContinuousIndex()
• Image::TransformPhysicalPointToIndex()
Let’s try these out in python
pt = (4.0, 2.0, 0.0)
idx = (30, 87, 45)
Out:
Point (4.0, 2.0, 0.0) is voxel (146, 160, 109).
Voxel (30, 87, 45) is point (-43.875, -85.125, 54.375).
Accessing Pixels
You can get the pixel values using one of Image::GetPixelAsInt8(), Image::GetPixelAsUInt32(),
Image::GetPixelAsFloat() Image::GetPixelAsDouble() etc.
Similarly, you can set the pixel values using Image::SetPixelAsInt8(), Image::SetPixelAsUInt32(),
Image::SetPixelAsFloat() Image::SetPixelAsDouble() etc.
In dynamic type languages like python and lua, GetPixel and SetPixel are available. In python, you can also
use pythonic indexing to get and set pixel values.
36 Chapter 1. Contents
SimpleITK Documentation, Release 0.11
For example
x, y, z = 10, 15, 20
# These two mean the same
print("Get pixels: {:.3f}, {:.3f}".format(image.GetPixel(x, y, z),
image[x, y, z]))
Out:
Get pixels: 8.638, 8.638
Arrays/Tensors If you have numpy library installed in python, you can convert images to arrays and vice versa
using GetArrayFromImage() and GetImageFromArray(). Similarly, if you have torch installed, you can
use GetTensorFromImage() and GetImageFromTensor(). Numpy and torch are numerical computational
libraries for python and lua respectively.
Note: While converting from tensor/array to Image, remember to set the image’s origin, spacing, and possibly
direction cosine matrix. The default values may not match the physical dimensions of your image.
Note: Image access is in x,y,z order (image.GetPixel(x,y,z) or image[x,y,z]) with zero based indexing. Note that this
is different from numpy or torch indexing which uses z, y, x order.
Out:
Size from SimpleITK: (10, 20, 30), numpy: (30, 20, 10)
npimg[1, 2, 3] = 0.0, npimg[3, 2, 1] = 1.5
sitksize = sitkimg:GetSize()
thsize = thimg:size()
print(sitksize[0], sitksize[1], sitksize[2]) -- prints 10 20 30
print(thsize[1], thsize[2], thsize[3]) -- prints 30 20 10
print(thimg[{2, 3, 4}], thimg[{3, 2, 1}],
thimg[{4, 3, 2}]) -- prints 0 0 1.5
Slicing Slice() can be used to slice the image and a dimension can be collapsed with Extract(). In python,
you can use pythonic slicing without having to use these:
import matplotlib.pyplot as plt
logo = sitk.ReadImage(fdata('SimpleITK.jpg'))
# Brute force subsampling
logo_subsampled = logo[::2, ::2]
# Get the sub-image containing the word Simple
simple = logo[0:115,:]
# Get the sub-image containing the word Simple and flip it
simple_flipped = logo[115:0:-1,:]
# display results
fig, ((ax1, ax2), (ax3, ax4)) = plt.subplots(nrows=2, ncols=2,
sharex=True,
sharey=True)
ax1.imshow(sitk.GetArrayFromImage(logo))
ax1.axis('off')
ax1.set_title("logo")
ax2.imshow(sitk.GetArrayFromImage(logo_subsampled))
ax2.axis('off')
ax2.set_title("logo_subsampled")
ax3.imshow(sitk.GetArrayFromImage(simple))
ax3.axis('off')
ax3.set_title("simple")
ax4.imshow(sitk.GetArrayFromImage(simple_flipped))
ax4.axis('off')
ax4.set_title("simple_flipped")
fig.tight_layout()
plt.show()
38 Chapter 1. Contents
SimpleITK Documentation, Release 0.11
Out:
Fetching SimpleITK.jpg
Image Operations
SimpleITK supports basic arithmetic operations between images, taking into account their physical space
img1 = sitk.Image(24, 24, sitk.sitkUInt8)
img2 = sitk.Image(img1.GetSize(), sitk.sitkUInt8)
img1[0, 0] = 10
img2[0, 0] = 30
img3 = img1 + img2
img4 = img1 + 72
print("Test add: {} {}".format(img3[0, 0], img4[0, 0]))
img2.SetOrigin([3, 5])
# Following raises error as the images are not in the
# same physical space
try:
img5 = img1 + img2
except Exception as e:
print(e)
Out:
Test add: 40 82
Exception thrown in SimpleITK Add: /tmp/SimpleITK-build/ITK-prefix/include/ITK-4.10/itkImageToImageFi
itk::ERROR: AddImageFilter(0x49bd350): Inputs do not occupy the same physical space!
InputImage Origin: [0.0000000e+00, 0.0000000e+00], InputImage_1 Origin: [3.0000000e+00, 5.0000000e+00
Tolerance: 1.0000000e-06
Following are some of the pixel-wise operations that can be used with image, image pairs or image, scalar pairs:
• Addition +
• Subtraction -
• Multiplication *
• Division /
• Modulo %
• Power **
Lot more operations like sine, cosine, exponentation etc. are also available.
Total running time of the script: ( 0 minutes 11.451 seconds)
Download Python source code: plot_image.py
Download Jupyter notebook: plot_image.ipynb
Generated by Sphinx-Gallery
myshow.py
Functions created in guides for visualization in other guides. If you want to run the code from other guides, please
download this file (by clicking Download Python source code at the bottom of the page) and add it to your
python path.
import matplotlib.pyplot as plt
import SimpleITK as sitk
if nda.ndim == 3:
# fastest dim, either component or x
c = nda.shape[-1]
elif nda.ndim == 4:
c = nda.shape[-1]
# take a z-slice
nda = nda[nda.shape[0] // 2, :, :, :]
40 Chapter 1. Contents
SimpleITK Documentation, Release 0.11
xsize = nda.shape[1]
ysize = nda.shape[0]
if nda.ndim == 2:
t.set_cmap("gray")
if(title):
plt.title(title)
plt.show()
img_slices = []
d = 0
if len(img_xslices):
img_slices += img_xslices + [img_null] * (maxlen - len(img_xslices))
d += 1
if len(img_yslices):
img_slices += img_yslices + [img_null] * (maxlen - len(img_yslices))
d += 1
if len(img_zslices):
img_slices += img_zslices + [img_null] * (maxlen - len(img_zslices))
d += 1
if maxlen != 0:
if img.GetNumberOfComponentsPerPixel() == 1:
img = sitk.Tile(img_slices, [maxlen, d])
# TO DO check in code to get Tile Filter working with vector images
else:
img_comps = []
for i in range(0, img.GetNumberOfComponentsPerPixel()):
img_slices_c = [sitk.VectorIndexSelectionCast(s, i)
for s in img_slices]
img_comps.append(sitk.Tile(img_slices_c, [maxlen, d]))
img = sitk.Compose(img_comps)
downloaddata.py
Download this file and Data folder and add them to your python path to run other examples.
Since we do not want to store large binary data files in our Git repository, we fetch_data_all from a network resource.
The data we download is described in a json file. The file format is a dictionary of dictionaries. The top level key is
the file name. The returned dictionary contains an md5 checksum and possibly a url and boolean flag indicating the
file is part of an archive. The md5 checksum is mandatory. When the optional url is given, we attempt to download
from that url, otherwise we attempt to download from the list of MIDAS servers returned by the get_midas_servers()
function. Files that are contained in archives are identified by the archive flag.
Example json file contents:
{ “SimpleITK.jpg”: { “md5sum”: “2685660c4f50c5929516127aed9e5b1a” }, “POPI/meta/00.mhd” : { “md5sum”:
“3bfc3c92e18a8e6e8494482c44654fd3”, “url”: “http://tux.creatis.insa-lyon.fr/~srit/POPI/Images/MetaImage/10-
MetaImage.tar” }, “CIRS057A_MR_CT_DICOM/readme.txt” : {
“md5sum” : “d92c97e6fe6520cb5b1a50b96eb9eb96”, “archive” : “true”
Notes: 1. The file we download can be inside an archive. In this case, the md5 checksum is that of the archive.
2. For the md5 verification to work we need to store archives on MIDAS and cannot use its on-the-fly archive down-
load mechanism (this mechanism allows users to download “directories/communities” as a single zip archive).
The issue is that every time the archive is created its md5 changes. It is likely MIDAS is also encoding the
archive’s modification/creation time as part of the md5.
Another issue is that when downloading from this type of url (e.g.
http://midas3.kitware.com/midas/download/folder/11610/ipythonNotebookData.zip) the returned data does not
have a “Content-Length” field in the header. The current implementation will throw an exception.
import hashlib
import sys
import os
import json
import errno
import warnings
# http://stackoverflow.com/questions/2028517/python-urllib2-progress-hook
42 Chapter 1. Contents
SimpleITK Documentation, Release 0.11
try:
# Python 3
from urllib.request import urlopen, URLError, HTTPError
except ImportError:
from urllib2 import urlopen, URLError, HTTPError
from xml.dom import minidom
try:
# Python 3
content_length = url_response.info().get("Content-Length")
except AttributeError:
content_length = url_response.info().getheader("Content-Length")
total_size = content_length.strip()
total_size = int(total_size)
bytes_so_far = 0
with open(outputfile, "wb") as local_file:
while 1:
try:
url_download = url_response.read(url_download_size)
bytes_so_far += len(url_download)
if not url_download:
break
local_file.write(url_download)
# handle errors
except HTTPError as e:
return "HTTP Error: {0} {1}\n".format(e.code, url)
except URLError as e:
return "URL Error: {0} {1}\n".format(e.reason, url)
if report_hook:
report_hook(bytes_so_far, url_download_size, total_size)
return "Downloaded Successfully"
# http://stackoverflow.com/questions/600268/mkdir-p-functionality-in-python?rq=1
def mkdir_p(path):
try:
os.makedirs(path)
except OSError as exc: # Python >2.5
if exc.errno == errno.EEXIST and os.path.isdir(path):
pass
else:
raise
#http://stackoverflow.com/questions/2536307/decorators-in-the-python-standard-lib-deprecated-specific
def deprecated(func):
"""This is a decorator which can be used to mark functions
as deprecated. It will result in a warning being emmitted
when the function is used."""
new_func.__name__ = func.__name__
new_func.__doc__ = func.__doc__
new_func.__dict__.update(func.__dict__)
return new_func
def get_midas_servers():
import os
midas_servers = list()
if 'ExternalData_OBJECT_STORES' in os.environ.keys():
44 Chapter 1. Contents
SimpleITK Documentation, Release 0.11
local_object_stores = os.environ['ExternalData_OBJECT_STORES']
for local_object_store in local_object_stores.split(";"):
midas_servers.append( "file://{0}/MD5/%(hash)".format(local_object_store) )
midas_servers.extend( [
# Data published by MIDAS
"http://midas3.kitware.com/midas/api/rest?method=midas.bitstream.download&checksum=%(hash)&al
# Data published by developers using git-gerrit-push.
"http://www.itk.org/files/ExternalData/%(algo)/%(hash)",
# Mirror supported by the Slicer community.
"http://slicer.kitware.com/midas3/api/rest?method=midas.bitstream.download&checksum=%(hash)&a
# Insight journal data server
"http://www.insight-journal.org/midas/api/rest?method=midas.bitstream.by.hash&hash=%(hash)"
])
return midas_servers
sys.stdout.write("Fetching {0}\n".format(onefilename))
output_file = os.path.realpath(os.path.join(output_directory, onefilename))
data_dictionary = manifest[onefilename]
md5sum = data_dictionary['md5sum']
# List of places where the file can be downloaded from
all_urls = []
if "url" in data_dictionary:
all_urls.append(data_dictionary["url"])
else:
for url_base in get_midas_servers():
all_urls.append(url_base.replace("%(hash)", md5sum).replace("%(algo)", "md5"))
new_download = False
break
# If the file exists this means the hash is invalid we have a problem.
elif os.path.exists(output_file):
error_msg = "File " + output_file
error_msg += " has incorrect hash value, " + md5sum + " was expected."
raise Exception(error_msg)
return output_file
@deprecated
def fetch_midas_data_one(onefilename, output_directory, manifest_file, verify=True, force=False):
return fetch_data_one(onefilename, output_directory, manifest_file, verify, force)
@deprecated
def fetch_midas_data_all(output_directory, manifest_file, verify=True):
return fetch_data_all(output_directory, manifest_file, verify)
46 Chapter 1. Contents
SimpleITK Documentation, Release 0.11
@deprecated
def fetch_midas_data(cache_file_name, verify=False, cache_directory_name="Data"):
return fetch_data(cache_file_name, verify, cache_directory_name)
if __name__ == '__main__':
if len(sys.argv) < 3:
print('Usage: ' + sys.argv[0] + ' output_directory manifest.json')
sys.exit(1)
output_directory = sys.argv[1]
if not os.path.exists(output_directory):
os.makedirs(output_directory)
manifest = sys.argv[2]
fetch_data_all(output_directory, manifest)
1.4.2 Segmentation
Image segmentation filters process an image to partition it into (hopefully) meaningful regions. The output is com-
monly an image of integers where each integer can represent an object. The value 0 is commonly used for the
background, and 1 ( sometimes 255) for a foreground object.
Thresholding
Thresholding is the most basic form of segmentation. It simply labels the pixels of an image based on the intensity
range without respect to geometry or connectivity.
# License: CC-BY
# sphinx_gallery_thumbnail_number = 4
Load Image
img_T1 = sitk.ReadImage(
fdata("nac-hncma-atlas2013-Slicer4Version/Data/A1_grayT1.nrrd"))
# To visualize the labels image in RGB needs a image with 0-255 range
img_T1_255 = sitk.Cast(sitk.RescaleIntensity(img_T1), sitk.sitkUInt8)
size = img_T1.GetSize()
myshow3d(img_T1_255, zslices=range(50, size[2] - 50, 20))
Out:
Fetching nac-hncma-atlas2013-Slicer4Version/Data/A1_grayT1.nrrd
Threshold
48 Chapter 1. Contents
SimpleITK Documentation, Release 0.11
Otsu Thresholding
ITK has a number of histogram based automatic thresholding filters including Huang, MaximumEntropy, Triangle,
and the popular Otsu’s method. These methods create a histogram then use a heuristic to determine a threshold value.
Otsu Thresholding for example, assumes that the image contains two classes of pixels following bi-modal histogram
and calculates the optimum threshold separating these two classes.
otsu_filter = sitk.OtsuThresholdImageFilter()
otsu_filter.SetInsideValue(0)
otsu_filter.SetOutsideValue(1)
seg = otsu_filter.Execute(img_T1)
myshow(sitk.LabelOverlay(img_T1_255, seg), "Otsu Thresholding")
50 Chapter 1. Contents
SimpleITK Documentation, Release 0.11
Out:
Computed Threshold: 227.550582886
Thresholding is the most basic form of segmentation. The first step of improvement upon the naive thresholding is a
class of algorithms called region growing.
The common theme in this class of algorithms is that a voxel’s neighbor is considered to be in the same class if its
intensities are similar to the current voxel. The definition of similar is what varies. Initial set of voxel are called seed
points. These initial seed points are usually manually selected.
We illustrate the use of three variants of this family of algorithms:
• ConnectedThreshold
• ConfidenceConnected
• VectorConfidenceConnected
We will illustrate the usage of these three filters using a cranial MRI scan (T1 and T2) and attempt to segment one of
the ventricles.
# License: CC-BY
# sphinx_gallery_thumbnail_number = 4
Load Images
img_T1 = sitk.ReadImage(
fdata("nac-hncma-atlas2013-Slicer4Version/Data/A1_grayT1.nrrd"))
# To visualize the labels image in RGB needs a image with 0-255 range
img_T1_255 = sitk.Cast(sitk.RescaleIntensity(img_T1), sitk.sitkUInt8)
size = img_T1.GetSize()
myshow3d(img_T1_255, zslices=range(50, size[2] - 50, 20), title='T1')
Out:
Fetching nac-hncma-atlas2013-Slicer4Version/Data/A1_grayT1.nrrd
Seed selection
Earlier we used 3D Slicer to determine that index: (132,142,96) was a good seed for the left lateral ventricle.
seed = (132, 142, 96)
seg = sitk.BinaryDilate(seg, 3)
myshow3d(sitk.LabelOverlay(img_T1_255, seg),
xslices=range(132, 133), yslices=range(142, 143),
zslices=range(96, 97), title="Initial Seed")
52 Chapter 1. Contents
SimpleITK Documentation, Release 0.11
Region Growing
ConnectedThreshold Here, voxel’s neighbor is considered to be in the same class if the neighboring voxel’s
intensity is within explicitly specified thresholds.
We start by using explicitly specified thresholds, you should modify these (lower/upper) to see the effects on the
resulting segmentation.
seg_con = sitk.ConnectedThreshold(img_T1, seedList=[seed],
lower=100, upper=190)
myshow3d(sitk.LabelOverlay(img_T1_255, seg_con),
xslices=range(132, 133), yslices=range(142, 143),
zslices=range(96, 97), title="Connected Threshold")
54 Chapter 1. Contents
SimpleITK Documentation, Release 0.11
myshow3d(sitk.LabelOverlay(img_T1_255, seg_conf),
xslices=range(132, 133), yslices=range(142, 143),
zslices=range(96, 97), title="ConfidenceConnected")
56 Chapter 1. Contents
SimpleITK Documentation, Release 0.11
VectorConfidenceConnected A generalization of the previous approach to vector valued images, for in-
stance multi-spectral images or multi-parametric MRI. Here,√︀The bounds for neighboring voxel’s intensity vector is
2implicitly specified bounds using the Mahalanobis distance (x − 𝜇)𝑇 Σ−1 (x − 𝜇) < 𝑐, where 𝜇 is the mean of the
vectors at the seed points, Σ is the covariance matrix and 𝑐 is a user specified constant.
Let’s load a T2 image from the same person and combine it with the T1 image to create a vector image and apply the
algorithm on it.
img_T2 = sitk.ReadImage(
fdata("nac-hncma-atlas2013-Slicer4Version/Data/A1_grayT2.nrrd"))
img_T2_255 = sitk.Cast(sitk.RescaleIntensity(img_T2), sitk.sitkUInt8)
myshow3d(sitk.LabelOverlay(img_T2_255, seg_vec),
xslices=range(132, 133), yslices=range(142, 143),
zslices=range(96, 97), title="VectorConfidenceConnected")
58 Chapter 1. Contents
SimpleITK Documentation, Release 0.11
Out:
Fetching nac-hncma-atlas2013-Slicer4Version/Data/A1_grayT2.nrrd
Use of low level segmentation algorithms such as region growing is often followed by a clean up step. In this step we
fill holes and remove small connected components. Both of these operations are achieved by using binary morpholog-
ical operations, opening (BinaryMorphologicalOpening) to remove small connected components and closing
(BinaryMorphologicalClosing) to fill holes.
SimpleITK supports several shapes for the structuring elements (kernels) including:
• sitkAnnulus
• sitkBall
• sitkBox
• sitkCross
The size of the kernel can be specified as a scalar (same for all dimensions) or as a vector of values, size per dimension.
The following code illustrates the results of such a clean up, using closing to remove holes in the original segmentation.
vectorRadius = (1, 1, 1)
kernel = sitk.sitkBall
seg_clean = sitk.BinaryMorphologicalClosing(seg_vec,
vectorRadius,
kernel)
myshow3d(sitk.LabelOverlay(img_T1_255, seg_clean),
xslices=range(132, 133), yslices=range(142, 143),
zslices=range(96, 97), title="Cleaned up segmentation")
60 Chapter 1. Contents
SimpleITK Documentation, Release 0.11
1.4.3 Transforms
Image Interpolation
We demonstrate the different interpolators available in SimpleITK available for image resampling. Their effect is
demonstrated on the Marschner-Lobb image.
import SimpleITK as sitk
import math
from myshow import myshow
Marschner-Lobb image
62 Chapter 1. Contents
SimpleITK Documentation, Release 0.11
Interpolations
•
Total running time of the script: ( 0 minutes 1.715 seconds)
Download Python source code: plot_interpolation.py
Download Jupyter notebook: plot_interpolation.ipynb
Generated by Sphinx-Gallery
64 Chapter 1. Contents
SimpleITK Documentation, Release 0.11
This guide introduces the transformation types supported by SimpleITK and illustrates how to “promote” transforma-
tions from a lower to higher parameter space (e.g. 3D translation to 3D rigid).
On this Page
• Points in SimpleITK
– Utility functions
* Print Point
* Generate Random Cloud of points
* Compute Registration Error
* Check difference between two transformations
• Global Transformations
– TranslationTransform
– Euler2DTransform
– VersorTransform
– Translation to Rigid [3D]
Points in SimpleITK
Utility functions Let’s write some functions that deal with point data in a uniform manner.
Print Point Format a point for printing, based on specified precision with trailing zeros.
def point2str(point, precision=1):
format_str = '.{0}f'.format(precision)
return ' '.join(format(c, format_str) for c in point)
Generate Random Cloud of points Generate random (uniform withing bounds) nD point cloud. Dimension is
based on the number of pairs in the bounds input.
def uniform_random_points(bounds, num_points):
internal_bounds = [sorted(b) for b in bounds]
# Generate rows for each of the coordinates according to
# the given bounds, stack into an array, and split into
# a list of points.
mat = np.vstack([np.random.uniform(b[0], b[1], num_points)
for b in internal_bounds])
return list(mat[:len(bounds)].T)
Compute Registration Error Distances between points transformed by the given transformation and their loca-
tion in another coordinate system. When the points are only used to evaluate registration accuracy (not used in the
registration) this is the target registration error (TRE).
def target_registration_errors(tx, point_list, reference_point_list):
return [np.linalg.norm(np.array(tx.TransformPoint(p)) - np.array(p_ref))
for p, p_ref in zip(point_list, reference_point_list)]
Check difference between two transformations Check whether two transformations are “equivalent” in an arbi-
trary spatial region either 3D or 2D, [x=(-10,10), y=(-100,100), z=(-1000,1000)]. This is just a sanity check, as we are
just looking at the effect of the transformations on a random set of points in the region.
def print_transformation_differences(tx1, tx2):
if tx1.GetDimension() == 2 and tx2.GetDimension() == 2:
bounds = [(-10, 10), (-100, 100)]
elif tx1.GetDimension() == 3 and tx2.GetDimension() == 3:
bounds = [(-10, 10), (-100, 100), (-1000, 1000)]
else:
raise ValueError('Transformation dimensions mismatch, '
'or unsupported transformation dimensionality')
num_points = 10
point_list = uniform_random_points(bounds, num_points)
tx1_point_list = [tx1.TransformPoint(p) for p in point_list]
differences = target_registration_errors(tx2, point_list, tx1_point_list)
In SimpleITK points can be represented by any vector-like data type. In Python these include Tuple, Numpy array,
and List. In general Python will treat these data types differently, as illustrated by the print function below.
SimpleITK points represented by vector-like data structures.
66 Chapter 1. Contents
SimpleITK Documentation, Release 0.11
print('tuple : {}'.format(point_tuple))
print('numpy array : {}'.format(point_np_array))
print('list: {}'.format(point_list))
Out:
tuple : (9.0, 10.531, 11.8341)
numpy array : [ 9. 10.531 11.8341]
list: [9.0, 10.531, 11.8341]
9.00 10.53 11.83
9.00 10.53 11.83
9.00 10.53 11.83
Global Transformations
TranslationTransform A 3D translation. Note that you need to specify the dimensionality, as the sitk Translation-
Transform represents both 2D and 3D translations.
dimension = 3
offset = (1, 2, 3) # offset can be any vector-like data
translation = sitk.TranslationTransform(dimension, offset)
print(translation)
Out:
itk::simple::Transform
TranslationTransform (0x3ece350)
RTTI typeinfo: itk::TranslationTransform<double, 3u>
Reference Count: 1
Modified Time: 11580
Debug: Off
Object Name:
Observers:
none
Offset: [1, 2, 3]
Transform a point and use the inverse transformation to get the original back.
point = [10, 11, 12]
transformed_point = translation.TransformPoint(point)
translation_inverse = translation.GetInverse()
print(('original point: {} \n'
'transformed point: {} \n'
'back to original: {} \n').format(
point2str(point),
point2str(transformed_point),
point2str(translation_inverse.TransformPoint(transformed_point))))
Out:
original point: 10.0 11.0 12.0
transformed point: 11.0 13.0 15.0
back to original: 10.0 11.0 12.0
Euler2DTransform This transform applies a rigid transformation is 2D space. The transform is specified as a
rotation around arbitrary center and is followed by a translation.
rotation2D = sitk.Euler2DTransform()
rotation2D.SetTranslation((7.2, 8.4))
rotation2D.SetAngle(np.pi / 2)
Out:
original point: 10.0 11.0
transformed point: -3.8 18.4
Change the center of rotation so that it coincides with the point we want to transform, why is this a unique configura-
tion?
rotation2D.SetCenter(point)
print(('original point: {}\n'
'transformed point: {}').format(
point2str(point),
point2str(rotation2D.TransformPoint(point))))
Out:
original point: 10.0 11.0
transformed point: 17.2 19.4
VersorTransform Rotation only, parametrized by Versor (vector part of unit quaternion), quaternion defined by
rotation of theta around axis n:
𝑞 = [𝑛 sin(𝜃/2), cos(𝜃/2)]
68 Chapter 1. Contents
SimpleITK Documentation, Release 0.11
# Using a versor
rotation1 = sitk.VersorTransform([0, 0, 1, 0])
# Using axis-angle:
rotation2 = sitk.VersorTransform((0, 0, 1), np.pi)
# Using a matrix:
rotation3 = sitk.VersorTransform()
rotation3.SetMatrix([-1, 0, 0, 0, -1, 0, 0, 0, 1])
Out:
Points after transformation:
p1 = (-10.0, -100.0, 1000.0)
p2 = (-10.000000000000012, -100.0, 1000.0)
p3 = (-10.0, -100.0, 1000.0)
We applied the “same” transformation to the same point, so why are the results slightly different for the second
initialization method?
This is where theory meets practice. Using the axis-angle initialization method involves trigonometric functions which
on a fixed precision machine lead to these slight differences. In many cases this is not an issue, but it is something to
remember. From here on we will sweep it under the rug (printing with a more reasonable precision).
On this Page
• Creating and Manipulating Transforms
– Identity Transform
– Translation Transform
– Affine Transform
• Applying Transforms to Images
– Translation
– Scaling
– Rotation
– Shearing
• Composite Transform
# License: CC-BY
# sphinx_gallery_thumbnail_number = 7
Identity Transform The simplest is the Identity Transform. This transform simply returns input points unaltered.
dimension = 2
print('*Identity Transform*')
identity = sitk.Transform(dimension, sitk.sitkIdentity)
print('Dimension: {}'.format(identity.GetDimension()))
transform_point(identity, point)
Out:
*Identity Transform*
Dimension: 2
Point (1.0, 1.0) is transformed to (1.0, 1.0)
Transform are defined by two sets of parameters, the Parameters and FixedParameters.
FixedParameters are not changed during the optimization process when performing registration.
70 Chapter 1. Contents
SimpleITK Documentation, Release 0.11
Translation Transform This transform simply translates input points by a offest. For the TranslationTransform, the
Parameters are the values of this translation Offset.
print('*Translation Transform*')
translation = sitk.TranslationTransform(dimension)
print('Parameters: {}'.format(translation.GetParameters()))
print('Offset: {}'.format(translation.GetOffset()))
print('FixedParameters: {}'.format(translation.GetFixedParameters()))
transform_point(translation, point)
print('')
translation.SetParameters((3.1, 4.4))
print('Parameters: {}'.format(translation.GetParameters()))
transform_point(translation, point)
Out:
*Translation Transform*
Parameters: (0.0, 0.0)
Offset: (0.0, 0.0)
FixedParameters: ()
Point (1.0, 1.0) is transformed to (1.0, 1.0)
Affine Transform The affine transform is capable of representing translations, rotations, shearing, and scaling.
Affine transformation can be described with the following equation:
𝑥′ = 𝐴.(𝑥 − 𝑐) + 𝑡
where x is the input cordinate vector and x’ is the output cordinate vector, A is the affine matrix, t is the translation
and c is the centre of the affine transform. By default, A = I and C = 0
print('*Affine Transform*')
affine = sitk.AffineTransform(dimension)
print('Parameters: {}'.format(affine.GetParameters()))
print('FixedParameters: {}'.format(affine.GetFixedParameters()))
transform_point(affine, point)
print('')
affine.SetTranslation((3.1, 4.4))
print('Parameters: {}'.format(affine.GetParameters()))
transform_point(affine, point)
Out:
*Affine Transform*
Parameters: (1.0, 0.0, 0.0, 1.0, 0.0, 0.0)
FixedParameters: (0.0, 0.0)
Point (1.0, 1.0) is transformed to (1.0, 1.0)
A number of other transforms exist to represent non-affine deformations, well-behaved rotation in 3D, etc. See the
Next guide for more information.
Note: Resample applies transform to phyiscal space, not voxel cordinates directly. Once phyiscal space is trans-
formed, you will need to specify how you view this space by setting output origin, spacing and direction. Alternatively,
you can specify a reference image so that output origin, spacing and direction are set to that of the reference image.
In the following resample function, output image Origin, Spacing, Size, Direction are taken from the reference
def resample(image, transform):
reference_image = image
interpolator = sitk.sitkCosineWindowedSinc
default_value = 100.0
return sitk.Resample(image, reference_image, transform,
interpolator, default_value)
72 Chapter 1. Contents
SimpleITK Documentation, Release 0.11
Out:
Point (1.0, 1.0) is transformed to (4.1, 5.6)
What happened? The translation is positive in both directions. Why does the output image move down and to the left?
Note: It important to keep in mind that a transform in a resampling operation defines the transform from the output
space to the input space.
inv_translation = translation.GetInverse()
transform_point(inv_translation, point)
resampled = resample(grid, inv_translation)
myshow(resampled, 'Inverse Resampled')
Out:
Point (1.0, 1.0) is transformed to (-2.1, -3.5999999999999996)
An affine (line preserving) transformation, can perform translation, scaling, rotation and shearing:
Translation
x_translation, y_translation = (3.1, 4.6)
affine = sitk.AffineTransform(2)
affine.SetTranslation((x_translation, y_translation))
resampled = resample(grid, affine)
myshow(resampled, 'Translated')
Scaling
x_scale, y_scale = 3.0, 0.7
affine = sitk.AffineTransform(2)
affine.Scale((x_scale, y_scale))
resampled = resample(grid, affine)
myshow(resampled, 'Scaled')
74 Chapter 1. Contents
SimpleITK Documentation, Release 0.11
Rotation We can either use AffineTransform::Rotate or directly set rotation matrix. Let’s take the first
route.
degrees = 20
affine = sitk.AffineTransform(2)
radians = np.pi * degrees / 180.
affine.Rotate(axis1=0, axis2=1, angle=radians)
resampled = resample(grid, affine)
myshow(resampled, 'Rotated')
matrix = np.eye(2)
matrix[0, 1] = -x_shear
matrix[1, 0] = -y_shear
print(matrix)
affine.SetMatrix(matrix.ravel())
resampled = resample(grid, affine)
myshow(resampled, 'Sheared')
Out:
[[ 1. -0.3]
[-0.1 1. ]]
Composite Transform
It is possible to compose multiple transform together into a single transform object. With a composite transform,
multiple resampling operations are prevented, so interpolation errors are not accumulated. For example, an affine
transformation that consists of a translation and rotation:
translate = (8.0, 16.0)
rotate = 20.0
affine = sitk.AffineTransform(2)
affine.SetTranslation(translate)
affine.Rotate(axis1=0, axis2=1, angle=np.pi / 180 * rotate)
76 Chapter 1. Contents
SimpleITK Documentation, Release 0.11
This can also be represented with two Transform objects applied in sequence with a Composite Transform:
translation = sitk.TranslationTransform(2)
translation.SetOffset(translate)
affine = sitk.AffineTransform(2)
affine.Rotate(axis1=0, axis2=1, angle=np.pi / 180 * rotate)
Visualizing 2D images
In this example, we will explore using matplotlib to display images in our notebooks, and work towards developing a
reusable function to display 2D,3D, color for SimpleITK images.
import matplotlib.pyplot as plt
import SimpleITK as sitk
from downloaddata import fetch_data as fdata
Out:
Fetching cthead1.png
Fetching VM1111Shrink-RGB.png
78 Chapter 1. Contents
SimpleITK Documentation, Release 0.11
SimpleITK has a built in Show method which saves the image to disk and launches a user configurable program (
defaults to ImageJ ), to display the image.
sitk.Show(img1, title="cthead1")
sitk.Show(img2, title="Visible Human Head")
nda = sitk.GetArrayFromImage(img2)
plt.imshow(nda)
Let’s write a function which directly takes Image object and shows it.
def myshow(img):
nda = sitk.GetArrayFromImage(img)
plt.imshow(nda)
plt.show()
80 Chapter 1. Contents
SimpleITK Documentation, Release 0.11
if nda.ndim == 3:
# fastest dim, either component or x
c = nda.shape[-1]
elif nda.ndim == 4:
c = nda.shape[-1]
# take a z-slice
nda = nda[nda.shape[0] // 2, :, :, :]
xsize = nda.shape[1]
ysize = nda.shape[0]
if nda.ndim == 2:
t.set_cmap("gray")
if(title):
plt.title(title)
plt.show()
82 Chapter 1. Contents
SimpleITK Documentation, Release 0.11
The myshow function is really useful. We will build up on it for 3d images( myshow3d ) in the next guide. They
have been copied into a “myshow.py” file so that they can be imported into other guides.
Total running time of the script: ( 0 minutes 1.667 seconds)
Visualizing Segmentations
In previous guides, we’ve seen how to visualize 2d and 3d images. We’ve written functions myshow and myshow3d
which we will be using in this guide.
We will also look at the subtleties of working with image filters that require the input images’ to be overlapping.
import matplotlib.pyplot as plt
import SimpleITK as sitk
from downloaddata import fetch_data as fdata
from myshow import myshow, myshow3d
LabelOverlay In 2D
We start by loading a segmented image. As the segmentation is just an image with integral data, we can display the
labels as we would any other image.
img1 = sitk.ReadImage(fdata("cthead1.png"))
img1_seg = sitk.ReadImage(fdata("2th_cthead1.png"))
myshow(img1, title="cthead1")
myshow(img1_seg, title="Label Image as Grayscale")
•
Out:
Fetching cthead1.png
Fetching 2th_cthead1.png
We can also map the scalar label image to a color image as shown below.
84 Chapter 1. Contents
SimpleITK Documentation, Release 0.11
Most filters which take multiple images as arguments require that the images occupy the same physical space. That is
the pixel you are operating must refer to the same location. Luckily for us our image and labels do occupy the same
physical space, allowing us to overlay the segmentation onto the original image.
myshow(sitk.LabelOverlay(img1, img1_seg), title="Label Overlayed")
LabelOverlay In 3D
The Surgical Planning Laboratory at Brigham and Women’s Hospital has a wonderful Multi-modality MRI-based
Atlas of the Brain that we can use.
img_T1 = sitk.ReadImage(
fdata("nac-hncma-atlas2013-Slicer4Version/Data/A1_grayT1.nrrd"))
img_T2 = sitk.ReadImage(
fdata("nac-hncma-atlas2013-Slicer4Version/Data/A1_grayT2.nrrd"))
img_labels = sitk.ReadImage(
fdata("nac-hncma-atlas2013-Slicer4Version/Data/hncma-atlas.nrrd"))
myshow(img_T1, title='T1')
myshow(img_T2, title='T2')
myshow(sitk.LabelToRGB(img_labels), title='lables')
86 Chapter 1. Contents
SimpleITK Documentation, Release 0.11
•
Out:
Fetching nac-hncma-atlas2013-Slicer4Version/Data/A1_grayT1.nrrd
Fetching nac-hncma-atlas2013-Slicer4Version/Data/A1_grayT2.nrrd
Fetching nac-hncma-atlas2013-Slicer4Version/Data/hncma-atlas.nrrd
Why doesn’t this work? The images do not overlap in physical space.
All the functions in SimpleITK work on underlying physical space. Thefore, mismatch in physical space like image
origin etc. will raise errors.
try:
size = img_T1.GetSize()
myshow3d(sitk.LabelOverlay(img_T1, img_labels),
yslices=range(50, size[1] - 50, 20),
zslices=range(50, size[2] - 50, 20), dpi=30)
except Exception as e:
print(e)
Out:
Exception thrown in SimpleITK LabelOverlay: /tmp/SimpleITK-build/SimpleITK-build/Code/BasicFilters/sr
sitk::ERROR: Both images for LabelOverlayImageFilter don't match type or dimension!
Note interpolating a label image with an interpolator that can generate non-label values is problematic as you may
end up with an image that has more classes/labels than your original. This is why we only use the nearest neighbor
interpolator when working with label images.
Option 1: Resample the label image using the identity transformation
resampled_img_labels = sitk.Resample(img_labels, img_T1, sitk.Transform(),
sitk.sitkNearestNeighbor, 0.0,
img_labels.GetPixelID())
Overlay onto the T1 image, requires us to rescale the intensity of the T1 image to [0,255] and cast it so that it can be
combined with the color overlay (we use an alpha blending of 0.5).
rescaled_T1 = sitk.Cast(sitk.RescaleIntensity(img_T1), sitk.sitkUInt8)
myshow3d(sitk.LabelOverlay(rescaled_T1, resampled_img_labels, 0.5),
yslices=range(50, size[1] - 50, 20),
zslices=range(50, size[2] - 50, 20),
dpi=100)
Why are the two displays above different? (hint: in the calls to the “myshow3d” function the indexes of the y and z
slices are the same).
Total running time of the script: ( 0 minutes 7.928 seconds)
Download Python source code: plot_visseg.py
Download Jupyter notebook: plot_visseg.ipynb
Generated by Sphinx-Gallery
88 Chapter 1. Contents
SimpleITK Documentation, Release 0.11
Visualizing 3D images
In previous guide, we’ve seen how to visualize 2d images. We’ve written a function myshow which we will be using
in this guide.
Now lets move on to visualizing real MRI images. The Surgical Planning Laboratory at Brigham and Women’s
Hospital has a wonderful Multi-modality MRI-based Atlas of the Brain that we can use.
Please note, what is done here is for convenience and is not the common way images are displayed for radiological
work.
Get Images
img_T1 = sitk.ReadImage(
fdata("nac-hncma-atlas2013-Slicer4Version/Data/A1_grayT1.nrrd"))
img_T2 = sitk.ReadImage(
fdata("nac-hncma-atlas2013-Slicer4Version/Data/A1_grayT2.nrrd"))
img_labels = sitk.ReadImage(
fdata("nac-hncma-atlas2013-Slicer4Version/Data/hncma-atlas.nrrd"))
myshow(img_T1, title='T1')
myshow(img_T2, title='T2')
myshow(sitk.LabelToRGB(img_labels), title='lables')
•
Out:
Fetching nac-hncma-atlas2013-Slicer4Version/Data/A1_grayT1.nrrd
Fetching nac-hncma-atlas2013-Slicer4Version/Data/A1_grayT2.nrrd
Fetching nac-hncma-atlas2013-Slicer4Version/Data/hncma-atlas.nrrd
Let’s visualize all three orthogonal views. You can use sitk.Tile for tiling images.
slices = [img_T1[size[0] // 2, :, :], img_T1[:, size[1] // 2, :],
img_T1[:, :, size[2] // 2]]
myshow(sitk.Tile(slices, [3, 1]), dpi=20)
90 Chapter 1. Contents
SimpleITK Documentation, Release 0.11
92 Chapter 1. Contents
SimpleITK Documentation, Release 0.11
Let’s create a version of the show methods which allows the selection of slices to be displayed.
def myshow3d(img, xslices=[], yslices=[], zslices=[], title=None, margin=0.05,
dpi=80):
img_xslices = [img[s, :, :] for s in xslices]
img_yslices = [img[:, s, :] for s in yslices]
img_zslices = [img[:, :, s] for s in zslices]
img_slices = []
d = 0
if len(img_xslices):
img_slices += img_xslices + [img_null] * (maxlen - len(img_xslices))
d += 1
if len(img_yslices):
img_slices += img_yslices + [img_null] * (maxlen - len(img_yslices))
d += 1
if len(img_zslices):
img_slices += img_zslices + [img_null] * (maxlen - len(img_zslices))
d += 1
if maxlen != 0:
if img.GetNumberOfComponentsPerPixel() == 1:
img = sitk.Tile(img_slices, [maxlen, d])
# TO DO check in code to get Tile Filter working with vector images
else:
img_comps = []
for i in range(0, img.GetNumberOfComponentsPerPixel()):
img_slices_c = [sitk.VectorIndexSelectionCast(s, i)
for s in img_slices]
img_comps.append(sitk.Tile(img_slices_c, [maxlen, d]))
img = sitk.Compose(img_comps)
1.5 Gallery
The Canny filter is a multi-stage edge detector. It uses a filter based on the derivative of a Gaussian in order to compute
the intensity of the gradients.The Gaussian reduces the effect of noise present in the image. Then, potential edges are
thinned down to 1-pixel curves by removing non-maximum pixels of the gradient magnitude. Finally, edge pixels are
kept or removed using hysteresis thresholding on the gradient magnitude.
The Canny has three adjustable parameters: the width of the Gaussian (the noisier the image, the greater the width),
and the low and high threshold for the hysteresis thresholding.
94 Chapter 1. Contents
SimpleITK Documentation, Release 0.11
1.5. Gallery 95
SimpleITK Documentation, Release 0.11
image = sitk.ReadImage('../example_images/lena_bw.png')
image = sitk.Cast(image, sitk.sitkFloat64)
# display results
fig, (ax1, ax2, ax3) = plt.subplots(nrows=3, ncols=1, figsize=(5, 15),
sharex=True, sharey=True)
ax1.imshow(image, cmap=plt.cm.gray)
ax1.axis('off')
ax1.set_title('Input image', fontsize=20)
ax2.imshow(edges1, cmap=plt.cm.gray)
ax2.axis('off')
ax2.set_title('Canny filter, $\sigma=1$', fontsize=20)
ax3.imshow(edges2, cmap=plt.cm.gray)
ax3.axis('off')
ax3.set_title('Canny filter, $\sigma=3$', fontsize=20)
fig.tight_layout()
plt.show()
This page hosts frequently asked questions about SimpleITK, and their answers.
96 Chapter 1. Contents
SimpleITK Documentation, Release 0.11
On this page
• Installation
– Why do I get an error about a missing Dynamic Library when running SimpleITK with Python on
windows?
– I am using the binary distribution of SimpleITK for Anaconda, why do I get an error about libpng?
• How to Use
– What filters are currently available in SimpleITK?
– How do I read a RAW image into SimpleITK?
– Can I use another image file viewer beside ImageJ?
– How can I use 3D Slicer to view my images?
– How can I use a newer Java with ImageJ on Mac OS X?
• Wrapping
– Python
– Tcl
– Java
– C#
– R
• Compilation
– Is my compiler supported?
* Committed to Support
* Noted Problems
– Why am I getting a compilation error on OSX Mavericks?
– Why does the Superbuild fail compiling PCRE on Mac OS X?
– Do I need to download an option package for TR1 support?
– Do I need to download an optional package for C99?
– How do I build with Visual Studio 2008?
– What Configurations on Windows are Supported For Building?
– Why are all of the configurations not supported on Windows?
– Where is the Test Data?
1.6.1 Installation
Why do I get an error about a missing Dynamic Library when running SimpleITK with Python on
windows?
This error has been resolved with SimpleITK version 0.5.1 and should no longer occur. Upgrading to the latest
SimpleITK is encouraged.
This error occurs after you have downloaded the Windows SimpleITK binaries when you are running python and try to
import SimpleITK. There is an error about a missing DLL on Windows when you don’t have Visual Studio 10 and no
other application has installed certain libraries before. You will need to download the Visual Studio 10 redistribution
libraries. The libraries are available for download here.
I am using the binary distribution of SimpleITK for Anaconda, why do I get an error about libpng?
This can be resolved by installing the version of libpng that SimpleITK 0.9 was built against:
As of March 2014 we have approximately 260 ITK image filters wrapped for SimpleITK. The filter coverage table
shows the current set of ITK filters in SimpleITK. Additionally the Doxygen can be looked at to determine if a filter
is available.
In general raw image files are missing information. They do not contain the nessesary header information to describe
the basic size and type for the data, so this format is intrinsically deficient. The RawImageIO class is not available in
SimpleITK so there is no direct way to programmatically hard code this header information. The suggested way is to
create a Meta image header file (*.mhd) which references the raw data file and describes the size and type of the data.
The documentation on how to write a Meta image header can be found here.
The following is a sample Meta image header file, perhaps of name sample.mhd:
ObjectType = Image
NDims = 3
DimSize = 256 256 64
ElementType = MET_USHORT
ElementDataFile = image.raw (this tag must be last in a MetaImageHeader)
By default when the Show function is called, SimpleITK writes out a temporary image in Nifti format then launches
ImageJ. The user can override the file format of the temporary file and/or the application used to handle that file.
The temporary file format can be specified via the SITK_SHOW_EXTENSION environment variable. For example,
if the user wanted to export a PNG file, on Linux it might look like this:
SITK_SHOW_EXTENSION=".png"
export SITK_SHOW_EXTENSION
98 Chapter 1. Contents
SimpleITK Documentation, Release 0.11
Use of an extension unsupported by ITK results in an error message. For the supported image formats, here is the ITK
Image IO Filters.
The default display application for all image types is ImageJ. To override ImageJ with some other application, use the
SITK_SHOW_COMMAND environment variable. For instance, on Unix systems, using GNOME’s image viewer
eog would be:
SITK_SHOW_EXTENSION=".png"
export SITK_SHOW_EXTENSION
SITK_SHOW_COMMAND="eog"
export SITK_SHOW_COMMAND
To override the default display applications for only color or 3d images, there are the
SITK_SHOW_COLOR_COMMAND and SITK_SHOW_3D_COMMAND environment variables.
More details on the Show function, including use of the “%a” and “%f” tokens, is at the Show function Doxygen page.
3D Slicer is a very powerful and popular application for visualization and medical image computing. The
SITK_SHOW_COMMAND environment variable may be used to display images in Slicer instead of SimpleITK’s
default viewer, ImageJ. The following are examples of what settings for SITK_SHOW_COMMAND might look like
for Mac OS X, Linux and Windows to use Slicer.
Mac OS X
export SITK_SHOW_COMMAND=/Applications/Slicer.app/Contents/MacOS/Slicer
Linux
export SITK_SHOW_COMMAND=Slicer
Windows
set SITK_SHOW_COMMAND=:"c:\Program Files\Slicer 4.2.2-1\Slicer"
The value of SITK_SHOW_COMMAND should be modified to point to wherever Slicer is installed. If you only
want to use Slicer for volumetric 3D images, use the SITK_SHOW_3D_COMMAND environment variable instead of
SITK_SHOW_COMMAND.
By default on Mac OS X, the ImageJ application expects Java 6, which is old and unsupported. The latest supported
version of Java (currently version 8u25) can be downloaded from Oracle’s Java Development kit page. The follow-
ing bash commands will set up the SITK_SHOW_COMMAND and SITK_SHOW_COLOR_COMMAND to invoke
ImageJ’s jar file using the Java compiler.
ij="/Applications/ImageJ/"
ijcmd="java -Dplugins.dir=$ij/plugins -jar $ij/ImageJ.app/Contents/Resources/Java/ij.jar"
export SITK_SHOW_COMMAND="$ijcmd -eval 'open( \"%f\" );'"
export SITK_SHOW_COLOR_COMMAND="$ijcmd -eval 'open( \"%f\" ); run(\"Make Composite\", \"display=Compo
The first lines set a variable pointing to the standard location for the ImageJ directory. If ImageJ is installed somewhere
else, the line should be modified. The second line provides the command to launch ImageJ using the Java compiler. It
includes flags that point to ImageJ’s plugiin directory and ImageJ’s ij.jar file.
The SITK_SHOW_COMMAND tells SimpleITK.Show() to launch Java with ij.jar and then execute the open macro
with an image file. The SITK_SHOW_COLOR_COMMAND does these same things and then executes the ImageJ
“Make Composite” command to treat a multichannel image as a composite color image.
1.6.3 Wrapping
Python
Tcl
Java
C#
1.6.4 Compilation
Is my compiler supported?
SimpleITK uses advanced C++ meta-programming to instantiate ITK’s Images and Filters. Addtionally, we use some
headers which are included in the C99 and C++ TR1 extension. Therefore SimpleITK places additional requirements
on the compiler beyond what is required for ITK. In principle we require C++x03 with C99’s “stdint.h” and TR1’s
“functional”. If your compiler has those features it is likely able to be supported.
The additional requirement for a supported compiler is that it is on the nightly dashboard. With this regard, the list
of supported compilers is on the SimpleITK SimpleITK dashboard. We welcome user contributions to the nightly
dashboard to expand the list of supported compilers.
Committed to Support
• GCC 4.2-4.7
• Visual Studio 2008 with Service Pack 1 (VS9)
• Visual Studio 2012 (VS10) ( including Express )
• Visual Studio 2012 (VS11)
Noted Problems
• Compiling on a MS Windows 32-bit OS with static libraries is not supported due to lack of memory.
• With SimpleITK release 0.4.0, Visual Studio 2008 was not compiling. This problem has since been remedied in
the development branch on April 18th, 2012.
• With SimpleITK release 0.7.0, Visual Studio 2008 is not able to compile all wrapped languages at the same
time, it’s recommenced to choose one at a time.
With SimpleITK <=0.7 the following error occurred during compilation on Apple OSX 10.9 Mavericks with clang
5.0:
SimpleITK/Code/Common/include/sitkMemberFunctionFactoryBase.h:106:16: error: no member named 'tr1' i
typedef std::tr1::function< MemberFunctionResultType ( ) > FunctionObjectType;
~~~~~^
With Xcode 5.0, Apple’s distributed version of clang (5.0) changed which implementation of the C++ Standard Library
it uses by default. Previous versions of clang (4.2 and earlier) used GNU’s libstdc++ , while clang 5.0 now uses
LLVM’s libc++. SimpleITK 0.7 and earlier require certain features from C++ tr1 which are not implemented in
LLVM’s libc++ but are available in GNU’s libstdc++.
To build SimpleITK <=0.7 with clang 5.0, you can configure the compiler to use GNU’s stdlibc++. This change must
be done at the initial configuration:
cmake "-DCMAKE_CXX_FLAGS:STRING=-stdlib=libstdc++" ../SimpleITK/SuperBuild
NOTE: If you already have a build directory which has been partially configured the contents must be deleted. The
above line needs to be done for an initial configuration in an empty build directory. NOTE: This work around does not
work when with the CMake “Xcode” generator. It is recommended to just use the default “Unix Makefiles” generator,
to build SimpleITK, and get using SimpleITK, not building it.
The following is a compatibility table for clang 5.0. It shows that the default of libc++ does not work with SimpleITK,
while the other options do. The choice of which standard library to use and which C++ language standard to use are
independent.
Clang 5.0 compatibility -stdlib=libc++ -stdlib=libstdc++
(c++03) FAIL OK
-std=c++11 OK (>=0.8) OK
For SimpleITK >=0.8, support for the tr1 features migrated to C++11 has been improved with better feature detection,
and the necessary flags are now automatically added. LLVM’s libc++ will now work if compiling with the C++11
standard by adding the flag “-std=c++11” in the initial configuration.
To further complicate dependencies and interactions, some downloadable languages such as Java, or R, may be com-
piled against GNU’s libstdc++. This may cause a conflict in the types used in the interface resulting in compilation
errors while wrapping the language.
If the Xcode command line tools are not properly set up on OS X, PCRE could fail to build in the Superbuild process.
To install the command line developer tools enter the following: ‘’‘xcode-select –install
To reset the default command line tools path: ‘’‘xcode-select –reset
Visual Studio 2008 requires an additional download for TR1 support. This support is best provided with the Service
Pack 1. There is a separate TR1 feature pack which can be downloaded, but it is no longer recommended since Service
Pack 1 includes TR1 and numerous bug and performance improvements.
Visual Studio 2008 is the oldest supported Microsoft development environment that SimpleITK supports. To build
SimpleITK, certain features of C++TR1 are required. These features are best provided by the “Microsoft Visual
Studio 2008 Service Pack 1” (or try this link 1). Alternatively just the Visual C++ 2008 Feature Pack Release can be
installed. Please note that all our dashboard machines now use SP1.
Older versions of SimpleITK (<0.7.0) requires a also required a separately downloaded stdint.h for this compiler. This
is not automatically provided if needed. If it’s still needed the file can be downloaded here. For 64-bit Microsoft
Windows it should be dragged with the GUI into the appropriate include path for the architecture.
There are quite a large number of configuration options available for the Windows platform. The following table is a
guide line of what is regularly tested and confirmed to work or fail.
INSERT TABLE LATER
Legend
Nightly This combination of options is nightly tested, and known to work.
This combinations has been manually tested, and is expected to work.
It is not known if this combinations of options will work.
This combination likely has problems, and is not recommended.
FAIL These options are known not to work.
This table has been updated for the release branch, master, as of February 15th 2013.
One of the following errors frequently occur when the set of configuration options fail:
LINK : fatal error LNK1102: out of memory
LINK : fatal error LNK1248: image size (80000010) exceeds maximum allowable size (80000000)
These errors occur because of limitations in the compiler’s linker or the operating system. For 64-bit architectures the
linker is still only 32-bits on some Visual Studios. In certain configurations the linker can run out of memory. Also
the Windows operating systems have a hard limit of 2GB for the size of libraries. For Debug mode configurations this
limit can be encounted.
In general building in Debug mode should not be necessary, unless you are trying to debug SimpleITK or ITK. This
configuration produces libraries that are very large because the compiler must maintain symbols for all instantiated
ITK classes and member functions for each template parameters that a class is instantiating.
The way testing data is obtained changed with SimpleITK 0.7. If you download the source tar-ball is should be
included. If you have obtained the source code from the git repository, it should be downloaded as part of the build
process.
• genindex
• modindex
• search
103