How to convert 3D numpy array to vtk and save the .vtk file?

Thanks Ebrahim,
In the begining,I just use python open() to write the numpy data,but later I found it is not efficient,taking too long to save large volume.
Your way is better so I have changed the Solution.I have followed your steps to save vtk file on disk but there’s some modification.

  1. Create a 3D scalar image just as an example
import numpy as np

numpy_arr = np.arange(1,61)
numpy_arr = numpy_arr.reshape(5,4,3)
numpy_arr.shape
--> (5, 4, 3)
  1. Create a new empty volume
nodeName = "MyNewVolume"
imageSize = [5, 4, 3]
voxelType=vtk.VTK_UNSIGNED_CHAR
imageOrigin = [0.0, 0.0, 0.0]
imageSpacing = [0.1, 0.1, 0.1]
imageDirections = [[1,0,0], [0,1,0], [0,0,1]]
fillVoxelValue = 0

# Create an empty image volume, filled with fillVoxelValue
imageData = vtk.vtkImageData()
imageData.SetDimensions(imageSize)
imageData.AllocateScalars(voxelType, 1)
imageData.GetPointData().GetScalars().Fill(fillVoxelValue)

# Create volume node
volumeNode = slicer.mrmlScene.AddNewNodeByClass("vtkMRMLScalarVolumeNode", nodeName)
volumeNode.SetOrigin(imageOrigin)
volumeNode.SetSpacing(imageSpacing)
volumeNode.SetIJKToRASDirections(imageDirections)
volumeNode.SetAndObserveImageData(imageData)
volumeNode.CreateDefaultDisplayNodes()
  1. Update voxels of my volume node from a numpy array
slicer.util.updateVolumeFromArray(volumeNode,numpy_arr)
  1. Save volumeNode to file
myStorageNode = volumeNode.CreateDefaultStorageNode()
myStorageNode.SetFileName("test_data.vtk")
myStorageNode.WriteData(volumeNode)

It is pretty okay when I open this test_data.vtk to check.
image

Also,I have loaded this file in Slicer as follows,
image
Then,I get the array back from this volume in order to double check,

volumeNode = getNode('MyNewVolume')
# volumeNode
a = arrayFromVolume(volumeNode)
a.shape
--> (5, 4, 3)

(a==numpy_arr).all()
--> True

So, I am pretty sure the data is saved correctly as vtk file.
Thank you very much for your help again,Ebrahim.

1 Like