Hi! I am a bit confused Andras says following “Displacement vector elements are defined in RAS coordinates in Slicer …”. But according to the link, Displacement field used Coordinate System LPS.
Transforms are written and read as LPS. Since Slicer uses RAS internally, there is an automatic conversion between RAS<->LPS when reading/writing a transform file.
Vector volumes can store color, displacements, etc. in their voxels and they are read/written to file without any modification.
If you export a transform to a vector volume in Transforms module then vectors will contain displacements in RAS coordinate system and since there is no conversion during read/write to file, if you save this volume, then the resulting file will contain displacement vectors in RAS. If you load this volume as a transform in Slicer or in most other software, they will all assume that the vectors are in LPS, so the displacement field will be incorrect.
We should probably distinguish between different kind of vector components in Slicer (color, spatial, etc.) and convert RAS<->LPS automatically during file read/write if vectors store spatial information. Until this is implemented, you need to manually convert from RAS to LPS before you save a displacement field volume to file that you intend to use as transform.
Thank you very much for the explanation, but I am not sure if I understand correctly. The Vector volume I am interested in is a dense Displacement vector obtained by nonlinear registration in Slicer (i.e. not by reading any external but generated by Slicer internally). As Slicer uses RAS, I assume this Displacement vector should be in RAS. But what about when save it from Slicer? Will Slicer do as for an image file to convert LPS to RAS first, then convert to LPS when save? Or simply save to RAS without any converting? (then if indeed RAS without converting, my confusion is still according to my test, it seems Slicer saved Displacement Vector in LPS). Please correct if I am wrong. Thanks!
Image grid (origin, spacing, axis directions) is always saved as LPS. Vector components in the voxel data are saved as is (if it was RAS in Slicer then it is RAS in the file, too).
Thanks a lot @lassoan for your answer which sounds certain (indeed Image grid is saved LPS which is consistent to what I see). Just Disp grid is also LPS as it is align with the LPS image (used Paraview to verify). Perhaps I should reflect my testing procedure, maybe I made a mistake somewhere… Will come back if I figure out later. Thanks.
Thanks @lassoan for the remind regarding Paraview. Indeed seems it ignores axis directions. But my strategy is always to convert the image to RAI in Slicer (to get a TransformMatrix = Identity matrix), in this way, I would verify in Paraview that Slicer indeed export image file back to LPS.
My ultimate goal is to use the disp field to displace node coordinate of stl surface generated from Slicer. This stl surface when export from Slicer and import to Paraview, I could see it is in RAS.
Following image shows what I described above
White gray shows the image exported from Slicer in mhd format (in LPS) and open in Paraview, then Thresholding to show the head geometry
Blue shows the stl surface generated from Slicer and open in Paraview (in RAS - make sense as this is generated in Slicer with RAS)
Did I misunderstand something during the process? Thanks!
For historical reasons, Slicer still saves STL files in RAS coordinate system by default. You can find the coordinate system definition in the STL header. We’ll probably change this default soon for consistency with other software (see this ticket).
For now, you can use “Export to files” feature in Segment Editor/Segmentation modules and choose LPS for export (or save model and rotate it by 180deg to get it in LPS coordinate system).
Since Paraview ignores direction matrix and its support for volumetric images and dense displacement fields in general have been deteriorated in recent years, I only use Paraview for mesh visualization. I don’t know what coordinate system Paraview uses for mhd files.
This works very well in Slicer. You can apply the transform (it can be simple linear transform, bspline, displacement field, or a combination of these) to the model node. When you read the displacement field from a nrrd file, make sure to choose “Transform” in “Add data” window to load the field as a transform and not as a vector image.
Thanks! OK seems all clear: Indeed I misunderstood and my alignment should be just a coincidence (without awareness of my misunderstanding). Will reflect further on RAS<->LPS in Slicer. With all the info you provided I should be able to sort out.
Thanks for the tip to export to LPS and great that Slicer will make effort updating to LPS.
Then just two short questions would be great if you could clarify:
Orient Scaler Image In Slicer has 48 options like RAI, LPI also RAS and LPS. Is the RAS and LPS there the same as we are taking about here? (Shouldn’t be same because Slicer always reads in RAS? Then what is the difference between RAS Orientation and the RAS anatomical orientation?)
When save (scalar) image to mhd in Slicer, it saved to mhd+zraw (compressesed raw). Is there any way to save to mhd+raw (uncompressed)?
Good question - perhaps a subtle point: This one just reshuffles the pixels and then updates the origin and directions to match. So the resulting volume headers (nrrd or mha) can still be written as LPS or whatever. I don’t use this module but I guess the purpose is to make it easier to export data to something like matlab that might expect a certain pixel layout in memory.
Sure, in the save dialog you can show the options and uncheck Compressed.
Thanks a lot @pieper for your reply! OK after reading the link you sent, I think the RAI, LPI,RAS and LPS in Slicer Orient Scalar Image module is indeed the same thing as we are discussing here on RAS and LPS. Interestingly, after some test, I realised that the RAI in Slicer Orient Image Module = LPS (anatomical orientation defined in https://www.slicer.org/wiki/Coordinate_systems). Hope some expert could confirm if this is indeed correct.
A great tip for saving uncompressed. Thanks a lot!
After more insightful info from @lassoan in a later post, need to update regarding this figure description:
I made a mistake in the text description: white gray color should be the stl generated from Slicer which indeed is in RAS as the stl header says - a remind from @lassoan (Thanks!). Blue color should be the Thresholding of mhd image saved from Slicer indeed in LPS (as it is rotated to the stl in RAS).
Apparently this fig shown in Paraview can not tell anything about RAS and LPS (another mistake I made).
Realised my misunderstanding was sourced to misinterpret RAS and LPS (had the opposite in mind). Coordinate systems - Slicer Wiki
Now seems all clear to me and appreciated very much all the insightful discussions.
The two are related, but be sure to note that Orient Image (renamed Orient Scalar Volume in recent Slicers) shuffles the data and updates the origin and directions accordingly. So the acronyms there refer to slice/row/column layouts. You can see this in the Volumes module Information tab if for example you convert an axial scan to a coronal (the header values will change the volume cover the same extent and the same pixel values will be at the same spots in space). The LPS/RAS difference in nrrd headers is related to the reference coordinate system used to encode points and vectors. (Sorry it’s a bit hard to describe but I wanted to be sure it’s clear).
Yes, RAI in a mha file header means LPS. It is unclear if this inversion was intentional or somehow misinterpreted, see more details in this discussion.