Dicom to Nifti format using mimics scripting. Problem with affine transformation matrix

I am trying to export the masks in mimics to nifti format, via the scripting module. However, I have a question regarding affine transformations as I am getting something wrong in the process. I think it is a really silly mistake but for some reason I cannot figure it out. I am using this page as a source of information: Neuroimaging in Python — NiBabel 3.2.1+100.g9fdf5e3e documentation

From what I understand, the tag 0020, 0037 provides the orientation of the rows and column of the slice of the MRI (in this case) image to transform the image into the patient (dicom) coordinate system. In my images, I get the following info from this tag:

1 0 0 \ 0 -1 0

From my readings, I understand that the patient/world coordinate for Dicom standard is left +, posterior +, superior + [LPS+]. This means that the images coordinate system is left+, inferior+ and posterior+. Therefore, the transformation affine matrix is from Dicom to Patient (assuming pixel spacing and slice thickness of 1 to keep it simple) and switching/flipping rows and columns as mentioned in the web page referenced above:
A= [0 1 0
0 0 1
-1 0 0]

From what I have read, the Nifti format has a different patient coordinate system than the Dicom, where right is +, anterior is +, and superior is+. Therefore, i and j are inverted with respect to Dicom and the Dicom patient to Nifti patient transformation matrix is
B= [ 0 -1 0
0 0 1
-1 0 0]

To obtain the nifti patient orientation (world), I would do the following:

Nifti patient [x; y; z]= [A][B]Dicom image[x; y; z] where the resulting rotation matrix is:

affine= [ 0 -1 0
0 0 1
1 0 0]

I obtain the mask using the scripting commands:

mimics_mask = mimics.data.masks.find(name=muscle)
mask_value = mimics_mask.get_voxel_buffer()
mask_array = np.asarray(mask_value)
mask_array = mask_array.astype(np.float)

I then export to nifti using

mask_img = nib.nifti1.Nifti1Image(mask_array, affine)

However, the resulting images (showing here the mask of a deformed vertebral column) are oriented all wrong, when I view it in ITK-snap.
-the sagittal plane image (first column, top row of the image quadrant) is in the location for the axial image
-the coronal plane image (second column, top row) is in the location for the sagittal image and it needs to be rotated clockwise by 90 degrees
-the axial plane image (second column, bottom row) is in the locatin for the coronal image and it needs to be rotated 90 degrees

It’s clear that I am getting something wrong in the affine transformation matrices, since the orientations are wrong, but I am not sure what it is?

I also tried using dicom2nifti function by importing it in the scripting module. Then I used :
image = nib.load (path to image)
affine_nifti = image.affine

To get the affine matrix this way. Then I use the same code as above to export the mask in Nifti format. I get a different result (!), but just as wrong in ITK, where the affine transformation is:
[-1 0 0
0 0 -1
0 -1 0]

I also noticed that the row and columns were not switched as instructed in the web page referenced above for the DICOM to Nifti conversion.

I was hoping to get some help from you to get the correct orientation in the nifti output…

Thank you,

Erica

Hi Erica,

Unfortunately we don’t have much experience with the NiBabel package and required affine transformation ourselves so I’m afraid we might be very limited in how we can help as we want to avoid giving wrong information.

However, I can confirm that there is a difference between the DICOM tags and resulting Mimics project. The DICOM tags return “raw” dicom information (imported files stripped of pixel data) while Mimics projects contain a lot of transformations and calculations in order to create the coordinate system.

Because of this (and other reasons), it’s not advised to combine DICOM orientation tags (0020, 0037 and 0020,0032) obtained from get_dicom_tags with get_voxel_buffer/get_voxel_center/logical_dimensions API’s related to the Mimics project.

In order to get the image directions (in Mimics for your mask), I would advise using something like the following:

p0 = i.get_voxel_center([0, 0, 0])

b = i.get_voxel_buffer()

d = b.shape

x = i.get_voxel_center([d[0]-1, 0, 0])

y = i.get_voxel_center([0, d[1]-1, 0])

z = i.get_voxel_center([0, 0, d[2]-1])

Another route would be to use “mimics.file.export_dicom” and work from the dicom format rather than the image. Hope this helps!

Kind regards,

Marnic

Hi Marnic,

Thank you for this information. It is actually quite useful.

However, just to be clear, what does the “i” variable refer to in the commands above. Could you please indicate how it would be defined in this specific case?

Thank you,

Erica

Hi Erica,

As Mimics is able to work with 4D scans, you can import multiple images at the same time as being part of the same project. To make sure the code works well, you’ll have to define on which image you want to work. There are some tools in the help manual like “get_images()” or “mimics.data.images” to get this information. (the “i” stands for the Image in this example)

Kind regards,

Marnic