InsightSoftwareConsortium / InsightSoftwareConsortium/ITK
Left-handed orientation is discarded when saving a .dcm file
- Dominant language
- C++
- Stars
- 1.7k
- Forks
- 748
- Avg merge
- 1d 1h
- Merged PRs (30d)
- 64
Description
### Description
Out of 48 possible orientations for a 3d image, the 24 left-handed orientations are treated incorrectly when saving a multi-frame dicom file or series.
- Examples for right-handed orientations (24 in total):
- RAI
- SAR
- Left-handed (24 in total):
- RAS
- RPI
### Steps to Reproduce
1. Download nih nifti example: [avg152T1_LR_nifti.nii.gz](https://nifti.nimh.nih.gov/nifti-1/data/avg152T1_LR_nifti.nii.gz)
(From: https://nifti.nimh.nih.gov/nifti-1/data)
This nifti's orientation is RPI - left-handed.
2. Run the following code in python:
```python
import itk
nifti_image = itk.imread('avg152T1_LR_nifti.nii.gz')
nifti_direction = itk.array_from_vnl_matrix(
nifti_image.GetDirection().GetVnlMatrix().as_matrix())
# save as a dicom
itk.imwrite(nifti_image, 'avg152T1_LR_nifti.dcm')
# read the saved dicom
dicom_image = itk.imread('avg152T1_LR_nifti.dcm')
dicom_direction = itk.array_from_vnl_matrix(
dicom_image.GetDirection().GetVnlMatrix().as_matrix())
print(nifti_direction)
# [[ 1. 0. 0.]
# [ 0. -1. 0.]
# [ 0. 0. 1.]]
print(dicom_direction)
# [[ 1. 0. 0.]
# [ 0. -1. 0.]
# [ 0. 0. -1.]]
```
3. Open in itk-snap/slicer the original nifti and then the dicom. The dicom is flipped up-down.
### Expected behavior
1. The direction matrix should be the same
2. The saved dicom image should not be flipped up-down
Actually, 1 leads to 2.
I should emphasize that this is not a bug of slicer nor itk-snap. The bug is in our dicom writer.
### Actual behavior
1. The direction matrices are different. The original direction matrix of the nifti (RPI):
```none
[[ 1. 0. 0.]
[ 0. -1. 0.]
[ 0. 0. 1.]]
```
The dicom's direction matrix (corresponding to RPS):
```none
[[ 1. 0. 0.]
[ 0. -1. 0.]
[ 0. 0. -1.]]
```
2. In itk-snap, the original nifti is:

The saved dicom is flipped in S-I axis:

### Reproducibility
100% for saving an image with left-handed orientation in multi-frame dicom, both single file (as shown here) and a series of 2d slices.
In general, it's relevant for 3d images with left-handed orientations (50% of all possible orientations).
### Versions
Itk 5.2.0
### Environment
Python 3.9.4, macOS Big Sur (probably irrelevant)
### Additional Information
The issue and some possible solutions have already been discussed here:
https://discourse.itk.org/t/nifti-rpi-orientation-file-exported-to-dicom-wrong-orientation/1612
### Explanation of the bug
The dicom orientation is encoded in the 6 numbers of [*Image Orientation (Patient)*](http://dicom.nema.org/medical/dicom/current/output/chtml/part03/sect_C.7.6.2.html) tag.
These 6 numbers correspond to the first and second column of the direction matrix. Let's call these columns u, v (vectors of length 3).
When saving the dicom, the 3rd column of `nifti_direction` - n, is discarded. When reading the dicom, it is inferred as the cross product of u and v:
* n = u x v
However, in this way it can never be (-n)!
### Possible fixes
1. Raise an error when saving a dicom with a left-handed orientation.
The orientation is easy to check: the determinant of the direction matrix (a rotation matrix) is either +1 or (-1).
+1 - right-handed orientation, go ahead
(-1) - error.
2. As Mihail Isakov [suggested](https://discourse.itk.org/t/nifti-rpi-orientation-file-exported-to-dicom-wrong-orientation/1612/2), if the image is left-handed - reorient it to the nearest right handed orientation.
3. Encode the orientation direction in the sign of [*Spacing Between Slices*](http://dicom.nema.org/medical/dicom/current/output/chtml/part03/sect_C.8.4.15.html) tag
Contributor guide
Assessment
This issue has not been assessed yet.