Transform freesurfer mesh coordinates to volume coordinates

Hello neuro friends!

I was given an anatomical template with (a) volume images and (b) surface meshes extracted from these volumes with freesurfer. The volumes are in nifti format, the meshes in gifti format.

Opening the volume and meshes in freeview will let you think that they are in the same coordinate system, while doing the same thing in fsleyes or other softwares seems to prove otherwise :scream_cat: (cf screens 1 & 2).
I tried to modify the affine matrix in the gifti header but it seems that these softwares don’t take it into account (same for nibabel and consequently nilearn).

I am very confused with what these coordinate systems are and would love to find a clear explanation about all this! In particular:

  • what space do freesurfer mesh coordinates live in? (I read it’s RAS and that it’s not centered the same way other coordinate systems are ; see screenshot 3, showing point (0,0,0) in my images)
  • what space do nifti volume images live in?
  • where can I find the affine transform to by applied to my freesurfer coordinates that will take them to the same space as my volume images? It feels like I need a simple translation
  • why don’t these softwares take gifti headers into account?

Sorry if these questions don’t make sense, I’m doing my best to untangle all this knowledge :sweat_smile:

[1] Freeview screenshot

[2] Niivue screenshot ; I get a similar result with FSLEyes
Screenshot from 2022-09-26 19-09-38

[3] FSLEyes screenshot showing point (0,0,0)

I eventually found RAS-related information in the header of the aforementioned Gifti files and was able to derive a translation which seem to bring my data to the same space :tada: (I am still not sure what space it is though haha, so I’m still interested in some explanation)

I cut a python gist in case someone else needs this.

1 Like

@alexisthual would you mind sharing your dataset with me so we can update NiiVue to support this? A voxel plus mesh dataset sent to my institutional email would be great.

1 Like

FreeSurfer-generated GIFTIs have two affines. One is the GIFTI-specified one, and the other is a GIFTI-metadata encoding of the FreeSurfer volume geometry (VolGeom{X,Y,Z,C}_{R,A,S} off of memory; this might not be exactly right). FreeSurfer knows to apply the VolGeom affine, pretty much nobody else does.

You can provide the --to-scanner option to mris_convert to have FreeSurfer update the coordinates with the VolGeom, but this will also leave in the VolGeom affine, so everybody but FreeSurfer will handle the file correctly.

The way to get a generic GIFTI from a FreeSurfer surface appears to be to use mris_convert --to-scanner and then remove the VolGeom metadata from the file yourself.


I just read your gist, @alexisthual. You’re doing the same thing that HCP Pipelines and fMRIPrep have done, which is just applying the translation encoded in C_RAS. If the image is oblique, you can get a non-identity XYZ_RAS matrix, in which case this will fail.

FWIW as of fMRIPrep 22.0, we now use the method I describe above: FIX: Use `mris_convert --to-scanner`, and update normalization step by effigies · Pull Request #295 · nipreps/smriprep · GitHub

1 Like