# vtkImageFourierCenter behaves differently from np.fft.fftshift ?

**URL:** https://discourse.vtk.org/t/vtkimagefouriercenter-behaves-differently-from-np-fft-fftshift/13957
**Category:** Support
**Created:** [May 29, 2024, 4:28pm UTC](https://discourse.vtk.org/t/vtkimagefouriercenter-behaves-differently-from-np-fft-fftshift/13957 "2024-05-29T16:28:04Z")
**Posts on this page:** 2
**Page:** 1

<div class="post-metadata">

### Author: ![martin.genet](https://discourse.vtk.org/user_avatar/discourse.vtk.org/martin.genet/32/635_2.png) [@martin.genet](https://discourse.vtk.org/u/martin.genet)
#### Post date: [May 29, 2024, 4:28pm UTC](https://discourse.vtk.org/t/vtkimagefouriercenter-behaves-differently-from-np-fft-fftshift/13957/1 "2024-05-29T16:28:04Z")

</div>

Dear all:  
I am confused with vtkImageFourierCenter, which seems to behave quite differently from numpy’s fftshift. Consider the following simple example:

```auto
import numpy as np
import vtk
import vtk.numpy_interface.dataset_adapter as dsa

# Creating a simple vtk image (2 components, each component is 0,1,2,3, etc)
N = 4
vtk_image = vtk.vtkImageData()
vtk_image.SetDimensions([N, N, 1])
vtk_image.AllocateScalars(vtk.VTK_DOUBLE, 2)
n_tuples = vtk_image.GetPointData().GetScalars().GetNumberOfTuples()
for k_tuple in range(n_tuples):
    vtk_image.GetPointData().GetScalars().SetTuple2(k_tuple, k_tuple, k_tuple)

np_image = np.array(dsa.WrapDataObject(vtk_image).PointData["ImageScalars"][:,0] + 1j * dsa.WrapDataObject(vtk_image).PointData["ImageScalars"][:,1]).reshape((N,N))
np_image
# array([[0. +0.j, 1. +1.j, 2. +2.j, 3. +3.j],
# [4. +4.j, 5. +5.j, 6. +6.j, 7. +7.j],
# [8. +8.j, 9. +9.j, 10.+10.j, 11.+11.j],
# [12.+12.j, 13.+13.j, 14.+14.j, 15.+15.j]])

# Shifting the image using numpy
np_image_shift = np.fft.fftshift(np_image)
np_image_shift
# array([[10.+10.j, 11.+11.j, 8. +8.j, 9. +9.j],
# [14.+14.j, 15.+15.j, 12.+12.j, 13.+13.j],
# [2. +2.j, 3. +3.j, 0. +0.j, 1. +1.j],
# [6. +6.j, 7. +7.j, 4. +4.j, 5. +5.j]])

# Shifting the image using vtk
vtkImageFourierCenter = vtk.vtkImageFourierCenter()
vtkImageFourierCenter.SetInputData(vtk_image)
vtkImageFourierCenter.Update()
vtk_image_shift = vtkImageFourierCenter.GetOutput()

np.array(dsa.WrapDataObject(vtk_image_shift).PointData["ImageScalars"][:,0] + 1j * dsa.WrapDataObject(vtk_image_shift).PointData["ImageScalars"][:,1]).reshape((N,N))
#array([[5. +5.j, 6. +6.j, 7. +7.j, 4. +4.j],
# [9. +9.j, 10.+10.j, 11.+11.j, 8. +8.j],
# [13.+13.j, 14.+14.j, 15.+15.j, 12.+12.j],
# [1. +1.j, 2. +2.j, 3. +3.j, 0. +0.j]])

```

Any insight on this would be super useful…thanks in advance!

---

<div class="post-metadata">

### Author: ![dgobbi](https://discourse.vtk.org/user_avatar/discourse.vtk.org/dgobbi/32/18_2.png) [@dgobbi](https://discourse.vtk.org/u/dgobbi)
#### Post date: [May 29, 2024, 10:06pm UTC](https://discourse.vtk.org/t/vtkimagefouriercenter-behaves-differently-from-np-fft-fftshift/13957/2 "2024-05-29T22:06:24Z")

</div>

Looks like an off-by-one error in vtkImageFourierCenter. Specifically this line in vtkImageFourierCenter.cxx where it computes the shift:

```c++
    mid0 = (wholeMin0 + wholeMax0) / 2;

```

In the case of a 4x4 image, `wholeMin0` is 0 and `wholeMax0` is 3 (i.e. the smallest and largest pixel index). So vtkImageFourierCenter computes the shift to be (0 + 3)/2 = 1. But the shift should be 2, not 1.

Likewise, VTK’s [Spectrum.py](https://gitlab.kitware.com/vtk/vtk/-/blob/master/Imaging/Core/Testing/Python/Spectrum.py) test, which is supposed to test vtkImageFourierCenter, has an incorrect test image. The test image has the center of the spectrum at pixel index (129,129) instead of at the correct location (128,128):

![Spectrum](https://discourse.vtk.org/uploads/default/original/2X/a/aa4d25b31fba5b37838a8cd3ee7c37d2c0d24a59.png)

This bug has existed in VTK from the very beginning. Strange that it wasn’t caught before.
