Input Orientation and Axis Indexing in PyRadiomics (SimpleITK vs NumPy)

Is there a specific orientation (axis order) expected by Pyradiomics when processing input images? I’m asking in the context of the opposite axes indexing between numpy/nibabel and SimpleITK :

SimpleITK and numpy indexing access is in opposite order!

SimpleITK: image[x,y,z]
numpy: image_numpy_array[z,y,x]

Since Pyradiomics uses SimpleITK internally, should the input axis order be interpreted as x, y, z?

If so, does this imply the following mapping for the force2Ddimension?

  • 0 == x == axial
  • 1 == y == coronal
  • 2 == z == sagittal
force2Ddimension details
force2Ddimension: 0  # axial slices, for coronal slices, use dimension 1 and for sagittal, dimension 2

Does Pyradiomics automatically reorder axes internally to match SimpleITK’s conventions (x, y, z), or is it the user’s responsibility to ensure the input image has the correct orientation?

I don’t recall exactly what pyradiomics does, but I believe it resamples the segmentation to match the geometry of the source image (or maybe the other way around).

Keep in mind that medical images can be acquired in many different orientations, so you should not make assumptions about the relationship between world space and index space. In Slicer that information is in the ijkToRAS matrix and related ones. See this info: https://slicer.readthedocs.io/en/latest/user_guide/coordinate_systems.html

You’are right! This is exactly why I want to reorient all my images to the same orientation before calling pyradiomics. Please note that I’m calling pyradiomics from the CLI, not via Slicer.

I should have mentioned in my first comment what I meant by axial, coronal, and sagittal, so clarifying it now:

  • 0 == x == axial == Superior-Inferior
  • 1 == y == coronal == Anterior-Posterior
  • 2 == z == sagittal == Right-Left

(source for numbers 0, 1, 2 and planes axial, coronal, saggital; source for x, y, z)

Which effectively translates into SAR (Superior-Anterior-Right) orientation, right?

This is however contradicted by this source:

ITK uses the LPS convention.

Just to restate what I said earlier, the 0, 1, 2 and x, y, z in image space that you are referring to do not correspond to any particular world space direction or slicing plane. That mapping is defined by an affine matrix.

You’ll need to study the pyradiomics code, but as I recall it takes care of the resampling for you.

But if you want to make sure all your test data is anatomically aligned, you need to be sure to understand and apply the transformations I’ve described.

1 Like

Thank you!

Just to confirm I understand it correctly, let me illustrate what I mean by an example:

  • I have two types of 3D MRI images: T2w axial images and T2w sagittal images.
  • T2w axial images have a high in-plane resolution in the axial plane and thick slices in the superior-inferior (S-I) axis.
  • T2w sagittal images have a high in-plane resolution in the sagittal plane and thick slices in the right-left (R-L) axis.
  • I reoriented both images to the RAS coordinate system

When inspecting the reoriented images using SimpleITK, I get the following:

>>> import SimpleITK as sitk
>>> image_ax = sitk.ReadImage('sub-001_acq-ax_T2w_RAS.nii.gz')
>>> image_ax.GetSpacing()
(0.5624999403953552, 0.5625000596046448, 3.7499988079071045)


>>> import SimpleITK as sitk
>>> image_sag = sitk.ReadImage('sub-001_acq-sag_T2w_RAS.nii.gz')
>>> image_sag.GetSpacing()
(3.4499998092651367, 0.48828125, 0.4882812798023224)
  • the axial image (sub-001_acq-ax_T2w_RAS.nii.gz) has correctly the highest spacing (i.e., thick slices) in the last dimension (S-I)
  • the sagittal image (sub-001_acq-sag_T2w_RAS.nii.gz) has correctly the highest spacing in the first dimension (R-L)

Then it matches the pyradiomics example, which states:

force2Ddimension: 0 # axial slices, for coronal slices, use dimension 1 and for sagittal, dimension 2.