How do I load a vtkImageData as an image?

Hello,

I have been trying to reuse the array of a UniformGrid (PyVista’s equivalent to vtkImageData) with ITK. The resulting data seems to be cropped by 1 voxel. How can I load the data as cells with ITK?

(Extra.) Ultimately, the point is to perform registration on this data, and to store the results in a VTK format (e.g. VTI, VTU, VTS). In the code below, the data is loaded from a VTI file, which could be achieved with ITK in some way, but in the actual case, a Gmsh file is loaded as PyVista data and processed before it arrives to ITK.

Thank you!

# License: GPLv3 (GNU Public License version 3.0)
import numpy as np
import pyvista as pv
import itk

ref_vti = pv.UniformGrid("tmp_gmsh.vti")
ref_vti.save("tmp_ref_vti.vti")
print("tmp_ref_vti.vti")

# * Convert grid into ITK images
image_type = itk.Image[itk.F, 3]
nx, ny, nz = [val - 1 for val in ref_vti.dimensions]
fixed_image_arr = np.reshape(
    ref_vti.cell_data["material"], [nz, nx, ny])
fixed_image = itk.image_from_array(
    fixed_image_arr.astype(np.float32), ttype=image_type)

# # Does not work:
#
# itk.image_from_vtk_image(ref_vti)
#
# # Result:
# #   File "/home/edgar/.local/lib/python3.10/site-packages/itk/support/extras.py", line 746, in image_from_vtk_image
# #     array = vtk_to_numpy(point_data.GetScalars())
# #   File "/usr/lib/python3.10/site-packages/vtkmodules/util/numpy_support.py", line 215, in vtk_to_numpy
# #   AttributeError: 'NoneType' object has no attribute 'GetDataType'

# Trying to set the right dimensions on the grid
fixed_image.SetSpacing(ref_vti.spacing)
fixed_image.SetOrigin(ref_vti.GetOrigin())

# * Save VTK
first_frame_vtk = "tmp_itk_reference.vtk"
itk.imwrite(fixed_image, first_frame_vtk)
print(first_frame_vtk)
np.savez(first_frame_vtk.replace(".vtk", ".npz"),
         fixed_image_arr)

# | itk                       |  5.3.0 |
# | itk-core                  |  5.3.0 |
# | itk-elastix               | 0.15.0 |
# | itk-filtering             |  5.3.0 |
# | itk-io                    |  5.3.0 |
# | itk-meshtopolydata        | 0.10.0 |
# | itk-minimalpathextraction |  1.2.4 |
# | itk-numerics              |  5.3.0 |
# | itk-registration          |  5.3.0 |
# | itk-segmentation          |  5.3.0 |
# | itk-strain                |  0.3.6 |
# | itk-tubetk                |  1.3.4 |
# | itkwidgets                | 0.32.5 |
# | numpy                     | 1.24.1 |
# | pyvista                   | 0.37.0 |
# | scipy                     | 1.10.0 |
# | python                    | 3.10.9 |

I also tried with this

itk.vtk_image_import("tmp_gmsh.vti", ttype=image_type)

Which results in this

Traceback (most recent call last):
  File "/home/edgar/.local/lib/python3.10/site-packages/itk/support/extras.py", line 1526, in set_inputs
    new_itk_object.SetInput(setInputNb, arg)
AttributeError: 'itkVTKImageImportIF3' object has no attribute 'SetInput'. Did you mean: 'GetInputs'?

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "<string>", line 19, in __PYTHON_EL_eval
  File "/home/edgar/GlassFibre/Code/examples/feed_vti_into_dvc.py", line 1, in <module>
    # License: GPLv3 (GNU Public License version 3.0)
  File "/home/edgar/.local/lib/python3.10/site-packages/itk/support/helpers.py", line 176, in image_filter_wrapper
    return image_filter(*args, **kwargs)
  File "/home/edgar/.local/lib/python3.10/site-packages/itk/itkVTKImageImportPython.py", line 1576, in vtk_image_import
    instance = itk.VTKImageImport.New(*args, **kwargs)
  File "/home/edgar/.local/lib/python3.10/site-packages/itk/support/template_class.py", line 735, in New
    return self[list(keys)[0]].New(*args, **kwargs)
  File "/home/edgar/.local/lib/python3.10/site-packages/itk/itkVTKImageImportPython.py", line 616, in New
    template_class.New(obj, *args, **kargs)
  File "/home/edgar/.local/lib/python3.10/site-packages/itk/support/template_class.py", line 800, in New
    itk.set_inputs(self, args, kargs)
  File "/home/edgar/.local/lib/python3.10/site-packages/itk/support/extras.py", line 1554, in set_inputs
    raise AttributeError("No method found to set the input.")
AttributeError: No method found to set the input.

tmp_size_mismatch.tar.gz (91.4 KB)

Here is a related question: Slack

[EDIT]
I hope that posting the raw code helps (it’s part of the tar.gz). Thanks!

# License: GPLv3 (GNU Public License version 3.0)
import numpy as np
import pyvista as pv
import itk

ref_vti = pv.UniformGrid("tmp_gmsh.vti")
ref_vti.save("tmp_ref_vti.vti")
print("tmp_ref_vti.vti")

# * Convert grid into ITK images
image_type = itk.Image[itk.F, 3]
nx, ny, nz = [val - 1 for val in ref_vti.dimensions]
fixed_image_arr = np.reshape(
    ref_vti.cell_data["material"], [nz, nx, ny])
fixed_image = itk.image_from_array(
    fixed_image_arr.astype(np.float32), ttype=image_type)

# # Does not work:
#
# itk.image_from_vtk_image(ref_vti)
#
# # Result:
# #   File "/home/edgar/.local/lib/python3.10/site-packages/itk/support/extras.py", line 746, in image_from_vtk_image
# #     array = vtk_to_numpy(point_data.GetScalars())
# #   File "/usr/lib/python3.10/site-packages/vtkmodules/util/numpy_support.py", line 215, in vtk_to_numpy
# #   AttributeError: 'NoneType' object has no attribute 'GetDataType'

# Trying to set the right dimensions on the grid
fixed_image.SetSpacing(ref_vti.spacing)
fixed_image.SetOrigin(ref_vti.GetOrigin())

# * Save VTK
first_frame_vtk = "tmp_itk_reference.vtk"
itk.imwrite(fixed_image, first_frame_vtk)
print(first_frame_vtk)
np.savez(first_frame_vtk.replace(".vtk", ".npz"),
         fixed_image_arr)

# | itk                       |                  5.3.0 |
# | itk-core                  |                  5.3.0 |
# | itk-elastix               |                 0.15.0 |
# | itk-filtering             |                  5.3.0 |
# | itk-io                    |                  5.3.0 |
# | itk-meshtopolydata        |                 0.10.0 |
# | itk-minimalpathextraction |                  1.2.4 |
# | itk-numerics              |                  5.3.0 |
# | itk-registration          |                  5.3.0 |
# | itk-segmentation          |                  5.3.0 |
# | itk-strain                |                  0.3.6 |
# | itk-tubetk                |                  1.3.4 |
# | itkwidgets                |                 0.32.5 |
# | numpy                     |                 1.24.1 |
# | pyvista                   |                 0.37.0 |
# | scipy                     |                 1.10.0 |

# feed_vti_into_dvc.py ends here

tmp_gmsh.vti (25.6 KB)
tmp_paraview.pvsm (407.0 KB)