Image slicing in Python

Hi, I have a probably trivial issue, but I can’t wrap my mind around it.I am trying to slice a 3D image using indexing but I get one slice short of what one would expect. After looking into it, it seems the last slice is always missing. Here’s a simple example using a simple array:

import numpy as np
import SimpleITK as itk
 # create 
test_array = np.array([0,1,2,3,4]*6).reshape(3,2,5)
test_array = test_array.swapaxes(2,0)
test_array
Out[2]:
array([[[0, 0, 0],
        [0, 0, 0]],
       [[1, 1, 1],
        [1, 1, 1]],
       [[2, 2, 2],
        [2, 2, 2]],
       [[3, 3, 3],
        [3, 3, 3]],
       [[4, 4, 4],
        [4, 4, 4]]])

If we convert this array to an Image and take every second slice in the third dimension and convert it back to a numpy array (for easier visualization), we expect to get an array of size (3,2,3), the same as one would by using the same operation on the array directly. Instead we get this

test_img = itk.GetImageFromArray(test_array)
sliced = test_img[:,:,::2]
sliced_array = itk.GetArrayFromImage(sliced)
sliced_array
Out[3]:
array([[[0, 0, 0],
        [0, 0, 0]],
       [[2, 2, 2],
        [2, 2, 2]]])

So the last slice

[[4,4,4],
[4,4,4]]

is missing.
Is this a bug or am I missing something?

2 Likes

Hello Lara and welcome to the ITK community,

Thanks you for you clear post with illustrative examples. Your expectations are the same as mine, so I am surprised by the result as well. The implementation of this functionality is by the SliceImageFilter. I’ll be able to investigate this issue on Monday further. In the mean time could you try to directly use the SliceImageFilter to see if you can reproduce the same surprising behavior?

Hi Bradley,
thanks for the welcome!
Yes, I was able to reproduce it by using the SliceImageFilter. Just to make sure I don’t have a problem locally, I ran it on three computers using Python 3.6.8 and Python 3.5.2.

slice = itk.SliceImageFilter()
slice.SetStep((1,1,2))
sliced_filter = slice.Execute(test_img)
sliced_filter.GetSize()
Out[14]: (3, 2, 2)

sliced_filter = itk.GetArrayFromImage(sliced_filter)
sliced_filter
Out[16]: 
array([[[0, 0, 0],
        [0, 0, 0]],
       [[2, 2, 2],
        [2, 2, 2]]])

2 Likes

Great, that narrows it down to a bug in the ITK filter itself. Can you please create a GitHub issue for this bug: https://github.com/InsightSoftwareConsortium/ITK/issues

2 Likes

Thanks, I did

2 Likes

Here is the PR to address the undersizing issue with the itkSliceImageFilter:

I will look into back porting this for SimpleITK.

2 Likes