Python writing is not working correctly

Hi,

The write image function in both SimpleITK and ITK python wrapping is broken.

I am having a very weird issue when writing images whose information has changed:

>>> import SimpleITK as sitk
>>> base_image = sitk.ReadImage("C:/test/test_flair.nii.gz")
>>> test_image = sitk.ReadImage("C:/test/test_001.nii.gz")
>>> test_image.CopyInformation(base_image)
>>> sitk.WriteImage(test_image, "C:/test/test_new.nii.gz")
>>> test_image_new = sitk.ReadImage("C:/test/test_new.nii.gz")
>>> test_image_new.GetOrigin()
(0.0, 0.0, 0.0)
>>> test_image.GetOrigin()
(-0.0, -239.0, 0.0)

As you can see, the information is no longer preserved. I am running on Windows with SimpleITK version 1.2.4 and 2.0.2. Any help towards this would be very helpful, thank you. I am also able to replicate this in ITK version 5.0.2 using Python wrapping. This is replicable across Windows and Linux.

Here are the files:
test_001.nii.gz (69.6 KB) test_flair.nii.gz (2.2 MB) test_new.nii.gz (28 KB)

Cross-post from https://github.com/SimpleITK/SimpleITK/issues/1323

Cheers,
Sarthak

Hello,

The Nifti file format has a lot of complicated and redundant meta-data information. You can use the Meta-Data Dictionary and Print to inspect all the fields of the input images. There are likely inconsistencies caused by your approach of bulk copying all the meta data.

If you are not able to inspect the Nifti meta data, and determine what specific meta-data fields need to changed for your purpose, perhaps a simpler file format such and MetaIO or Nrrd can be used.

1 Like

Hello @sarthakpati,

Based on the following MWE I suspect there is a bug in the underlying ITK implementation (copying the metadata dictionary will resolve your issue, but isn’t what is expected). When it isn’t copied the srow_x, srow_y, srow_z values in the written nifti are all zeros:

import SimpleITK as sitk

base_image = sitk.ReadImage("test_flair.nii.gz")
test_image = sitk.ReadImage("test_001.nii.gz")
test_image.CopyInformation(base_image)
sitk.WriteImage(test_image, "test_new.nii.gz")
test_image_new = sitk.ReadImage("test_new.nii.gz")
print('Expected path:')
print(test_image.GetOrigin())
print(test_image_new.GetOrigin())

base_image = sitk.ReadImage("test_flair.nii.gz")
test_image = sitk.ReadImage("test_001.nii.gz")
test_image.CopyInformation(base_image)
for k in base_image.GetMetaDataKeys():
    test_image.SetMetaData(k, base_image.GetMetaData(k))
sitk.WriteImage(test_image, "test_new.nii.gz")
test_image_new = sitk.ReadImage("test_new.nii.gz")
print('Unexpected path:')
print(test_image.GetOrigin())
print(test_image_new.GetOrigin())

@blowekamp, @hjmjohnson, @dzenanz, any idea what is going on (I’m “at” a conference so didn’t have too much time to dig into this).

Update from GitHub:

This issue is not present in itk 5.2rc2

I’m not sure which commit in ITK fixed the issue. Can you check the SimpleITK “latest” binary which is build against ITK from Jan 28th to see if it contains this issue. I am working on a pack to update SimpleITK super build the rc2.

Just checked with the latest SimpleITK, that version resolved the issue.

Best usage of my time while listening to an awards ceremony :wink: .

2 Likes