Skip to content

Commit 691fd0b

Browse files
committed
fix: orientation bug in ITK's displacements fields (also h5)
1 parent bad8bec commit 691fd0b

File tree

1 file changed

+11
-20
lines changed

1 file changed

+11
-20
lines changed

nitransforms/io/itk.py

Lines changed: 11 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
"""Read/write ITK transforms."""
2+
23
import warnings
34
import numpy as np
45
from scipy.io import loadmat as _read_mat, savemat as _save_mat
@@ -138,8 +139,7 @@ def from_matlab_dict(cls, mdict, index=0):
138139
sa = tf.structarr
139140

140141
affine = mdict.get(
141-
"AffineTransform_double_3_3",
142-
mdict.get("AffineTransform_float_3_3")
142+
"AffineTransform_double_3_3", mdict.get("AffineTransform_float_3_3")
143143
)
144144

145145
if affine is None:
@@ -337,7 +337,7 @@ def from_image(cls, imgobj):
337337
hdr = imgobj.header.copy()
338338
shape = hdr.get_data_shape()
339339

340-
if len(shape) != 5 or shape[-2] != 1 or not shape[-1] in (2, 3):
340+
if len(shape) != 5 or shape[-2] != 1 or shape[-1] not in (2, 3):
341341
raise TransformFileError(
342342
'Displacements field "%s" does not come from ITK.'
343343
% imgobj.file_map["image"].filename
@@ -348,9 +348,7 @@ def from_image(cls, imgobj):
348348
hdr.set_intent("vector")
349349

350350
field = np.squeeze(np.asanyarray(imgobj.dataobj))
351-
field[..., (0, 1)] *= -1.0
352-
353-
return imgobj.__class__(field, imgobj.affine, hdr)
351+
return imgobj.__class__(field, LPS @ imgobj.affine, hdr)
354352

355353
@classmethod
356354
def to_image(cls, imgobj):
@@ -360,9 +358,7 @@ def to_image(cls, imgobj):
360358
hdr.set_intent("vector")
361359

362360
warp_data = imgobj.get_fdata().reshape(imgobj.shape[:3] + (1, imgobj.shape[-1]))
363-
warp_data[..., (0, 1)] *= -1
364-
365-
return imgobj.__class__(warp_data, imgobj.affine, hdr)
361+
return imgobj.__class__(warp_data, LPS @ imgobj.affine, hdr)
366362

367363

368364
class ITKCompositeH5:
@@ -410,21 +406,16 @@ def from_h5obj(cls, fileobj, check=True, only_linear=False):
410406
directions = np.reshape(_fixed[9:], (3, 3))
411407
affine = from_matvec(directions * zooms, offset)
412408
# ITK uses Fortran ordering, like NIfTI, but with the vector dimension first
413-
field = np.moveaxis(
414-
np.reshape(
415-
xfm[f"{typo_fallback}Parameters"], (3, *shape.astype(int)), order='F'
416-
),
417-
0,
418-
-1,
419-
)
420-
field[..., (0, 1)] *= -1.0
409+
# In practice, this seems to work (see issue #171)
410+
field = np.reshape(
411+
xfm[f"{typo_fallback}Parameters"], (*shape.astype(int), 3)
412+
).transpose(2, 1, 0, 3)
413+
421414
hdr = Nifti1Header()
422415
hdr.set_intent("vector")
423416
hdr.set_data_dtype("float")
424417

425-
xfm_list.append(
426-
Nifti1Image(field.astype("float"), LPS @ affine, hdr)
427-
)
418+
xfm_list.append(Nifti1Image(field.astype("float"), affine, hdr))
428419
continue
429420

430421
raise TransformIOError(

0 commit comments

Comments
 (0)