External Email - Use Caution
Thank you so much, Douglas! Turned out that negating the second column of the affine matrix was the right thing to do :) My code was not working for another reason (the code wasn't reading the nifti header correctly). You're right: the affine matrix is the multiplication of scaling, rotation, shear, and translation matrices. So if the original affine matrix is M, the scaling matrix is S, and the corrected affine matrix is Mc: Mc = M @ S If we define S matrix as: S = np.array([[1, 0, 0, 0], [0, -1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]]) The result on Mc will be negating the second column, which we can directly do by: Mc = MMc[:, 1] = - M[:, 1] instead of multiplying M and S. Thank you for your input, I appreciate it :) Arman Avesta
the easiest way to think about it is in terms of matrices. You have an affine matrix M already that converts from col,row,slice to xyz. When you flip the 2nd dim, it is like you are applying a matrix R to the new col,row,slice to get the old col,row,slice, so your new affine matrix will be M*R. R will be something like1 0 0 0 0 -1 0 Nrows 0 0 1 0 0 0 1 On 9/15/2022 4:39 PM, Arman Avesta wrote:
External Email - Use Caution
Hi gang,
I hope you're enjoying the last stretch of summer!
I am writing a python code that reads NIfTI images, changes their coordinate system into LAS (*MailScanner has detected a possible fraud attempt from "secure-web.cisco.com" claiming to be* http://secure-web.cisco.com/1BgqieiGDbxuT4tCHyJZWr1ABBl6JirOFjUmCoUV-_5mJyih...http://secure-web.cisco.com/1_56Y7I55cGEKACYrc6S3VTmRRwExp_9ZrFfAHl414WhHLPeDdTjXbHeoVx3rsKJSxijXBZ4PlHc8hScAYAxMmq38vQ7zf1r_2qA0Xk4nDyi4f1sv6LDudunSfrBTCIEm4dR6-Yi4zJAwYNNSCtCo_s2cdn3in_HBnRzsMhxxe5UVXbrExWQpN1xVnAAwnOCFMHA3FiPIPd_fY4qWQvsnFwmK5EATBmo9kqmBrT44kZL13Qy9unKKXsb_8ZKxZ0f-xS8jkh88S2GBOOCfJmJ9YqOxBVIAe0fY-I-uywrlbCkVK7vJvalzVZEUqOQ2UZEWMIfZgbrVNQPA2gZ3zHzGdw/http%3A%2F%2Fwww.grahamwideman.com%2Fgw%2Fbrain%2Forientation%2Forientterms.htm), and then saves the corrected NIfTI mage.The function that corrects the coordinate system is copied below. I am not sure if I am changing the *affine transform* (from the MRI space to the scanner space) correctly.For instance, to go from LPS to LAS, I should flip the image in 2nd dimension. The piece that I'm not sure about is if I should negate the 2nd column of the affine matrix or if the affine correction is more complicated:image = np.flip(image, 1) affine[:, 1] = - affine[:, 1] I would really really appreciate any help here! I'm stuck :D
Cheers, Arman
----------------------------------------------------------------- def correct_coordinates(image, affine, coords): """ This function re-orients the MRI volume into the standard radiology system, i.e. ('L','A','S'), and also corrects the affine transform for the volume (from the MRI volume space to the scanner space). Inputs: - image: MRI volume - affine: affine transform for the MRI volume (e.g. [[-5, 0, 0, 1] [0, -5.2, 7.8 1.6] [0, 6.9, 5.9, -7.7] [0, 0, 0, 1]] - coords: the coordinate system of the MRI volume (e.g. ('L', 'P', 'S') Outputs: - image: corrected MRI volume in the standard radiology coordinate system: ('L', 'A', 'S') - affine: corrected affine transform (from MRI volume space to the scanner space). """ if coords == ('L', 'A', 'S'): return image, affine
if coords == ('R', 'A', 'S'): image = np.flip(image, 0) affine[:, 0] = - affine[:, 0] return image, affine
if coords == ('L', 'P', 'S'): image = np.flip(image, 1) affine[:, 1] = - affine[:, 1] # print('func coords: ', coords) # print('func corr coords: ', nib.aff2axcodes(affine)) # print('function affine: \n', affine) return image, affine if coords == ('L', 'S', 'A'): image = np.swapaxes(image, 1, 2) affine[:, [1, 2]] = affine[:, [2, 1]] return image, affine
if coords == ('L', 'I', 'A'): # L,I,A --> L,A,I image = np.swapaxes(image, 1, 2) affine[:, [1, 2]] = affine[:, [2, 1]] # L,A,I --> L,A,S image = np.flip(image, 2) affine[:, 2] = - affine[:, 2] return image, affine if coords == ('L', 'P', 'S'): image = np.flip(image, 1) affine[:, 1] = - affine[:, 1] return image, affine
if coords == ('L', 'I', 'P'): # L,I,P --> L,I,A image = np.flip(image,2) affine[:, 2] = - affine[:, 2] # L,I,A --> L,A,I image = np.swapaxes(image, 1, 2) affine[:, [1, 2]] = affine[:, [2, 1]] # L,A,I --> L,A,S image = np.flip(image, 2) affine[:, 2] = - affine[:, 2] return image, affine
if coords == ('P', 'I', 'R'): # P,I,R --> A,I,R image = np.flip(image, 0) affine[:, 0] = - affine[:, 0] # A,I,R --> A,S,R image = np.flip(image, 1) affine[:, 1] = - affine[:, 1] # A,S,R --> A,S,L image = np.flip(image, 2) affine[:, 2] = - affine[:, 2] # A,S,L --> L,A,S image = np.moveaxis(image, [0, 1, 2], [1, 2, 0]) affine[:, [0, 1, 2]] = affine[:, [1, 2, 0]] return image, affine
raise Exception('coords not identified: please go to correct_coordinates function ' 'and define the coordinate system.')