# In Python, how to convert between SimpleITK and ITK Images?

**URL:** https://discourse.itk.org/t/in-python-how-to-convert-between-simpleitk-and-itk-images/1922
**Category:** Beginner Questions
**Created:** [May 30, 2019, 3:41pm UTC](https://discourse.itk.org/t/in-python-how-to-convert-between-simpleitk-and-itk-images/1922 "2019-05-30T15:41:57Z")
**Posts on this page:** 6
**Page:** 1

<div class="post-metadata">

### Author: ![alkamid](https://discourse.itk.org/letter_avatar_proxy/v4/letter/a/3bc359/32.png) [@alkamid](https://discourse.itk.org/u/alkamid)
#### Post date: [May 30, 2019, 3:41pm UTC](https://discourse.itk.org/t/in-python-how-to-convert-between-simpleitk-and-itk-images/1922/1 "2019-05-30T15:41:57Z")

</div>

There is a C++ tutorial on how to [convert between SimpleITK and ITK](https://simpleitk.readthedocs.io/en/master/Examples/ITKIntegration/Documentation.html), but I’m struggling to translate it into Python.

```auto
In [14]: test_arr = np.ones((30, 30, 30), dtype=np.int16)                                       

In [15]: test_arr[15, 15, 15] = 999                                                             

In [16]: sitk_image = sitk.GetImageFromArray(test_arr)                                          

In [17]: sitk_image.GetPixelID()                                                                
Out[17]: 2

In [18]: itk_image = sitk_image.GetITKBase()                                                    

In [19]: itk_image                                                                              
Out[19]: <Swig Object of type 'itk::DataObject *' at 0x7f6115837f30>

In [20]: itk_image.IsNull()                                                                     
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
<ipython-input-20-ed3d70ad1fde> in <module>
----> 1 itk_image.IsNull()

AttributeError: 'SwigPyObject' object has no attribute 'IsNull'
In [22]: itk_arr = itk.array_from_image(itk_image)                                              
---------------------------------------------------------------------------
RuntimeError Traceback (most recent call last)
<ipython-input-22-1ffbcbc9e438> in <module>
----> 1 itk_arr = itk.array_from_image(itk_image)

~/anaconda3/envs/dl/lib/python3.7/site-packages/itkExtras.py in GetArrayFromImage(image_or_filter, keep_axes, update)
    255 """Get an array with the content of the image buffer
    256 """
--> 257 return _GetArrayFromImage(image_or_filter, "GetArrayFromImage", keep_axes, update)
    258 
    259 array_from_image = GetArrayFromImage

~/anaconda3/envs/dl/lib/python3.7/site-packages/itkExtras.py in _GetArrayFromImage(image_or_filter, function, keep_axes, update)
    246 keys = [k for k in itk.PyBuffer.keys() if k[0] == output(image_or_filter). __class__ ]
    247 if len(keys ) == 0:
--> 248 raise RuntimeError("No suitable template parameter can be found.")
    249 ImageType = keys[0]
    250 # Create a numpy array of the type of the input image

RuntimeError: No suitable template parameter can be found.

```

Could you please help me with this (and reverse, ITK -\> SimpleITK) conversion?

---

<div class="post-metadata">

### Author: ![zivy](https://discourse.itk.org/user_avatar/discourse.itk.org/zivy/32/1726_2.png) [@zivy](https://discourse.itk.org/u/zivy)
#### Post date: [May 30, 2019, 8:24pm UTC](https://discourse.itk.org/t/in-python-how-to-convert-between-simpleitk-and-itk-images/1922/2 "2019-05-30T20:24:10Z")

</div>

The safe way to do this is through numpy as the compiled versions of ITK and SimpleITK are not necessarily compatible. Also, be aware that the supported pixel types may differ, so some image types supported by SimpleITK are not supported by ITK and vice versa.

Below is a code snippet that does what you want (written so it is agnostic of the image dimensions):

```auto
import SimpleITK as sitk
import itk
import numpy as np

image_dimension = 2
index = [15]*image_dimension

test_arr = np.ones([32]*image_dimension, dtype=np.int16)
test_arr[index] = 999

# Create a simpleitk image from the numpy array
sitk_image = sitk.GetImageFromArray(test_arr)
print('SimpleITK image value at {0}: {1}'.format(index, sitk_image[index]))

# Create an itk image from the simpleitk image via numpy array
itk_image = itk.GetImageFromArray(sitk.GetArrayFromImage(sitk_image), is_vector = sitk_image.GetNumberOfComponentsPerPixel()>1)
itk_image.SetOrigin(sitk_image.GetOrigin())
itk_image.SetSpacing(sitk_image.GetSpacing())   
itk_image.SetDirection(itk.GetMatrixFromArray(np.reshape(np.array(sitk_image.GetDirection()), [image_dimension]*2)))
print('ITK image value at {0}: {1}'.format(index, itk_image.GetPixel(index)))

# Change the pixel value
itk_image.SetPixel(index, 888)

# Back to a simpleitk image from the itk image
new_sitk_image = sitk.GetImageFromArray(itk.GetArrayFromImage(itk_image), isVector=itk_image.GetNumberOfComponentsPerPixel()>1)
new_sitk_image.SetOrigin(tuple(itk_image.GetOrigin()))
new_sitk_image.SetSpacing(tuple(itk_image.GetSpacing()))
new_sitk_image.SetDirection(itk.GetArrayFromMatrix(itk_image.GetDirection()).flatten()) 
print('New SimpleITK image value at {0}: {1}'.format(index, new_sitk_image[index]))

```

---

<div class="post-metadata">

### Author: ![alkamid](https://discourse.itk.org/letter_avatar_proxy/v4/letter/a/3bc359/32.png) [@alkamid](https://discourse.itk.org/u/alkamid)
#### Post date: [May 31, 2019, 7:56am UTC](https://discourse.itk.org/t/in-python-how-to-convert-between-simpleitk-and-itk-images/1922/3 "2019-05-31T07:56:45Z")

</div>

Thank you for this @zivy. I was hoping that a safe conversion method exists which avoids converting to and from numpy arrays.

---

<div class="post-metadata">

### Author: ![blowekamp](https://discourse.itk.org/user_avatar/discourse.itk.org/blowekamp/32/79_2.png) [@blowekamp](https://discourse.itk.org/u/blowekamp)
#### Post date: [May 31, 2019, 1:28pm UTC](https://discourse.itk.org/t/in-python-how-to-convert-between-simpleitk-and-itk-images/1922/4 "2019-05-31T13:28:45Z")

</div>

Both ITK and SimpleITK have a `GetArrayView` method which does not do a copy the buffer. These methods just use the python `BufferObject` to hold a reference to the buffer. This will save a copy.

I believe native ITK Python has a method to import a python buffer by reference too (?), but SimpleITK does not. It can be tricky to have to manually keep track of how buffers are shared. Frequently, it leads to more problems than is actually solves.

---

<div class="post-metadata">

### Author: ![zivy](https://discourse.itk.org/user_avatar/discourse.itk.org/zivy/32/1726_2.png) [@zivy](https://discourse.itk.org/u/zivy)
#### Post date: [May 31, 2019, 2:12pm UTC](https://discourse.itk.org/t/in-python-how-to-convert-between-simpleitk-and-itk-images/1922/5 "2019-05-31T14:12:23Z")

</div>

Hello @alkamid,

I just realized I had a **serious** omission in the code above which I just corrected, you also need to copy the meta-data (origin, spacing, direction cosine matrix).

This was not an issue with the snippet because we started with a numpy array so our origin was all zeros, spacing all ones, and direction cosine matrix the identity matrix. These are the defaults when an image is created. If you start with an image that you read it will have different values for these which **must be copied over**.

---

<div class="post-metadata">

### Author: ![Theoretialperson](https://discourse.itk.org/letter_avatar_proxy/v4/letter/t/c5a1d2/32.png) [@Theoretialperson](https://discourse.itk.org/u/Theoretialperson)
#### Post date: [November 2, 2021, 2:43pm UTC](https://discourse.itk.org/t/in-python-how-to-convert-between-simpleitk-and-itk-images/1922/6 "2021-11-02T14:43:05Z")

</div>

It’s been a long time since this was posted, but I’m also facing the same problem. Because SITK is ‘simple’, there is a need to sometimes do things in e.g. numpy, or even ITK. Unfortunately there is no way to quickly (as in without any copies) transform one into the other. If you have this problem, then your only option currently is to either switch all your code to ITK or numpy, or take the performance hit. Note that although SimpleITK is ‘simple’, that doesn’t mean there can’t be a possibility to dive into a more low-level API if needed. Great libraries provide multiple levels of abstration.
