Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Incorrect orientation of exported meshes #11

Closed
thangngoc89 opened this issue May 9, 2024 · 6 comments
Closed

Incorrect orientation of exported meshes #11

thangngoc89 opened this issue May 9, 2024 · 6 comments

Comments

@thangngoc89
Copy link

thangngoc89 commented May 9, 2024

Hey, thank you for making and publishing nii2mesh. I'm a big fan of your works (using NiiVue for open visualization).
I've notice that the generated meshes from nii2mesh is in a different orientation comparing to the voxel orientation. I need to perform a 180 degrees rotation around the Z axis in local coordinates of the object* for correction.

I've tested and confirmed with different files having these original affine: RAS, LPS and LAI.

Example file:

  1. I created a rough segmentation using 3D Slicer for bet.nii.gz provided on nii2meshweb demo.
    You could download it here bet.seg.nii.gz
  2. Run nii2mesh:
nii2mesh bet.seg.nii.gz -a 1 bet_.ply

Output bet_1.ply.zip

  1. View with 3D Slicer:

Green is segmentaiton visualization, yellow is model:

image image

Happy to provide any more details that you need.

@neurolabusc
Copy link
Owner

This reflects the fact that DICOM uses LPS while NIfTI uses the RAS coordinate system. This tool (as well as Surfice and NiiVue) uses RAS Talairach_coordinates popular in neuroimaging (e.g. NIfTI, GIfTI, TRX, etc), whereas Slicer3D defaults to LPS.

To demonstrate the behavior, convert the AIL.nii.gz image, where the columns, rows and slices are saved to disk as posterior->anterior, superior->inferior, and right->left respectively (alternatively, try any of the 48 combinations) using nii2mesh. Drag and drop the resulting obj mesh onto the NiiVue worldspace demo and click the cube checkbox to show the spatial directions. Note that the orientation of the voxels is preserved in the image:

AIL

You can further investigate the polarity by leveraging the fact that the OBJ format is a text format, and you can edit the first line of the text file to change the spatial position of the first vertex, which is initially

v 72.2707 -36.1367 -0.389995

Doing so, you can see that NiiVue interprets the first component as ascending rightwards, the second component as ascending anteriorly, and the third component as ascending superiorly. Therefore, the mesh uses the same RAS coordinate system.

To resolve the issue, choose use the Show options button with Slicer3D and set the Coordinate system to RAS:

ras

@thangngoc89
Copy link
Author

Thank you for a very detailed explanation. As I understand it, nii2mesh exports meshes to RAS coordinate regardless of the input coordinate system. Is that correct? Given that the meshes don't carry coordinate or affine information, it would be up to downstream users to ensure the correct coordinate system.

@neurolabusc
Copy link
Owner

Yes. To clarify: nii2mesh reads NIfTI images which uses the RAS coordinate system. The NIfTI header orientation information is used to transform the voxels to vertices specified with RAS coordinates, regardless of the order that voxels are saved to disk.

@thangngoc89
Copy link
Author

nii2mesh reads NIfTI images which uses the RAS coordinate system

I totally understand this part.

The reason I said this:

nii2mesh exports meshes to RAS coordinate regardless of the input coordinate system

is because that my input NIfTI file has LPS orientation (converted from DICOM using SimpleITK).

The LPS orientation is confirmed with nibabel:

import nibabel as nib
img = nib.load(nii_file)
print(nib.aff2axcodes(img.affine))
# ("L", "P", "S")

So is it safe to assume that nii2mesh ALWAYS return the mesh in RAS coordinate system regardless of the input coordinate system?

@neurolabusc
Copy link
Owner

Yes. The nii2mesh mesh vertices are always RAS, regardless of the order that input voxels are stored to disk.

Note that NIfTI always describes world space as RAS, and there are logically 48 combinations that data can be stored to disk. The NIfTI header spatial transformation(s) map voxel to world space. One little wrinkle is that the NIfTI header can store two independent spatial transforms: the quaternion-based QForm and the matrix-based SForm. Similar to most tools, when both are specified my tools give precedence to the SForm. However, be aware that at least historically VTK tools gave precedence to the QForm. I believe this was because those tools could not store the shear of rhomboidal volumes (the SForm has 12 degrees of freedom while the QForm has 9).

@thangngoc89
Copy link
Author

Thank you so much and have a good day.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants