I’m working on adding support for orientation in VTK image data and what depends on it (filters, mappers, IO… more details here).
I was working on the MetaIO (.mha, .mhd) reader and tested using a sample dataset with the following header:
ObjectType = Image
NDims = 3
BinaryData = True
BinaryDataByteOrderMSB = False
CompressedData = True
CompressedDataSize = 1486837
TransformMatrix = 1 7.5286998857393448e-16 4.3888503942213362e-16 7.4766581814600425e-16 -1 -3.8487811825327185e-47 0 0 -1
Offset = -9.360019529721862e-29 360.00000000000006 332.5
CenterOfRotation = 0 0 0
AnatomicalOrientation = RPS
ElementSpacing = 1.4062499999999947 1.4062500000000002 2.4999999999999813
DimSize = 256 256 133
ElementType = MET_UCHAR
ElementDataFile = LOCAL
Note that the anatomical orientation for this file is RPS
, spacing is ~ [1.4, 1.4, 2.5] and the orientation matrix is, after rounding:
1 0 0
0 -1 0
0 0 -1
In VTK the system is XYZ=LPS, so after flipping the first axis, the orientation matrix becomes, in LPS:
-1 0 0
0 -1 0
0 0 -1
Now… I use 3DSlicer as the ground truth in term of orientation when I test things for VTK, and the data read in my VTK example with the MHA reader was flipped along the Sagittal axis (L/R) compared to 3D Slicer…
I then proceed to export the dataset to NRRD from Slicer, and this is the resulting header:
NRRD0004
# Complete NRRD file format specification at:
# http://teem.sourceforge.net/nrrd/format.html
type: unsigned char
dimension: 3
space: left-posterior-superior
sizes: 256 256 133
space directions: (1.4062499999999947,1.0587234214320913e-15,6.171820866873731e-16) (1.0514050567678187e-15,-1.4062500000000002,-5.4123485379366359e-47) (0,0,-2.4999999999999813)
kinds: domain domain domain
encoding: gzip
space origin: (-9.360019529721862e-29,360.00000000000006,332.5)
With rounding, the direction matrix here is:
1.4 0 0
0 -1.4 0
0 0 -2.5
If we extract the spacing (1.4, 1.4, 2.5) we get:
1 0 0
0 -1 0
0 0 -1
That’s the same as in the MHA header… however, the space
is now left-posterior-superior
instead of RPS
in MHA: here we find the flip along the X-axis again.
So two possible reasons:
- MHA reader is incorrect
- NRRD writer is incorrect
Given that my VTK implementation gives me a flip from the one loaded by Slicer, my guess is on number 1. I followed up by looking at itkMetaImageIO and there are numerous mentions of AnatomicalOrientation
in MetaImageIO::Write
, but none in MetaImageIO::Read
.
Based on all this, would you all agree we are indeed ignoring the anatomical orientation when reading MHA/MHD files?