Skip to content

Commit

Permalink
ENH: Expose numpy / vector container interface
Browse files Browse the repository at this point in the history
  • Loading branch information
tbirdso committed Mar 24, 2021
1 parent 346e127 commit cca42db
Show file tree
Hide file tree
Showing 2 changed files with 79 additions and 12 deletions.
25 changes: 13 additions & 12 deletions Modules/Bridge/NumPy/wrapping/test/itkPyVectorContainerTest.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,24 +33,25 @@ def test_NumPyBridge_VectorContainer(self):
"Try to convert a itk.VectorContainer into a Numpy array and back."

if not (
hasattr(itk.VectorContainer, "ULF")
hasattr(itk.VectorContainer, "ULLF")
and hasattr(itk.PyVectorContainer, "F")
and hasattr(itk.Point, "F3")
and hasattr(itk.VectorContainer, "ULPF3")
and hasattr(itk.VectorContainer, "ULLPF3")
and hasattr(itk.Point, "F2")
and hasattr(itk.VectorContainer, "ULPF2")
and hasattr(itk.VectorContainer, "ULLPF2")
):
# There is insufficient wrapping to perform this test; skip it.
print('Insufficient wrapping to perform itkPyVectorContainerTest')
return

v1 = itk.VectorContainer[itk.UL, itk.F].New()
v1 = itk.VectorContainer[itk.ULL, itk.F].New()
v1.Reserve(4)
v1.SetElement(0, 1.2)
v1.SetElement(1, 2)
v1.SetElement(2, 4)
v1.SetElement(3, 5)
arr = itk.PyVectorContainer[itk.F].array_view_from_vector_container(v1)
v2 = itk.PyVectorContainer[itk.F].vector_container_from_array(arr)
arr = itk.array_view_from_vector_container(v1)
v2 = itk.vector_container_from_array(arr)
self.assertEqual(v1.Size(), arr.shape[0])
self.assertEqual(v1.Size(), v2.Size())
# Compute difference between the original vector and numpy array view
Expand All @@ -67,16 +68,16 @@ def test_NumPyBridge_VectorContainer(self):
v1.SetElement(0, 1)
self.assertEqual(v1.GetElement(0), arr[0])
# Test deep copy
arr_cp = itk.PyVectorContainer[itk.F].array_from_vector_container(v1)
arr_cp = itk.array_from_vector_container(v1)
self.assertEqual(v1.GetElement(0), arr_cp[0])
v1.SetElement(0, 0)
self.assertNotEqual(v1.GetElement(0), arr_cp[0])
v2_cp = itk.PyVectorContainer[itk.F].vector_container_from_array(arr_cp)
v2_cp = itk.vector_container_from_array(arr_cp)
arr_cp[0] = 2
self.assertNotEqual(v2_cp.GetElement(0), arr_cp[0])

PointType = itk.Point[itk.F, 3]
v_point = itk.VectorContainer[itk.UL, PointType].New()
v_point = itk.VectorContainer[itk.ULL, PointType].New()
v_point.Reserve(2)
point = PointType()
point[0] = 1.0
Expand All @@ -87,13 +88,13 @@ def test_NumPyBridge_VectorContainer(self):
point[1] = 8.0
point[2] = 9.0
v_point.SetElement(1, point)
arr = itk.PyVectorContainer[PointType].array_view_from_vector_container(v_point)
arr = itk.array_view_from_vector_container(v_point)
self.assertTrue(
np.array_equal(arr, np.array([[1.0, 2.0, 4.0], [6.0, 8.0, 9.0]]))
)

PointType = itk.Point[itk.F, 2]
v_point = itk.VectorContainer[itk.UL, PointType].New()
v_point = itk.VectorContainer[itk.ULL, PointType].New()
v_point.Reserve(2)
point = PointType()
point[0] = 1.0
Expand All @@ -102,7 +103,7 @@ def test_NumPyBridge_VectorContainer(self):
point[0] = 6.0
point[1] = 8.0
v_point.SetElement(1, point)
arr = itk.PyVectorContainer[PointType].array_view_from_vector_container(v_point)
arr = itk.array_view_from_vector_container(v_point)
self.assertTrue(np.array_equal(arr, np.array([[1.0, 2.0], [6.0, 8.0]])))


Expand Down
66 changes: 66 additions & 0 deletions Wrapping/Generators/Python/itk/support/extras.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,9 @@
"image_from_array",
"GetImageViewFromArray",
"image_view_from_array",
"array_from_vector_container",
"array_view_from_vector_container",
"vector_container_from_array",
"GetArrayFromVnlVector",
"array_from_vnl_vector",
"GetArrayViewFromVnlVector",
Expand Down Expand Up @@ -385,6 +388,69 @@ def GetImageViewFromArray(arr, is_vector: bool = False, ttype=None):
image_view_from_array = GetImageViewFromArray


def array_from_vector_container(container, ttype=None):
"""Get an Array with the content of the vector container"""
import itk

# Find container type
if ttype is not None:
if isinstance(ttype, (tuple, list)):
if len(ttype) != 1:
raise RuntimeError("Expected 1 component in ttype tuple.")
DataType = ttype[0]
else:
DataType = ttype
else:
DataType = itk.template(container)[1][1]
keys = [k for k in itk.PyVectorContainer.keys() if k[0] == DataType]
if len(keys) == 0:
raise RuntimeError("No suitable template parameter can be found.")
# Create numpy array of the type of the input container
return itk.PyVectorContainer[keys[0]].array_from_vector_container(container)


def array_view_from_vector_container(container, ttype=None):
"""Get an Array view with the content of the vector container"""
import itk

# Find container type
if ttype is not None:
if isinstance(ttype, (tuple, list)):
if len(ttype) != 1:
raise RuntimeError("Expected 1 component in ttype tuple.")
DataType = ttype[0]
else:
DataType = ttype
else:
DataType = itk.template(container)[1][1]
keys = [k for k in itk.PyVectorContainer.keys() if k[0] == DataType]
if len(keys) == 0:
raise RuntimeError("No suitable template parameter can be found.")
# Create numpy array of the type of the input container
return itk.PyVectorContainer[keys[0]].array_view_from_vector_container(container)


def vector_container_from_array(arr, ttype=None):
"""Get a vector container from a Python array"""
import itk

# Find container type
if ttype is not None:
if isinstance(ttype, (tuple, list)):
if len(ttype) != 1:
raise RuntimeError("Expected 1 component in ttype tuple.")
DataType = ttype[0]
else:
DataType = ttype
else:
DataType = _get_itk_pixelid(arr)
keys = [k for k in itk.PyVectorContainer.keys() if k[0] == DataType]
if len(keys) == 0:
raise RuntimeError("No suitable template parameter can be found.")
# Create numpy array of the type of the input container
return itk.PyVectorContainer[keys[0]].vector_container_from_array(arr)


def _GetArrayFromVnlObject(vnl_object, function_name: str, ttype):
"""Get an array with the content of vnl_object"""
# Finds the vnl object type
Expand Down

0 comments on commit cca42db

Please sign in to comment.