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

**URL:** <https://discourse.slicer.org/t/how-to-convert-3d-numpy-array-to-vtk-and-save-the-vtk-file/22327>\
**Category:** Support\
**Tags:** vtk, python\
**Created:** [March 5, 2022, 6:23pm UTC](https://discourse.slicer.org/t/how-to-convert-3d-numpy-array-to-vtk-and-save-the-vtk-file/22327 "2022-03-05T18:23:12Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![user4](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/user4/32/13172_2.png) [@user4](https://discourse.slicer.org/u/user4)\
**Post date:** [March 5, 2022, 6:23pm UTC](https://discourse.slicer.org/t/how-to-convert-3d-numpy-array-to-vtk-and-save-the-vtk-file/22327/1 "2022-03-05T18:23:12Z")

</div>

Hi,all.Sorry for my little knowledge about VTK.  
Here is the thing I want to do:  
I have a scalar volume (3D numpy array)  
 ![1646504309(1)](https://us1.discourse-cdn.com/flex002/uploads/slicer/original/3X/d/c/dc35aee498196792389e5fb04bbc356857db4e3d.png)  
I want to add some information describing the image and then save it as a .vtk file as follows:  
 ![image](https://us1.discourse-cdn.com/flex002/uploads/slicer/original/3X/d/a/daac4e154ebb304b01eaf0cb2db1d7139d57b973.png)

 ![image](https://us1.discourse-cdn.com/flex002/uploads/slicer/original/3X/6/a/6a99a1737008e06fab116e13c41a7484e8986501.png)  
What should I do to achieve this conversion?  
Thank you in advance for your attention and help!

---

<div class="post-metadata">

**Author:** ![ebrahim](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/ebrahim/32/13403_2.png) [@ebrahim](https://discourse.slicer.org/u/ebrahim)\
**Post date:** [March 7, 2022, 2:00pm UTC](https://discourse.slicer.org/t/how-to-convert-3d-numpy-array-to-vtk-and-save-the-vtk-file/22327/2 "2022-03-07T14:00:19Z")

</div>

I don’t know about adding information to a vtk file, but for converting a numpy array to a vtk array format there is `vtk.util.numpy_support.numpy_to_vtk`; see [here](https://github.com/Kitware/VTK/blob/0e3d0202115be28c521b3116e664250a8c8368c1/Wrapping/Python/vtkmodules/util/numpy_support.py#L104-L127)

---

<div class="post-metadata">

**Author:** ![user4](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/user4/32/13172_2.png) [@user4](https://discourse.slicer.org/u/user4)\
**Post date:** [March 8, 2022, 9:06am UTC](https://discourse.slicer.org/t/how-to-convert-3d-numpy-array-to-vtk-and-save-the-vtk-file/22327/3 "2022-03-08T09:06:52Z")

</div>

yes you are right.

```auto
import vtk.util.numpy_support as numpy_support

def numpyToVTK(data):
    data_type = vtk.VTK_FLOAT
    shape = data.shape

    flat_data_array = data.flatten()
    vtk_data = numpy_support.numpy_to_vtk(num_array=flat_data_array, deep=True, array_type=data_type)
    
    img = vtk.vtkImageData()
    img.GetPointData().SetScalars(vtk_data)
    img.SetDimensions(shape[0], shape[1], shape[2])
    return img

```

with the above function I did a quick test below:

```auto
test_arr = np.arange(36).reshape(3,4,3)
test_arr

--> array([[
        [0, 1, 2],
        [3, 4, 5],
        [6, 7, 8],
        [9, 10, 11]],

       [[12, 13, 14],
        [15, 16, 17],
        [18, 19, 20],
        [21, 22, 23]],

       [[24, 25, 26],
        [27, 28, 29],
        [30, 31, 32],
        [33, 34, 35]]])

```

img = numpyToVTK(data)

**Then verify the vtkImageData is right or not**

```auto
test = vtk.util.numpy_support.vtk_to_numpy(img.GetPointData().GetScalars())
test = test.reshape(3,4,3)
(test == test_arr).all()

-->True

```

However,I’m like you and don’t know how to save the vtk file to the hard drive

---

<div class="post-metadata">

**Author:** ![ebrahim](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/ebrahim/32/13403_2.png) [@ebrahim](https://discourse.slicer.org/u/ebrahim)\
**Post date:** [March 8, 2022, 1:40pm UTC](https://discourse.slicer.org/t/how-to-convert-3d-numpy-array-to-vtk-and-save-the-vtk-file/22327/4 "2022-03-08T13:40:38Z")

</div>

If you have the array associated to a storable mrml node then you can write it to file [as shown here](https://slicer.readthedocs.io/en/latest/developer_guide/script_repository.html#save-a-node-to-file).

To create a volume node out of your numpy array,

1. Add a volume node: `volume_node = slicer.mrmlScene.AddNewNodeByClass("vktMRMLScalarVolumeNode")`
2. Set the values of `volume_node`'s underlying vtkImageData using `slicer.util.updateVolumeFromArray` [described here](https://github.com/Slicer/Slicer/blob/41e1adf2a86a18bef376c3220a8125cd034b971e/Base/Python/slicer/util.py#L1958-L1967).

---

<div class="post-metadata">

**Author:** ![user4](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/user4/32/13172_2.png) [@user4](https://discourse.slicer.org/u/user4)\
**Post date:** [March 10, 2022, 6:11am UTC](https://discourse.slicer.org/t/how-to-convert-3d-numpy-array-to-vtk-and-save-the-vtk-file/22327/5 "2022-03-10T06:11:13Z")

</div>

Thanks, Ebrahim.  
Thank you for telling me the way to create the volume node.  
However,if I want to save the numpy array as .vtk file,actually it’s quite simple as follows:

```auto
f = open('test.vtk','w') # change your vtk file name
f.write('# vtk DataFile Version 2.0\n')
f.write('test\n')
f.write('ASCII\n')
f.write('DATASET STRUCTURED_POINTS\n')
f.write('DIMENSIONS 3 3 4\n') # change your dimension
f.write('SPACING 0.100000 0.100000 0.100000\n')
f.write('ORIGIN 0 0 0\n')
f.write('POINT_DATA 36\n') # change the number of point data
f.write('SCALARS volume_scalars float 1\n')
f.write('LOOKUP_TABLE default\n')
f.write(numpy_array) # change your numpy array here but need some processing
f.close()

```

---

<div class="post-metadata">

**Author:** ![koeglfryderyk](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/koeglfryderyk/32/14638_2.png) [@koeglfryderyk](https://discourse.slicer.org/u/koeglfryderyk)\
**Post date:** [April 22, 2022, 1:38am UTC](https://discourse.slicer.org/t/how-to-convert-3d-numpy-array-to-vtk-and-save-the-vtk-file/22327/6 "2022-04-22T01:38:33Z")

</div>

do you maybe have an idea how to do this for a 2D numpy array?

---

<div class="post-metadata">

**Author:** ![koeglfryderyk](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/koeglfryderyk/32/14638_2.png) [@koeglfryderyk](https://discourse.slicer.org/u/koeglfryderyk)\
**Post date:** [April 22, 2022, 1:42am UTC](https://discourse.slicer.org/t/how-to-convert-3d-numpy-array-to-vtk-and-save-the-vtk-file/22327/7 "2022-04-22T01:42:00Z")

</div>

Just found out:

> **[matlab martix to vtkMatrix4x4](https://discourse.vtk.org/t/matlab-martix-to-vtkmatrix4x4/1419/3)**
>
> Conversion is possible with the DeepCopy() methods that were originally written to be used with C arrays. The ndarray.ravel() method returns a flattened view of the numpy array that can be used with DeepCopy: import numpy as np import vtk m =...

---

<div class="post-metadata">

**Author:** ![user4](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/user4/32/13172_2.png) [@user4](https://discourse.slicer.org/u/user4)\
**Post date:** [June 16, 2022, 2:36am UTC](https://discourse.slicer.org/t/how-to-convert-3d-numpy-array-to-vtk-and-save-the-vtk-file/22327/8 "2022-06-16T02:36:42Z")

</div>

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

```auto
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

```auto
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

```auto
slicer.util.updateVolumeFromArray(volumeNode,numpy_arr)

```

1. Save volumeNode to file

```auto
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](https://us1.discourse-cdn.com/flex002/uploads/slicer/original/3X/6/1/6161cb7ea218c22ca34595395c182c6c6df6c174.png)

Also,I have loaded this file in Slicer as follows,

 ![image](https://us1.discourse-cdn.com/flex002/uploads/slicer/original/3X/a/3/a3c0465b1dc93dce34978b8bfc0ac4ed76d27c96.png)  
Then,I get the array back from this volume in order to double check,

```auto
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.
