This gist was created to investigate and verify the patient orientation & position of nifti files created using libraries: dcm2niix
and simpleitk
(ITK) from the same DICOM files. Code is executed within a Docker container to ensure reproducibility. Additionally, 3dinfo
from afni
was executed to see how afni handles these nifti files, specifically the physical extents of the loaded 3d volume.
- run below to build the container, download images from tcia, generate nifti files (with
dcm2niix
,simpleitk
), print affine matrix from nifti files (nibabel
) and print nifti info withafni 3dinfo
.
bash run.sh
- sample print out from
run.sh
using a series pulled from TCIA with oblique axial slices. Differences are observed between the affine transforms from the 2 nifti files, physical extent printout from afni's 3dinfo are also different.
first image (instance 1):
(0020,0013) IS [1] # 2, 1 InstanceNumber
(0020,0037) DS [1\0\0\0\0.99452189536827\-0.1045284632677] # 42, 6 ImageOrientationPatient
(0020,0032) DS [-108.2880859375\-282.97187247236\115.51118721324] # 48, 3 ImagePositionPatient
last image (instance 72):
(0020,0013) IS [72] # 2, 1 InstanceNumber
(0020,0037) DS [1\0\0\0\0.99452189536827\-0.1045284632677] # 42, 6 ImageOrientationPatient
(0020,0032) DS [-108.2880859375\-282.97187247236\281.57518721324] # 48, 3 ImagePositionPatient
affine matrix of nifti file generate by sitk:
[[-0.424 -0.000 -0.000 108.288]
[ 0.000 -0.422 -0.244 282.972]
[ 0.000 -0.044 2.326 115.511]
[ 0.000 0.000 0.000 1.000]]
shape: (512, 512, 72)
physical coordinates | image coordinates:
[ 108.288 282.972 115.511 1.000] | [0, 0, 0, 1]
[ 108.193 67.582 92.873 1.000] | [0, 511, 0, 1]
[-108.288 283.067 115.516 1.000] | [511, 0, 0, 1]
[-108.384 67.678 92.878 1.000] | [511, 511, 0, 1]
[ 108.284 265.613 280.665 1.000] | [0, 0, 71, 1]
[ 108.189 50.224 258.027 1.000] | [0, 511, 71, 1]
[-108.292 265.709 280.670 1.000] | [511, 0, 71, 1]
[-108.387 50.319 258.032 1.000] | [511, 511, 71, 1]
Dataset File: /workdir/itk.nii.gz
Identifier Code: NII_GT2VqUf8zzMwesHiW2tNSg Creation Date: Mon Apr 26 23:02:40 2021
Template Space: ORIG
Dataset Type: Anat Bucket (-abuc)
Byte Order: LSB_FIRST {assumed} [this CPU native = LSB_FIRST]
Storage Mode: NIFTI
Storage Space: 37,748,736 (38 million) bytes
Geometry String: "MATRIX(0.423828,0,0,-108.2881,0,0.421506,0.244485,-282.9719,0,-0.044302,2.326117,115.5112):512,512,72"
Data Axes Tilt: Oblique (6.000 deg. from plumb)
Data Axes Approximate Orientation:
first (x) = Right-to-Left
second (y) = Anterior-to-Posterior
third (z) = Inferior-to-Superior [-orient RAI]
R-to-L extent: -108.288 [R] -to- 108.288 [L] -step- 0.424 mm [512 voxels]
A-to-P extent: -282.972 [A] -to- -66.396 [A] -step- 0.424 mm [512 voxels]
I-to-S extent: 115.511 [S] -to- 281.575 [S] -step- 2.339 mm [ 72 voxels]
Number of values stored at each pixel = 1
-- At sub-brick #0 '?' datum type is short
--
affine matrix of nifti file generate by dcm2niix:
[[-0.424 0.000 0.000 108.288]
[ 0.000 0.426 -0.000 67.582]
[ 0.000 0.044 2.387 92.873]
[ 0.000 0.000 0.000 1.000]]
shape: (512, 512, 72)
physical coordinates | image coordinates:
[ 108.288 67.582 92.873 1.000] | [0, 0, 0, 1]
[ 108.288 285.351 115.511 1.000] | [0, 511, 0, 1]
[-108.288 67.582 92.873 1.000] | [511, 0, 0, 1]
[-108.288 285.351 115.511 1.000] | [511, 511, 0, 1]
[ 108.288 67.582 262.324 1.000] | [0, 0, 71, 1]
[ 108.288 285.351 284.962 1.000] | [0, 511, 71, 1]
[-108.288 67.582 262.324 1.000] | [511, 0, 71, 1]
[-108.288 285.351 284.962 1.000] | [511, 511, 71, 1]
Dataset File: /workdir/ok/ok.nii
Identifier Code: NII__o7Symja8fyulzCu9ZQtag Creation Date: Mon Apr 26 23:02:40 2021
Template Space: ORIG
Dataset Type: Anat Bucket (-abuc)
Byte Order: LSB_FIRST {assumed} [this CPU native = LSB_FIRST]
Storage Mode: NIFTI
Storage Space: 75,497,472 (75 million) bytes
Geometry String: "MATRIX(0.423828,0,0,-108.2881,0,-0.426163,4.768372e-07,-67.58212,0,0.044302,2.386637,92.87281):512,512,72"
Data Axes Tilt: Oblique (5.935 deg. from plumb)
Data Axes Approximate Orientation:
first (x) = Right-to-Left
second (y) = Posterior-to-Anterior
third (z) = Inferior-to-Superior [-orient RPI]
R-to-L extent: -108.288 [R] -to- 108.288 [L] -step- 0.424 mm [512 voxels]
A-to-P extent: -286.525 [A] -to- -67.582 [A] -step- 0.428 mm [512 voxels]
I-to-S extent: 92.873 [S] -to- 262.324 [S] -step- 2.387 mm [ 72 voxels]
Number of values stored at each pixel = 1
-- At sub-brick #0 '?' datum type is float