I encountered an issue while trying to align NIfTI files (segmentation results from TotalSegmentator) with the original DICOM files in Jupyter Notebook. Despite my efforts to construct an appropriate affine matrix for the DICOM data, the axes do not align as expected.
Here’s the workflow I followed:
I sorted the DICOM files based on InstanceNumber:
dicom_files = sorted(
[os.path.join(dcm_folder, f) for f in os.listdir(dcm_folder) if f.endswith('.dcm')],
key=lambda x: pydicom.dcmread(x).InstanceNumber
)
Using the DICOM metadata, I constructed an affine matrix:
ds1 = pydicom.dcmread(dicom_files[0])
ds2 = pydicom.dcmread(dicom_files[1])
a = np.array(ds1.ImageOrientationPatient[:3])
b = np.array(ds1.ImageOrientationPatient[3:])
slice_diff = (np.array(ds1.ImagePositionPatient) - np.array(ds2.ImagePositionPatient)) / (
ds1.InstanceNumber - ds2.InstanceNumber
)
c = slice_diff / np.sum(slice_diff**2) ** 0.5
matrix = np.zeros((4, 4))
matrix[3, 3] = 1
matrix[:3, 0] = b
matrix[:3, 1] = a
matrix[:3, 2] = c
affine_matrix = matrix
I computed the transformation between the NIfTI and DICOM orientations using nib.orientations.ornt_transform
transform_ornt = nib.orientations.ornt_transform(start_ornt, end_ornt)
I applied the computed transformation to the NIfTI data:
reoriented_nifti = nib.orientations.apply_orientation(nii_data, transform_ornt)
Despite these steps, the alignment of the NIfTI and DICOM files is still incorrect. It seems like the axes are not properly aligned.
What I tried:
- I tested several cases with different orientations and found that axes could flip in all three directions under certain conditions.
- When viewing the files in 3D Slicer or ITK-Snap, the alignment looks almost correct but has slight offsets.
- I inspected the NIfTI transformation matrix in ITK-Snap (via Image Layer
Inspector -> Info -> Reorient -> Voxel to World Matrix
) and found that the NIfTI affine matrix appears correct. - However, in the DICOM files, certain axes sometimes seem flipped.
- I also tried simpleITK
SetDirection
for aligning, but it seems not work.
My Questions:
- Is there an issue with how I constructed the affine matrix for the DICOM files?
- Should I handle the orientation of the DICOM files differently due to their non-fixed orientations?
- Why does the NIfTI file display correctly in 3D Slicer/ITK-Snap but not when visualized in my Jupyter Notebook workflow?
- Are there any known pitfalls in using nib.orientations.ornt_transform or apply_orientation that I might have overlooked?
- What is the best way to ensure that the NIfTI and DICOM files align perfectly, considering the frequent axis flips in the DICOM files?
Any insights, suggestions, or alternative workflows to address this alignment issue would be greatly appreciated. Thank you!