Skip to content

Commit

Permalink
test(image-io): add python emscirpten tests
Browse files Browse the repository at this point in the history
  • Loading branch information
thewtex committed Nov 8, 2023
1 parent eca5bda commit 2302ec4
Show file tree
Hide file tree
Showing 9 changed files with 325 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

from .read_image import read_image, imread
from .write_image import write_image, imwrite
from .read_image_async import read_image_async, imread_async
from .write_image_async import write_image_async, imwrite_async

from .bio_rad_read_image_async import bio_rad_read_image_async
from .bio_rad_read_image import bio_rad_read_image
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import os
from typing import Optional, Union

from itkwasm import (
environment_dispatch,
Image,
PixelTypes,
IntTypes,
FloatTypes,
)

async def read_image_async(
serialized_image: os.PathLike,
information_only: bool = False,
pixel_type: Optional[PixelTypes]=None,
component_type: Optional[Union[IntTypes, FloatTypes]]=None,
) -> Image:
"""Read an image file format and convert it to the itk-wasm file format
:param serialized_image: Input image serialized in the file format
:type serialized_image: os.PathLike
:param information_only: Only read image metadata -- do not read pixel data.
:type information_only: bool
:param pixel_type: Pixel type to cast to.
:type pixel_Type: Optional[PixelTypes]
:param component_type: Component type to cast to.
:type component_type: Optional[Union[IntTypes, FloatTypes]]
:return: Output image
:rtype: Image
"""
func = environment_dispatch("itkwasm_image_io", "read_image_async")
output = await func(serialized_image, information_only=information_only, pixel_type=pixel_type, component_type=component_type)
return output

async def imread_async(
serialized_image: os.PathLike,
information_only: bool = False,
pixel_type: Optional[PixelTypes]=None,
component_type: Optional[Union[IntTypes, FloatTypes]]=None,
) -> Image:
return await read_image_async(serialized_image, information_only=information_only, pixel_type=pixel_type, component_type=component_type)

imread_async.__doc__ = f"""{read_image_async.__doc__}
Alias for read_image.
"""
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ def write_image(
:param use_compression: Use compression in the written file
:type use_compression: bool
"""
func = environment_dispatch("itkwasm_image_io", "png_write_image")
func = environment_dispatch("itkwasm_image_io", "write_image")
func(image, serialized_image, information_only=information_only, use_compression=use_compression)
return

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import os
from typing import Dict, Tuple, Optional, List, Any

from itkwasm import (
environment_dispatch,
Image,
)

async def write_image_async(
image: Image,
serialized_image: str,
information_only: bool = False,
use_compression: bool = False,
) -> None:
"""Write an itk-wasm file format converted to an image file format
:param image: Input image
:type image: Image
:param serialized_image: Output image serialized in the file format.
:type serialized_image: str
:param information_only: Only write image metadata -- do not write pixel data.
:type information_only: bool
:param use_compression: Use compression in the written file
:type use_compression: bool
"""
func = environment_dispatch("itkwasm_image_io", "write_image_async")
await func(image, serialized_image, information_only=information_only, use_compression=use_compression)
return

async def imwrite_async(
image: Image,
serialized_image: os.PathLike,
information_only: bool = False,
use_compression: bool = False,
) -> None:
return await write_image_async(image, serialized_image, information_only=information_only, use_compression=use_compression)

imwrite_async.__doc__ = f"""{write_image_async.__doc__}
Alias for write_image.
"""
20 changes: 17 additions & 3 deletions packages/image-io/python/itkwasm-image-io/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ keywords = [

requires-python = ">=3.8"
dependencies = [
"itkwasm >= 1.0.b131",
"itkwasm >= 1.0.b145",
"itkwasm-image-io-wasi; sys_platform != \"emscripten\"",
"itkwasm-image-io-emscripten; sys_platform == \"emscripten\"",

Expand All @@ -45,15 +45,29 @@ path = "itkwasm_image_io/_version.py"
[tool.hatch.envs.default]
dependencies = [
"pytest",
"pytest-pyodide",
]

[project.urls]
Home = "https://github.com/InsightSoftwareConsortium/itk-wasm"
Source = "https://github.com/InsightSoftwareConsortium/itk-wasm"

[tool.hatch.envs.default.scripts]
test = "pytest"

test = [
"hatch build -t wheel",
"pytest --dist-dir=./dist --rt=chrome",
]
download-pyodide = [
"curl -L https://github.com/pyodide/pyodide/releases/download/0.24.1/pyodide-0.24.1.tar.bz2 -o pyodide.tar.bz2",
"tar xjf pyodide.tar.bz2",
"rm -rf dist pyodide.tar.bz2",
"mv pyodide dist",
]
serve = [
"hatch build -t wheel",
'echo "\nVisit http://localhost:8877/console.html\n"',
"python -m http.server --directory=./dist 8877",
]

[tool.hatch.build]
exclude = [
Expand Down
29 changes: 29 additions & 0 deletions packages/image-io/python/itkwasm-image-io/tests/fixtures.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import pytest
import sys

if sys.version_info < (3,10):
pytest.skip("Skipping pyodide tests on older Python", allow_module_level=True)

from pytest_pyodide import run_in_pyodide

from itkwasm_image_io import __version__ as test_package_version

@pytest.fixture
def package_wheel():
return f"itkwasm_image_io-{test_package_version}-py3-none-any.whl"

@pytest.fixture
def input_data():
from pathlib import Path
input_base_path = Path('..', '..', 'test', 'data')
test_files = [
Path('input') / 'cthead1.png',
Path('input') / 'biorad.pic',
Path('input') / 'brainweb165a10f17.mha',
]
data = {}
for f in test_files:
with open(input_base_path / f, 'rb') as fp:
print(str(f.name))
data[str(f.name)] = fp.read()
return data
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import sys

if sys.version_info < (3,10):
pytest.skip("Skipping pyodide tests on older Python", allow_module_level=True)

from pytest_pyodide import run_in_pyodide
from .fixtures import package_wheel, input_data

@run_in_pyodide(packages=['micropip'])
async def test_bio_rad_async(selenium, package_wheel, input_data):
import micropip
await micropip.install(package_wheel)
def write_input_data_to_fs(input_data, filename):
with open(filename, 'wb') as fp:
fp.write(input_data[filename])

from pathlib import Path

from itkwasm_image_io import bio_rad_read_image_async, bio_rad_write_image_async

def verify_image(image):
assert image.imageType.dimension == 2
assert image.imageType.componentType == "uint8"
assert image.imageType.pixelType == "Scalar"
assert image.imageType.components == 1
assert image.origin[0] == 0.0
assert image.origin[1] == 0.0
assert image.spacing[0] == 0.06000000238418579
assert image.spacing[1] == 0.06000000238418579
assert image.direction[0, 0] == 1.0
assert image.direction[0, 1] == 0.0
assert image.direction[1, 0] == 0.0
assert image.direction[1, 1] == 1.0
assert image.size[0] == 768
assert image.size[1] == 512
assert image.data.shape[1] == 768
assert image.data.shape[0] == 512
assert image.data.ravel()[1000] == 27

test_file_path = 'biorad.pic'
write_input_data_to_fs(input_data, test_file_path)

assert Path(test_file_path).exists()

could_read, image = await bio_rad_read_image_async(test_file_path)
assert could_read
verify_image(image)

test_output_file_path = 'biorad_out.pic'

use_compression = False
could_write = await bio_rad_write_image_async(image, test_output_file_path, use_compression)
assert could_write

could_read, image = await bio_rad_read_image_async(test_output_file_path)
assert could_read
verify_image(image)
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
import sys

if sys.version_info < (3,10):
pytest.skip("Skipping pyodide tests on older Python", allow_module_level=True)

from pytest_pyodide import run_in_pyodide
from .fixtures import package_wheel, input_data

@run_in_pyodide(packages=['micropip'])
async def test_metaimage_async(selenium, package_wheel, input_data):
import micropip
await micropip.install(package_wheel)
def write_input_data_to_fs(input_data, filename):
with open(filename, 'wb') as fp:
fp.write(input_data[filename])

from pathlib import Path

from itkwasm_image_io_emscripten import meta_read_image_async, meta_write_image_async

test_input_file_path = 'brainweb165a10f17.mha'
test_output_file_path = 'meta-image-test-brainweb165a10f17.mha'

def verify_image(image):
assert image.imageType.dimension == 3
assert image.imageType.componentType == "uint8"
assert image.imageType.pixelType == "Scalar"
assert image.imageType.components == 1
assert image.origin[0] == 0.0
assert image.origin[1] == 0.0
assert image.origin[2] == 0.0
assert image.spacing[0] == 1.0
assert image.spacing[1] == 1.0
assert image.spacing[2] == 1.0
assert image.direction[0, 0] == 1.0
assert image.direction[0, 1] == 0.0
assert image.direction[0, 2] == 0.0
assert image.direction[1, 0] == 0.0
assert image.direction[1, 1] == 1.0
assert image.direction[1, 2] == 0.0
assert image.direction[2, 0] == 0.0
assert image.direction[2, 1] == 0.0
assert image.direction[2, 2] == 1.0
assert image.size[0] == 181
assert image.size[1] == 217
assert image.size[2] == 180
assert image.data.ravel()[0] == 5
assert image.data.ravel()[1] == 8
assert image.data.ravel()[2] == 2

write_input_data_to_fs(input_data, test_input_file_path)

assert Path(test_input_file_path).exists()

could_read, image = await meta_read_image_async(test_input_file_path)
assert could_read
verify_image(image)

use_compression = False
could_write = await meta_write_image_async(image, test_output_file_path, use_compression)
assert could_write

could_read, image = await meta_read_image_async(test_output_file_path)
assert could_read
verify_image(image)
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import sys

if sys.version_info < (3,10):
pytest.skip("Skipping pyodide tests on older Python", allow_module_level=True)

from pytest_pyodide import run_in_pyodide
from .fixtures import package_wheel, input_data

@run_in_pyodide(packages=['micropip'])
async def test_read_write_image_async(selenium, package_wheel, input_data):
import micropip
await micropip.install(package_wheel)
def write_input_data_to_fs(input_data, filename):
with open(filename, 'wb') as fp:
fp.write(input_data[filename])

from pathlib import Path

from itkwasm_image_io import read_image_async, write_image_async, imread_async, imwrite_async

test_input_file_path = "cthead1.png"
test_output_file_path = "read-write-cthead1.png"

def verify_image(image):
assert image.imageType.dimension == 2
assert image.imageType.componentType == "uint8"
assert image.imageType.pixelType == "RGB"
assert image.imageType.components == 3
assert image.origin[0] == 0.0
assert image.origin[1] == 0.0
assert image.spacing[0] == 1.0
assert image.spacing[1] == 1.0
assert image.direction[0, 0] == 1.0
assert image.direction[0, 1] == 0.0
assert image.direction[1, 0] == 0.0
assert image.direction[1, 1] == 1.0
assert image.size[0] == 256
assert image.size[1] == 256
assert image.data.shape[1] == 256
assert image.data.shape[0] == 256

write_input_data_to_fs(input_data, test_input_file_path)

assert Path(test_input_file_path).exists()

image = await read_image_async(test_input_file_path)
verify_image(image)

use_compression = False
await write_image_async(image, test_output_file_path, use_compression=use_compression)

image = await read_image_async(test_output_file_path)
verify_image(image)

image = await imread_async(test_input_file_path)
verify_image(image)

use_compression = False
await imwrite_async(image, test_output_file_path, use_compression=use_compression)

image = await imread_async(test_output_file_path)
verify_image(image)

0 comments on commit 2302ec4

Please sign in to comment.