Registration Deformation Export

I am doing the example from the Slicer Sequence Registration Module found online (https://github.com/moselhy/SlicerSequenceRegistration).

I can visualize the results but how do I export them?

How do I know how many nodes I have and how do I export their positions? Can you fit an equation to the deformation?

I will need to make code for updating grid motion.

Thank you.

You can save all data that is in the scene from menu: File / Save.

Displacement field matches the fixed volume geometry (origin, spacing, axis direction, and extents). This information is stored in the displacement field transform file.

There is no equation to fit. What would you like to do?

You can apply the transform to any node in Slicer. For example, you can load a grid model and apply the transform to it - without writing any code. You can then view the deformed grid, save to file, etc.

Let us know if you need more detailed instructions.

Hello and thank you for your reply.

I can export the txt file with the info but every time I open it, it crashes. I am using a macbook.

I need to extract the x y and z components of each node. Is there a way I can have less nodes so the txt file does not crash every time I try to open it?

Thank you.

Sequence Registration uses Elastix and the only standard file format it supports is displacement field, which is typically very large. You may need tens of gigabytes of memory space and if you don’t have it then you run out of memory (the application crashes). Upgrade your computer with more RAM, make available more space (at least 50-100GB) on your hard disk, and/or crop and resample your input image sequence.

I see. I can eventually open the file…it takes a long time.

I am having trouble understanding the file. Screen capture below shows what I see. There are four columns with many rows, what do each column/row mean? I need x y z displacements that I can use in another program to tell the program to move the mesh at each time point.

deform_file

The file contains exactly that.

In the Save data dialog you can also choose to save the displacement field as a nrrd file: in the File Format column choose Displacement field (.nrrd). Saving/loading will also be much faster if you don’t save the values in a text file (.tfm file).

Thank you for your solution!

Hello and sorry to bother again,

I have saved displacement field as .nrrd format but I cannot load it to matlab 2018b. I used the nrrdread.m file but it could not recognize the file. I do not know how to use python so is there another way to open it to view numerical data?

I need to extract x y and z numerical displacements.

Thank you again.

I would try two things:

  1. matlab support hdf5, load the nrrd file in slicer and save it as transform. You can view hdf5 also using [hdfview].(https://www.hdfgroup.org/downloads/hdfview/#obtain)
  2. use the text format.
1 Like

It should work. If there was a problem then it msut be something trivial to fix. Maybe due to some minor syntax difference between Matlab versions. What error message did you get exactly?

Unless you are near the end of your career, it is probably a good idea to switch from Matlab to Python. Analyzing displacement field using Python can be a good learning exercise. Check out Slicer’s Jupyter notebooks, too.

I think I will make the transition to python. Thank you again for the extended help.

Hi,

I think I am doing the similar thing. I have saved displacement field as .nrrd format and loaded it to matlab 2018a. Maybe you need to modify the last sentence in nrrdread.m (the default setting is for 3D but the dvf is 4D array). Do you still use matlab or just make the transition to python? (I am new to python so I’d like to hear your suggestions~)

I need to extract x y and z numerical displacements of specific voxel points. But I am a bit confused about the coordinate definition (especially when the nrrdread.m contains matrix permutation). Did you ever verify the displacement of voxel located at specific position? Or how to check the displacement results?

Your help is highly appreciated!

Crayon

Hi everyone,

Thanks for your discussion. I have tried to register pre-operative ct (moving image) with post-operative ct (fixed image) using Plastimatch (B-spline deformable registration) and also Elastix. The resulting displacement field was saved as .nrrd format.

Also I have done segmentation of fixed image and exported the segment to STL file format.

I need to extract x y and z numerical displacements of specific voxel points (in fixed volume) related to my segment. I wonder when I export to STL files, which coordinate system should I choose?

I know from https://www.slicer.org/wiki/Documentation/4.10/SlicerApplication/SupportedDataFormat and also the metadata that Displacement field is defined in LPS Coordinate system. So maybe I also need to export my stl file with LPS coordinate?

Sorry but I am just entangled in the coordinate definition which I think is quite important for the displacement extraction of specific points. Can I check the displacement results of specific points? Hope for some advice. Thank you all!

Crayon

nrrdread.m supports reading of 4D volumes, so it should work as is. Let me know if you find any issues with it.

The displacement field volume contains exactly that. Each element in the 3D array is a 3-element vector.

What may be confusing is that Slicer stores elements in RAS coordinates, while the geometry of image saved to file is specified in LPS. Displacement vector elements are defined in RAS coordinates in Slicer and when we save a vector volume from Slicer, we do not alter the stored vector components (we don’t know if the vector components correspond to color, spatial coordinates, etc.). Image geometry is stored in LPS by most medical imaging software, that’s why we follow this convention, too. We should probably change Slicer to somehow know that vector components should be converted to LPS for displacement field images, but for now you can do this yourself by inverting the sign of the first two components of the displacement vector that you have read using nrrdread.

Fortunately, this is very simple: Image is specified in LPS physical space. You can convert between LPS and IJK array indexes by using img.ijkToLpsTransform provided by nrrdread.m.

If you process data outside Slicer, I would recommend using LPS coordinate system.

In Slicer, displacement vector values at current mouse pointer position are shown in Transforms module’s Information section (“Displacement vector RAS: (…, …, …)”).

If you exported a transform to a displacement field image and that image is shown in a slice viewer, you can also see the displacement values in the Data Probe window (in the bottom left corner).

By the way, most probably everything would be much simpler to do in Slicer’s Python environment. If you describe what your end goal is, I can give specific advice about how to achieve that.

Thanks for your help. I want to combine intensity based registration with finite element method. My end goal is to modify the displacement vector field and then evaluate the new transform.

I will use the displacement of boundary node as boundary condition. And the position of boundary node is related to the segment (in fixed volume) which is exported to STL file in LPS coordinate. I know that the dvf defines the displacement of voxels in fixed volume. So I will first extract the displacements of specific voxel points. Then write back new displacements calculated by fem to generate new transform (may need some interpolation).

That’s why I am more concerned with coordinate definition, including the position and displacement of specific voxel points. Many thanks if you have any suggestions.

Best,
Crayon

Thanks for the clarifications. I have succeeded in reading 4D transform using nrrdread.m you provided. But I don’t quite understand that “Displacement vector elements are defined in RAS coordinates in Slicer” and “for now you can do this yourself by inverting the sign of the first two components of the displacement vector that you have read using nrrdread”.

After loading the dvf (.nrrd) to matlab, it showed LPS coordinate (shown below)? Besides, when I located the displacement of specific point in matlab, the absolute value of three directions are all the same as viewed values at current mouse pointer position (“Displacement vector RAS: (…, …, …)”), except the sign of the first two components? I wonder which are the actual displacement results related to voxel points (of segment) defined in LPS coordinate?

Sorry for being entangled in the coordinate definition. I have got inspiration from this discussion thread (Porting a transformation from Matlab to Slicer). But I was still not sure related to my own problem. Your help is highly appreciated!

Best,
Crayon

dvf

Slicer can compute for you the displacement at each surface mesh point and save it in the mesh: after you exported the displacement field to image volume in Transforms module, go to “Probe volume with model” module to compute displacement of each model point and save it in the model as point data. This output model must be saved in a file format that can store vector data associated with points: VTK or VTP (STL file can only store point positions and triangles, not the displacement vectors, so STL will not work).

You can find VTK and VTP file readers for Matlab, but it would be probably much more user-friendly to implement the whole registration workflow in Python. There are many free FEM solvers in Python (such as FEniCS) that can be installed in recent Slicer Preview versions and directly used by Slicer modules.

Yes, conversion between LPS (left-posterior-superior) and RAS (right-anterior-superior) coordinates is simply inverting the sign of the first two components.

Thanks for the extended help. I think I will make the transition to python soon and will try to implement the whole workflow in python environment.

Now I have got modified displacement field calculated by fem and imported it back to slicer as transform (.nrrd format using nrrdwrite.m). I wonder if I have a contour/segment in moving image, can I apply transform to get a deformed one in fixed image? Then I could use Segment Comparison module in SlicerRT extension to compare the deformed contour/segment to the reference one delineated by radiation oncologist.

Sorry but I didn’t find relevant discussion thread which I could follow. Hope for some advice. Thanks a lot for your kindness.

Best,
Crayon

You can load the displacement field as a Transform (in Add data dialog, choose “Transform” in Description column) and apply it to any node (image, segment, etc.) using Transforms module. If you want to do analysis, then it may be necessary to harden the transform on the node.