Hi message board,
I’m trying to create a script in Python where I create a cine clip of a 3D volume. I want to make an itk image out of a 4D x array with data labels ‘x’, ‘y’, ‘z’, ‘t’.
I made a simple script where I repeat an image volume of a sphere at each time point. When I try to create the itk image I get an error message. My python script and error messages are below. Are there any suggestions for what the problem could be?
Code:
import numpy as np
import xarray as xr
import itk
###3D sphere
npim = np.zeros( (101,101,101) )
xx, yy, zz = np.mgrid[0:101, 0:101, 0:101]
rr = np.sqrt( (xx-50)**2 + (yy-50)**2 + (zz-50)**2 )
npim[rr < 15] = 1
###Replicate across t dimension
fourd = npim
fourd.shape = ( 101, 101,101, 1)
fourd = np.tile(fourd, [1,1,1,5])
fourdxr = xr.DataArray(fourd, dims=['x','y','z','t'])
###Create an itk image
print('Creating a 4D image')
itkim = itk.image_from_xarray(fourdxr)
Error Message:
Traceback (most recent call last):
File “testScript.py”, line 24, in
itkim = itk.image_from_xarray(fourdxr)
File “/home/nick/Software/InsightToolkit-5.1.2/build/Wrapping/Generators/Python/itkExtras.py”, line 453, in image_from_xarray
origin.reverse()
TypeError: Expecting an itkVectorD4, an int, a float, a sequence of int or a sequence of float.
Additional information:
Wrong number or type of arguments for overloaded function ‘itkImageBase4_SetSpacing’.
Possible C/C++ prototypes are:
itkImageBase4::SetSpacing(itkVectorD4 const &)
itkImageBase4::SetSpacing(double const *)
itkImageBase4::SetSpacing(float const *)
ITK script where my code sample errors out:
def image_from_xarray(data_array):
"""Convert an xarray.DataArray to an itk.Image.
Metadata encoded with xarray_from_image is applied to the itk.Image.
This interface is and behavior is experimental and is subject to possible
future changes."""
import numpy as np
import itk
spatial_dims = list({'z', 'y', 'x'}.intersection(set(data_array.dims)))
spatial_dims.sort(reverse=True)
spatial_dimension = len(spatial_dims)
ordered_dims = ('z', 'y', 'x')[-spatial_dimension:]
if ordered_dims != tuple(spatial_dims):
raise ValueError('Spatial dimensions do not have the required order: ' + str(ordered_dims))
is_vector = 'c' in data_array.dims
itk_image = itk.image_view_from_array(data_array.values, is_vector=is_vector)
origin = [0.0]*spatial_dimension
spacing = [1.0]*spatial_dimension
for index, dim in enumerate(spatial_dims):
coords = data_array.coords[dim]
if coords.shape[0] > 1:
origin[index] = float(coords[0])
spacing[index] = float(coords[1]) - float(coords[0])
spacing.reverse()
itk_image.SetSpacing(spacing)
origin.reverse()
itk_image.SetOrigin(origin)
if 'direction' in data_array.attrs:
direction = data_array.attrs['direction']
itk_image.SetDirection(np.flip(direction))
return itk_image