# Resampling difference between SimpleITK and scipy's zoom

**URL:** https://discourse.itk.org/t/resampling-difference-between-simpleitk-and-scipys-zoom/4548
**Category:** Beginner Questions
**Tags:** python, simpleitk
**Created:** [November 4, 2021, 5:07pm UTC](https://discourse.itk.org/t/resampling-difference-between-simpleitk-and-scipys-zoom/4548 "2021-11-04T17:07:22Z")
**Posts on this page:** 3
**Page:** 1

<div class="post-metadata">

### Author: ![couzulli](https://discourse.itk.org/letter_avatar_proxy/v4/letter/c/ba8739/32.png) [@couzulli](https://discourse.itk.org/u/couzulli)
#### Post date: [November 4, 2021, 5:07pm UTC](https://discourse.itk.org/t/resampling-difference-between-simpleitk-and-scipys-zoom/4548/1 "2021-11-04T17:07:22Z")

</div>

I am checking a simple resampling operation to double the size of input array. SimpleITK’s resample output seems to be shifted to left and top by one voxel. Is there any other argument such as origin of the grid that I need to change to match scipy’s zoom output?

Scipy Zoom:

- [https://docs.scipy.org/doc/scipy/reference/generated/scipy.ndimage.zoom.html](https://docs.scipy.org/doc/scipy/reference/generated/scipy.ndimage.zoom.html)

**Sample script:**

```auto
import numpy as np
from scipy.ndimage import zoom
import SimpleITK as sitk

def sitk_resample(arr, new_shape, new_spacing):

    arr_t = np.transpose(arr, (2, 1, 0))
    sitk_arr = sitk.GetImageFromArray(arr_t)

    resampled_arr = sitk.Resample(sitk_arr,
                                  new_shape,
                                  sitk.Transform(),
                                  sitk.sitkNearestNeighbor,
                                  sitk_arr.GetOrigin(),
                                  new_spacing,
                                  sitk_arr.GetDirection(),
                                  0.0,
                                  sitk_arr.GetPixelIDValue()
                                 )

    resampled_arr = sitk.GetArrayFromImage(resampled_arr)
    resampled_arr = np.transpose(resampled_arr, (2, 1, 0))

    return resampled_arr

def scipy_zoom(arr, new_shape, new_spacing):
    zoomed_arr = [np.zeros(new_shape)]
    for i in range(1, 9):
        tmp = arr.copy()
        tmp[tmp!=i] = 0
        tmp[tmp>0] = 1
        zoom_arr = zoom(tmp, zoom=new_spacing, order=0)
        zoom_arr[zoom_arr<0.5] = 0
        zoomed_arr.append(zoom_arr)

    zoomed_arr = np.argmax(zoomed_arr, axis=0)
    
    return zoomed_arr

def main():
    arr = np.zeros((4, 4, 4), dtype=np.uint8)
    arr[1, 1, 1] = 1
    arr[1, 2, 1] = 2
    arr[2, 1, 1] = 3
    arr[2, 2, 1] = 4
    arr[1, 1, 2] = 5
    arr[1, 2, 2] = 6
    arr[2, 1, 2] = 7
    arr[2, 2, 2] = 8
    print("Input_arr\n", arr)

    new_shape = [8, 8, 8]
    new_spacing = [.5, .5, .5]

    sitk_out = sitk_resample(arr, new_shape, new_spacing)

    zoom_out = scipy_zoom(arr, new_shape, 1./np.array(new_spacing))

    print("\n\tsitk_out\t\tzoom_out\n")

    for i in range(new_shape[0]):
        for j in range(new_shape[0]):
            print(sitk_out[i,j,:], "\t", zoom_out[i,j,:])
        print()

if __name__ == " __main__":
    main()

```

**Sample Output:**

```auto
Input_arr
 [[[0 0 0 0]
  [0 0 0 0]
  [0 0 0 0]
  [0 0 0 0]]

 [[0 0 0 0]
  [0 1 5 0]
  [0 2 6 0]
  [0 0 0 0]]

 [[0 0 0 0]
  [0 3 7 0]
  [0 4 8 0]
  [0 0 0 0]]

 [[0 0 0 0]
  [0 0 0 0]
  [0 0 0 0]
  [0 0 0 0]]]

	sitk_out zoom_out

[0 0 0 0 0 0 0 0] [0 0 0 0 0 0 0 0]
[0 0 0 0 0 0 0 0] [0 0 0 0 0 0 0 0]
[0 0 0 0 0 0 0 0] [0 0 0 0 0 0 0 0]
[0 0 0 0 0 0 0 0] [0 0 0 0 0 0 0 0]
[0 0 0 0 0 0 0 0] [0 0 0 0 0 0 0 0]
[0 0 0 0 0 0 0 0] [0 0 0 0 0 0 0 0]
[0 0 0 0 0 0 0 0] [0 0 0 0 0 0 0 0]
[0 0 0 0 0 0 0 0] [0 0 0 0 0 0 0 0]

[0 0 0 0 0 0 0 0] [0 0 0 0 0 0 0 0]
[0 1 1 5 5 0 0 0] [0 0 0 0 0 0 0 0]
[0 1 1 5 5 0 0 0] [0 0 0 0 0 0 0 0]
[0 2 2 6 6 0 0 0] [0 0 0 0 0 0 0 0]
[0 2 2 6 6 0 0 0] [0 0 0 0 0 0 0 0]
[0 0 0 0 0 0 0 0] [0 0 0 0 0 0 0 0]
[0 0 0 0 0 0 0 0] [0 0 0 0 0 0 0 0]
[0 0 0 0 0 0 0 0] [0 0 0 0 0 0 0 0]

[0 0 0 0 0 0 0 0] [0 0 0 0 0 0 0 0]
[0 1 1 5 5 0 0 0] [0 0 0 0 0 0 0 0]
[0 1 1 5 5 0 0 0] [0 0 1 1 5 5 0 0]
[0 2 2 6 6 0 0 0] [0 0 1 1 5 5 0 0]
[0 2 2 6 6 0 0 0] [0 0 2 2 6 6 0 0]
[0 0 0 0 0 0 0 0] [0 0 2 2 6 6 0 0]
[0 0 0 0 0 0 0 0] [0 0 0 0 0 0 0 0]
[0 0 0 0 0 0 0 0] [0 0 0 0 0 0 0 0]

[0 0 0 0 0 0 0 0] [0 0 0 0 0 0 0 0]
[0 3 3 7 7 0 0 0] [0 0 0 0 0 0 0 0]
[0 3 3 7 7 0 0 0] [0 0 1 1 5 5 0 0]
[0 4 4 8 8 0 0 0] [0 0 1 1 5 5 0 0]
[0 4 4 8 8 0 0 0] [0 0 2 2 6 6 0 0]
[0 0 0 0 0 0 0 0] [0 0 2 2 6 6 0 0]
[0 0 0 0 0 0 0 0] [0 0 0 0 0 0 0 0]
[0 0 0 0 0 0 0 0] [0 0 0 0 0 0 0 0]

[0 0 0 0 0 0 0 0] [0 0 0 0 0 0 0 0]
[0 3 3 7 7 0 0 0] [0 0 0 0 0 0 0 0]
[0 3 3 7 7 0 0 0] [0 0 3 3 7 7 0 0]
[0 4 4 8 8 0 0 0] [0 0 3 3 7 7 0 0]
[0 4 4 8 8 0 0 0] [0 0 4 4 8 8 0 0]
[0 0 0 0 0 0 0 0] [0 0 4 4 8 8 0 0]
[0 0 0 0 0 0 0 0] [0 0 0 0 0 0 0 0]
[0 0 0 0 0 0 0 0] [0 0 0 0 0 0 0 0]

[0 0 0 0 0 0 0 0] [0 0 0 0 0 0 0 0]
[0 0 0 0 0 0 0 0] [0 0 0 0 0 0 0 0]
[0 0 0 0 0 0 0 0] [0 0 3 3 7 7 0 0]
[0 0 0 0 0 0 0 0] [0 0 3 3 7 7 0 0]
[0 0 0 0 0 0 0 0] [0 0 4 4 8 8 0 0]
[0 0 0 0 0 0 0 0] [0 0 4 4 8 8 0 0]
[0 0 0 0 0 0 0 0] [0 0 0 0 0 0 0 0]
[0 0 0 0 0 0 0 0] [0 0 0 0 0 0 0 0]

[0 0 0 0 0 0 0 0] [0 0 0 0 0 0 0 0]
[0 0 0 0 0 0 0 0] [0 0 0 0 0 0 0 0]
[0 0 0 0 0 0 0 0] [0 0 0 0 0 0 0 0]
[0 0 0 0 0 0 0 0] [0 0 0 0 0 0 0 0]
[0 0 0 0 0 0 0 0] [0 0 0 0 0 0 0 0]
[0 0 0 0 0 0 0 0] [0 0 0 0 0 0 0 0]
[0 0 0 0 0 0 0 0] [0 0 0 0 0 0 0 0]
[0 0 0 0 0 0 0 0] [0 0 0 0 0 0 0 0]

[0 0 0 0 0 0 0 0] [0 0 0 0 0 0 0 0]
[0 0 0 0 0 0 0 0] [0 0 0 0 0 0 0 0]
[0 0 0 0 0 0 0 0] [0 0 0 0 0 0 0 0]
[0 0 0 0 0 0 0 0] [0 0 0 0 0 0 0 0]
[0 0 0 0 0 0 0 0] [0 0 0 0 0 0 0 0]
[0 0 0 0 0 0 0 0] [0 0 0 0 0 0 0 0]
[0 0 0 0 0 0 0 0] [0 0 0 0 0 0 0 0]
[0 0 0 0 0 0 0 0] [0 0 0 0 0 0 0 0]

```

---

<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: [November 4, 2021, 6:55pm UTC](https://discourse.itk.org/t/resampling-difference-between-simpleitk-and-scipys-zoom/4548/2 "2021-11-04T18:55:13Z")

</div>

Hello @couzulli,

The voxel/pixel location in ITK/SimpleITK is not at the corner of the grid, it is the center of the element. I suspect this is the reason for the discrepancy you are experiencing. Please see the [SimpleITK Fundamental Concepts](https://simpleitk.readthedocs.io/en/master/fundamentalConcepts.html) page for details.

Also, note that the original image and the resampled image in the code do not occupy the same physical region. The resampled image extends 0.5mm out beyond the bounds of the original. For the resampled image to occupy the same physical region as the original and have a spacing of 0.5, its size would be 7 voxels.

---

<div class="post-metadata">

### Author: ![couzulli](https://discourse.itk.org/letter_avatar_proxy/v4/letter/c/ba8739/32.png) [@couzulli](https://discourse.itk.org/u/couzulli)
#### Post date: [November 4, 2021, 7:16pm UTC](https://discourse.itk.org/t/resampling-difference-between-simpleitk-and-scipys-zoom/4548/3 "2021-11-04T19:16:20Z")

</div>

@zivy Thank you for the clarification!

Per your comment and the information from the link which states that “_image’s physical extent starts half a voxel before the origin_”, I updated `origin` argument in the above code to `[-.5, -.5, -.5]` and the results match now.
