Mentions légales du service

Skip to content
Snippets Groups Projects
Commit 3b95434e authored by LEGRAND Jonathan's avatar LEGRAND Jonathan
Browse files

Add a MWE test illustrating troubles when wrapping vt.vtImage

parent 234c5992
No related branches found
No related tags found
No related merge requests found
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
import logging import logging
import numpy as np import numpy as np
import vt from vt import vtImage as vt_vtImage
def _round_list(input_list, dec_val=6): def _round_list(input_list, dec_val=6):
...@@ -31,12 +31,12 @@ def _round_list(input_list, dec_val=6): ...@@ -31,12 +31,12 @@ def _round_list(input_list, dec_val=6):
def _new_from_vt_image(vt_img): def _new_from_vt_image(vt_img):
"""Extract objects to create an image from a ``vtImage`` or a ``vt.vtImage``. """Extract objects to create an image from a ``vtImage`` or a ``vt_vtImage``.
Parameters Parameters
---------- ----------
vt_img : vtImage vt_img : vt_vtImage or vtImage
The vtImage to convert as a SpatialImage An image object inheriting from vt_vtImage.
Returns Returns
------- -------
...@@ -50,28 +50,34 @@ def _new_from_vt_image(vt_img): ...@@ -50,28 +50,34 @@ def _new_from_vt_image(vt_img):
The dictionary of metadata associated to the image. The dictionary of metadata associated to the image.
""" """
# Retreive the shape # - Retrieve the image shape:
sh = vt_img.shape() # returns xyz ordered shape sh = vt_img.shape() # returns xyz ordered shape
sh.reverse() # convert to zyx ordered shape sh.reverse() # convert to zyx ordered shape
vxs = _round_list(vt_img.spacing(), dec_val=6) # - Retrieve the image voxelsize:
vxs = _round_list(vt_img.spacing(), dec_val=6) # round it up to 6 decimals
vxs = vxs[::-1] # convert to zyx ordered voxelsize vxs = vxs[::-1] # convert to zyx ordered voxelsize
# - 2D management:
if len(sh) == 3 and sh[0] == 1: if len(sh) == 3 and sh[0] == 1:
vxs = vxs[1:] vxs = vxs[1:]
sh = sh[1:] sh = sh[1:]
# - Retrieve the array:
arr = vt_img.copy_to_array() arr = vt_img.copy_to_array()
arr = arr.ravel().reshape(sh) # arr = arr.ravel().reshape(sh)
# - Not so important here...
ori = getattr(vt_img, 'origin', None) ori = getattr(vt_img, 'origin', None)
md = getattr(vt_img, 'metadata', {}) md = getattr(vt_img, 'metadata', {})
return arr, vxs, ori, md return arr, vxs, ori, md
class vtImage(vt.vtImage): DEFAULT_ORIG_2D, DEFAULT_ORIG_3D = [0, 0], [0, 0, 0]
"""Python wrapper for vt.vtImage.
class vtImage(vt_vtImage):
"""Python wrapper for vt_vtImage.
Attributes Attributes
---------- ----------
...@@ -80,12 +86,12 @@ class vtImage(vt.vtImage): ...@@ -80,12 +86,12 @@ class vtImage(vt.vtImage):
""" """
def __init__(self, image, voxelsize=None): def __init__(self, image, voxelsize=None, **kwargs):
""" Constructor. """ Constructor.
Parameters Parameters
---------- ----------
image : str or numpy.ndarray or vt.vtImage image : str or numpy.ndarray or vt_vtImage
If a ``str``, should match a file path to load. If a ``str``, should match a file path to load.
If a ``numpy.ndarray``, the array of the image. If a ``numpy.ndarray``, the array of the image.
We assume they are sorted as (planes,) rows & columns ([Z,] Y, X). We assume they are sorted as (planes,) rows & columns ([Z,] Y, X).
...@@ -94,25 +100,31 @@ class vtImage(vt.vtImage): ...@@ -94,25 +100,31 @@ class vtImage(vt.vtImage):
Should be sorted as (planes,) rows & columns ([Z,] Y, X). Should be sorted as (planes,) rows & columns ([Z,] Y, X).
""" """
# Parse keyword arguments:
origin = kwargs.get('origin', None)
metadata = kwargs.get('metadata', {})
if isinstance(image, np.ndarray): if isinstance(image, np.ndarray):
logging.debug( logging.debug(
"``vtImage`` constructor got a ``numpy.ndarray`` as input!") "``vtImage`` constructor got a ``numpy.ndarray`` as input!")
if voxelsize is None: if voxelsize is None:
super().__init__(image) # call to `vt.vtImage` init method! super().__init__(image)
else: else:
super().__init__(image, voxelsize) # call to `vt.vtImage` init method! super().__init__(image, voxelsize)
elif isinstance(image, vt.vtImage): elif isinstance(image, vt_vtImage):
logging.debug( logging.debug(
"``vtImage`` constructor got a ``vt.vtImage`` as input!") "``vtImage`` constructor got a ``{}`` as input!".format(
arr, vxs, _, _ = _new_from_vt_image(image) type(image)))
super().__init__(arr, vxs[::-1]) # call to `vt.vtImage` init method! arr, vxs, ori, md = _new_from_vt_image(image)
# super().__init__(arr, vxs[::-1])
self.__init__(arr, vxs[::-1], origin=ori, metadata=md)
elif isinstance(image, str): elif isinstance(image, str):
logging.debug( logging.debug(
"``vtImage`` constructor got a filename ``str`` as input!") "``vtImage`` constructor got a filename ``str`` as input!")
super().__init__(image) # call to `vt.vtImage` init method! super().__init__(image)
else: else:
raise TypeError( raise TypeError(
"Could not make sense of object given in imput, read the doc!") "Could not make sense of object given in input, read the doc!")
# Specify `ndim` attribute: # Specify `ndim` attribute:
sh = self.shape() sh = self.shape()
...@@ -120,32 +132,81 @@ class vtImage(vt.vtImage): ...@@ -120,32 +132,81 @@ class vtImage(vt.vtImage):
ndim = 3 ndim = 3
else: else:
ndim = 2 ndim = 2
if origin is None:
if ndim == 3:
origin = DEFAULT_ORIG_3D
else:
origin = DEFAULT_ORIG_2D
# Defines attributes:
self._metadata = metadata
self._origin = origin
self.ndim = ndim self.ndim = ndim
if __name__ == '__main__': if __name__ == '__main__':
import vt logging.basicConfig()
logging.getLogger().setLevel(logging.DEBUG)
from os.path import abspath, dirname, join from os.path import abspath, dirname, join
# Defines the image path: # - Defines the image path:
# file_path = '/home/jonathan/Projects/VT_Python/vt-python/data/p58-t0_INT_down_interp_2x.inr'
file_path = abspath( file_path = abspath(
join(dirname(__file__), "..", "data", "p58-t0_INT_down_interp_2x.inr")) join(dirname(__file__), "../..", "data", "p58-t0_INT_down_interp_2x.inr"))
print("Image file path is: {}".format(file_path)) print("Image file path is: {}".format(file_path))
# Load it with vtImage from VT: # - Load it with vtImage from VT:
print("Load it with `vt.vtImage` (i.e. from VT)...") print("Load it with `vt_vtImage` (i.e. from VT)...")
vt_vtim = vt.vtImage(file_path) vt_vtim = vt_vtImage(file_path)
assert isinstance(vt_vtim, vt.vtImage) assert isinstance(vt_vtim, vt_vtImage)
print("Successfully created `vt.vtImage` object:") print("Successfully created `vt_vtImage` object:")
print(vt_vtim) print(vt_vtim)
# Create a vtImage object (defined above, inherit from vt.vtImage) # - Manual creation of vt_vtImage from array and voxelsize:
print("Instantiation of `vtImage` object (INHERIT from `vt.vtImage`)...") arr = vt_vtim.copy_to_array()
vxs = vt_vtim.spacing()
# vt_vtim2 = vt_vtImage(arr, vxs)
# arr2 = vt_vtim2.copy_to_array()
# np.testing.assert_array_equal(arr, arr2)
# - Create a vtImage object a from array and voxelsize:
print("\n\n# - Instantiation of `vtImage` object from array and voxelsize...")
vtim = vtImage(arr, vxs)
isinstance(vtim, vtImage)
print("Successfully created `vtImage` object:")
print(vtim)
print("vtImage.ndim = {}".format(vtim.ndim))
print("Testing `spacing` method:", end=" ")
assert vtim.spacing() == vt_vtim.spacing()
print("OK!")
print("Testing `shape` method:", end=" ")
assert vtim.shape() == vt_vtim.shape()
print("OK!")
print("Testing `copy_to_array` method of `vt_vtImage` object:", end=" ")
vt_vtarr = vt_vtim.copy_to_array()
print("OK!")
print("Testing `copy_to_array` method of `vtImage` object:", end=" ")
vtarr = vtim.copy_to_array()
print("OK!")
print("Comparing arrays from `vt_vtImage` & `vtImage` objects:", end=" ")
np.testing.assert_array_equal(vt_vtarr, vtarr)
print("OK!")
# - Create a vtImage object a from `vt_vtImage`
print("\n\n# - Instantiation of `vtImage` object from `vt_vtImage`...")
vtim = vtImage(vt_vtim) vtim = vtImage(vt_vtim)
isinstance(vtim, vtImage) isinstance(vtim, vtImage)
print("Successfully created `vtImage` object:") print("Successfully created `vtImage` object:")
print(vtim) print(vtim)
print("vtImage.ndim = {}".format(vtim.ndim))
print("vtImage._origin = {}".format(vtim._origin))
print("vtImage._metadata = {}".format(vtim._metadata))
print("Testing `spacing` method:", end=" ") print("Testing `spacing` method:", end=" ")
assert vtim.spacing() == vt_vtim.spacing() assert vtim.spacing() == vt_vtim.spacing()
...@@ -155,7 +216,7 @@ if __name__ == '__main__': ...@@ -155,7 +216,7 @@ if __name__ == '__main__':
assert vtim.shape() == vt_vtim.shape() assert vtim.shape() == vt_vtim.shape()
print("OK!") print("OK!")
print("Testing `copy_to_array` method of `vt.vtImage` object:", end=" ") print("Testing `copy_to_array` method of `vt_vtImage` object:", end=" ")
vt_vtarr = vt_vtim.copy_to_array() vt_vtarr = vt_vtim.copy_to_array()
print("OK!") print("OK!")
...@@ -163,6 +224,6 @@ if __name__ == '__main__': ...@@ -163,6 +224,6 @@ if __name__ == '__main__':
vtarr = vtim.copy_to_array() vtarr = vtim.copy_to_array()
print("OK!") print("OK!")
print("Comparing arrays obtained from `vt.vtImage` & `vtImage` objects:", end=" ") print("Comparing arrays from `vt_vtImage` & `vtImage` objects:", end=" ")
np.testing.assert_array_equal(vt_vtarr, vtarr) np.testing.assert_array_equal(vt_vtarr, vtarr)
print("OK!") print("OK!")
# !/usr/bin/env python
# -*- coding: utf-8 -*-
import unittest
import numpy as np
from os.path import abspath, dirname, join
from vt import vtImage as vt_vtImage
from vt.wrapping_vtImage import vtImage
class TestWrappingvtImage(unittest.TestCase):
@classmethod
def setUpClass(cls):
# Path to a real image file:
cls._file_path = abspath(join(dirname(__file__), "..", "data",
"p58-t1_INT_down_interp_2x.inr"))
# Use vt.vtImage to read image file:
cls._vt_vtim = vt_vtImage(cls._file_path)
def test_init_vt_vtimg_from_copy_to_array(self):
"""Test creation of vt_vtImage from array and voxelsize. """
arr = self._vt_vtim.copy_to_array()
assert isinstance(arr, np.ndarray)
vxs = self._vt_vtim.spacing()
vt_vtim2 = vt_vtImage(arr, vxs)
assert isinstance(vt_vtim2, vt_vtImage)
arr2 = vt_vtim2.copy_to_array()
assert isinstance(arr2, np.ndarray)
np.testing.assert_array_equal(arr, arr2)
def test_init_vtimg_from_copy_to_array(self):
"""Test creation of vtImage from array and voxelsize. """
arr = self._vt_vtim.copy_to_array()
assert isinstance(arr, np.ndarray)
vxs = self._vt_vtim.spacing()
vtim = vtImage(arr, vxs)
assert isinstance(vtim, vt_vtImage)
arr2 = vtim.copy_to_array()
assert isinstance(arr2, np.ndarray)
np.testing.assert_array_equal(arr, arr2)
def test_init_vtimg_from_vt_vtimg(self):
"""Test creation of vtImage from vt_vtImage. """
vtim = vtImage(self._vt_vtim)
assert isinstance(vtim, vt_vtImage)
arr2 = vtim.copy_to_array()
assert isinstance(arr2, np.ndarray)
print(np.array(np.where(self._vt_vtim.copy_to_array() != arr2)).T)
np.testing.assert_array_equal(self._vt_vtim.copy_to_array(), arr2)
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment