simple itk is not behaving as expected while flip using affine transform

I want to flip a volume using simpleitk.

vol = np.arange(1, 25).reshape((4, 6))
print(vol)
vol = sitk.GetImageFromArray(vol)

Result:

[[ 1  2  3  4  5  6]
 [ 7  8  9 10 11 12]
 [13 14 15 16 17 18]
 [19 20 21 22 23 24]]

according to the this torurial there are two ways of doing it.

  1. using slicing
  2. using an affine transform.

However, the result of the second approach is not correct because of the transformation center.

flip = sitk.AffineTransform(2) 
flip.SetMatrix([1.0,0,0,-1.0]) volume_shape= np.array(vol.GetSize()) 
center = (int(volume_shape[0] / 2), int(volume_shape[1] / 2))
#if I change the center to (3,1.5) it works 
flip.SetCenter(center)
interp_img = sitk.sitkLinear 
vol_resampled = sitk.Resample(vol, flip, interp_img,0.0)

print(sitk.GetArrayFromImage(vol_resampled))
print(sitk.GetArrayFromImage(vol[:, ::-1]))

Result:

[[ 0  0  0  0  0  0]
 [19 20 21 22 23 24]
 [13 14 15 16 17 18]
 [ 7  8  9 10 11 12]]

[[19 20 21 22 23 24]
 [13 14 15 16 17 18]
 [ 7  8  9 10 11 12]
 [ 1  2  3  4  5  6]]

I would appreciate it if someone could explain the reason.


Solution 1:

The simple solution:

center = ((volume_shape[0] - 1) / 2, (volume_shape[1] - 1) / 2)

Here is the solution when spacing != 1.0:

spacing = vol.GetSpacing()
center = ((volume_shape[0] - 1) * spacing[0] / 2, (volume_shape[1] - 1) * spacing[1] / 2)

Reason: sitk.Resample only cares about the real pixel position. volume_shape = [6, 4] The pixels are located in [0, 1, 2, 3, 4, 5] for the first axis and [0, 1, 2, 3] for the second axis. You need to set the center as (2.5, 1.5) rather than (3, 2).