Skip to content

Commit 22c8e60

Browse files
authored
Merge pull request #244 from thewtex/mesh-transform-numpy
DOC: Mesh and Transform NumPy conversion
2 parents b3f6d0e + 35d6f62 commit 22c8e60

File tree

5 files changed

+4358
-15
lines changed

5 files changed

+4358
-15
lines changed

docs/Quick_start_guide.rst

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,16 +27,25 @@ ITK and NumPy
2727

2828
A common use case for using ITK in Python is to mingle NumPy and ITK operations on raster data. ITK provides a large number of I/O image formats and several sophisticated image processing algorithms not available in any other packages. The ability to intersperse that with the SciPy ecosystem provides a great tool for rapid prototyping.
2929

30-
The following script shows how to integrate NumPy and ITK:
30+
The following script shows how to integrate NumPy and `itk.Image`:
3131

3232
.. literalinclude:: code/MixingITKAndNumPy.py
33-
:lines: 8-33
33+
:lines: 16-59
3434

35+
NumPy and `itk.Mesh`:
3536

36-
Similar functions are available to work with `itk.Matrix`, VNL vectors and matrices:
37+
.. literalinclude:: code/MixingITKAndNumPy.py
38+
:lines: 62-76
39+
40+
NumPy and `itk.Transform`:
41+
42+
.. literalinclude:: code/MixingITKAndNumPy.py
43+
:lines: 96-115
44+
45+
NumPy and `itk.Matrix`, VNL vectors, and VNL matrices:
3746

3847
.. literalinclude:: code/MixingITKAndNumPy.py
39-
:lines: 35-
48+
:lines: 118-
4049

4150
ITK and Xarray
4251
..............

docs/code/MixingITKAndNumPy.py

Lines changed: 93 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,38 +1,119 @@
11
#!/usr/bin/env python3
22

33
import sys
4+
from pathlib import Path
45

5-
input_filename = sys.argv[1]
6-
output_filename = sys.argv[2]
6+
data_dir = Path(__file__).parent.resolve() / '..' / 'data'
7+
8+
input_image_filename = sys.argv[1]
9+
temp_dir = Path(input_image_filename).parent
10+
output_image_filename = sys.argv[2]
11+
input_mesh_filename = data_dir / 'cow.vtk'
12+
output_mesh_filename = temp_dir / 'cow.vtk'
13+
input_transform_filename = data_dir / 'rigid.tfm'
14+
output_transform_filename = temp_dir / 'rigid.tfm'
715

816
import itk
917
import numpy as np
1018

1119
# Read input image
12-
itk_image = itk.imread(input_filename)
20+
itk_image = itk.imread(input_image_filename)
1321

1422
# Run filters on itk.Image
1523

1624
# View only of itk.Image, pixel data is not copied
17-
np_view = itk.array_view_from_image(itk_image)
25+
array_view = itk.array_view_from_image(itk_image)
1826

1927
# Copy of itk.Image, pixel data is copied
20-
np_copy = itk.array_from_image(itk_image)
28+
array_copy = itk.array_from_image(itk_image)
2129
# Equivalent
22-
np_copy = np.asarray(itk_image)
30+
array_copy = np.asarray(itk_image)
31+
32+
# Image metadata
33+
# Sequences, e.g. spacing, are in zyx (NumPy) indexing order
34+
metadata = dict(itk_image)
2335

36+
# Pixel array and image metadata together
37+
# in standard Python data types + NumPy array
38+
# Sequences, e.g. spacing, are in xyz (ITK) indexing order
39+
image_dict = itk.dict_from_image(itk_image)
2440

25-
# Do NumPy stuff...
41+
42+
# Do interesting things...
2643

2744

2845
# Convert back to ITK, view only, data is not copied
29-
itk_np_view = itk.image_view_from_array(np_copy)
46+
itk_image_view = itk.image_view_from_array(array_copy)
3047

3148
# Convert back to ITK, data is copied
32-
itk_np_copy = itk.image_from_array(np_copy)
49+
itk_image_copy = itk.image_from_array(array_copy)
50+
51+
# Add the metadata
52+
for k, v in metadata.items():
53+
itk_image_view[k] = v
54+
55+
# Save result
56+
itk.imwrite(itk_image_view, output_image_filename)
57+
58+
# Convert back to itk image data structure
59+
itk_image = itk.image_from_dict(image_dict)
60+
61+
62+
# Read input mesh
63+
itk_mesh = itk.meshread(input_mesh_filename)
64+
65+
# Convert to standard Python data types + NumPy arrays
66+
mesh_dict = itk.dict_from_mesh(itk_mesh)
67+
68+
69+
# Do interesting things...
70+
71+
72+
# Convert back to itk mesh data structure
73+
itk_mesh = itk.mesh_from_dict(mesh_dict)
74+
75+
# Save result
76+
itk.meshwrite(itk_mesh, output_mesh_filename)
77+
78+
79+
# itk.Mesh inherits from itk.PointSet,
80+
# create a PointSet from the Mesh
81+
itk_pointset = itk.PointSet[itk.F, 3].New()
82+
itk_pointset.SetPoints(itk_mesh.GetPoints())
83+
itk_pointset.SetPointData(itk_mesh.GetPointData())
84+
85+
# Convert to standard Python data types + NumPy arrays
86+
pointset_dict = itk.pointset_from_dict(itk_pointset)
87+
88+
89+
# Do interesting things...
90+
91+
92+
# Convert back to itk pointset instance
93+
itk_pointset = itk.pointset_from_dict(pointset_dict)
94+
95+
96+
# Read input transforms
97+
#
98+
# This is a Python list
99+
#
100+
# When there is more than one transformation
101+
# the list defines a transformation chain
102+
itk_transforms = itk.transformread(input_transform_filename)
103+
104+
# Convert to standard Python data types + NumPy arrays
105+
transform_dicts = [itk.dict_from_transform(t) for t in itk_transforms]
106+
107+
108+
# Do interesting things...
109+
110+
111+
# Convert back to itk transform instance
112+
itk_transforms = [itk.transform_from_dict(t) for t in transform_dicts]
33113

34114
# Save result
35-
itk.imwrite(itk_np_view, output_filename)
115+
itk.transformwrite(itk_transforms, output_transform_filename)
116+
36117

37118
# VNL matrix from np.ndarray
38119
arr = np.zeros([3,3], np.uint8)
@@ -53,3 +134,5 @@
53134

54135
# np.ndarray from itk.Matrix
55136
arr = itk.array_from_matrix(mat)
137+
# Equivalent
138+
arr = np.asarray(mat)

docs/code/test.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import sys
55
import os
66
import tempfile
7+
import shutil
78

89
def add_test(cmd):
910
cmd.insert(0, sys.executable)
@@ -12,7 +13,7 @@ def add_test(cmd):
1213
def cleanup(files):
1314
for f in files:
1415
if os.path.isdir(f):
15-
os.rmdir(f)
16+
shutil.rmtree(f)
1617
else:
1718
os.remove(f)
1819

0 commit comments

Comments
 (0)