Interpolate volumetric mesh from deformation vector field image volume

Hi,

I have created a deformed 3D-CT version and corresponding deformation vector field (DVF) volume of a given nifti image volume (reference image 3D-CT volume) using another tool. I then extracted the liver mesh from the binary mask image volume which is obtained by segmenting the liver region from the reference image volume. Now what I want is that extract the displacement field from the deformation vector field and apply that to the mesh points so that deformed 3D-CT align with the mesh.

I’ve already done this with SimpleITK, but I’m curious if it’s also possible with the 3D slicer. If so, could you kindly explain the procedure to me ? Additionally, I would also like to know how to visualze the deforamtion field on mesh points with a colour map ?

Let’s assume I have loaded volumes below to the 3D slicer:

  • Reference 3D-CT volume (nifti format)
  • Deformed 3D-CT volume and its corresponding deformation vector field (nifti format)
  • Reference volumetric mesh in .vtk format (extracted from the reference 3D-CT)

Please note that here the deformation field is the final position of the voxel after it has been transformed, i.e. initial position of the voxel + the displacement of the voxel

That should all work fine, but storing deformation fields in nifti is sure to lead to coordinate system issues that you’ll need to sort out. Just select Transform when loading the vector field and then you can apply it to your mesh. Have a look at the documentation of the Transforms module.

Hi Steve,

Thank you for your response. I’ve loaded the deformation field as a transform and attempted to apply it to the mesh nodes (see the attacehd screen-shot below). However, it appears that the mesh deformation isn’t occurring as expected. I suspect the reason for this discrepancy is that the transform represents a deformation field, not a displacement field.

I’m now seeking guidance on how to calculate the displacement field using 3D Slicer, given that I have access to both the reference 3D-CT and the Deformation vector field. To clarify, the deformation vector field in question represents the voxel’s final position after undergoing transformation, which is essentially the initial voxel position combined with its displacement.

In my previous work with SimpleITK, I used the DisplacementField function to calculate the displacement field, as illustrated in the code snippet below. My current query pertains to extracting the displacement field and applying it to the mesh nodes in a manner similar to what I’ve done previously. Any insights or guidance on this matter would be greatly appreciated.

Screenshot:

SimpleITK code:

def generateDeformedMeshesFromITKDVFs(dvf_path, reference_image_physical_points, reference_mesh):

    dvf_image = sitk.ReadImage(dvf_path)

    corrected_dvf_image = sitk.Compose(
        [
            sitk.VectorIndexSelectionCast(dvf_image, 0, sitk.sitkFloat64),
            sitk.VectorIndexSelectionCast(dvf_image, 1, sitk.sitkFloat64),
            sitk.VectorIndexSelectionCast(dvf_image, 2, sitk.sitkFloat64),
        ]
    )

    #create the SimpleITK representation of the DVF transformation, which differs from the dvf_image
    # generate displacement vector field
    sitk_dvf = sitk.DisplacementFieldTransform(reference_image_physical_points - corrected_dvf_image)


    reference_mesh_duplicate = copy.deepcopy(reference_mesh)

    transformed_physical_points = []

    # transform each point in the mesh using a displacement field
    for index in range(0, reference_mesh_duplicate.points.shape[0]):
        transformed_physical_points.append(sitk_dvf.TransformPoint(reference_mesh_duplicate.points[index]))


            
reference_image = sitk.ReadImage('./reference_image/MCR.nii.gz')

reference_image_physical_points = sitk.PhysicalPointSource(outputPixelType = sitk.sitkVectorFloat64,
size = reference_image.GetSize(),
origin = reference_image.GetOrigin(),
spacing = reference_image.GetSpacing(),
direction = reference_image.GetDirection())

reference_mesh = meshio.read('./reference_mesh/MCR.vtk')

DVF_path = './dvf.nii.gz'

generateDeformedMeshesFromITKDVFs(DVF_path, reference_image_physical_points, reference_mesh)

Thanks for the extra information.

In this case I guess you need to subtract the original position (the physical coordinate) from the vector stored at that location. This sounds easy enough to do as long as you know all the geometry involved.

Note that SimpleITK is directly available in Slicer’s python environment, so you can just use any of that code to implement the change and make a grid transform to apply to the model’s polydata.