Skip to content

Commit

Permalink
feat(compare-images): Add compare_images_async
Browse files Browse the repository at this point in the history
  • Loading branch information
thewtex committed Aug 22, 2023
1 parent 4959c42 commit 9b20e09
Show file tree
Hide file tree
Showing 3 changed files with 150 additions and 3 deletions.
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
"""itkwasm-compare-images-emscripten: Compare images with a tolerance for regression testing. Emscripten implementation."""

from .compare_double_images_async import compare_double_images_async
from .compare_images_async import compare_images_async
from .vector_magnitude_async import vector_magnitude_async

from ._version import __version__
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
from pathlib import Path
import os
from typing import Dict, Tuple, Optional, List

from .js_package import js_package

from itkwasm.pyodide import (
to_js,
to_py,
js_resources
)
from itkwasm import (
InterfaceTypes,
Image,
)

async def compare_images_async(
test_image: Image,
baseline_images: List[Image] = [],
difference_threshold: float = 0,
radius_tolerance: int = 0,
number_of_pixels_tolerance: int = 0,
ignore_boundary_pixels: bool = False,
) -> Tuple[Dict, Image, Image]:
"""Compare double pixel type images with a tolerance for regression testing.
:param test_image: The input test image
:type test_image: Image
:param baseline_images: Baseline images compare against
:type baseline_images: Image
:param difference_threshold: Intensity difference for pixels to be considered different.
:type difference_threshold: float
:param radius_tolerance: Radius of the neighborhood around a pixel to search for similar intensity values.
:type radius_tolerance: int
:param number_of_pixels_tolerance: Number of pixels that can be different before the test fails.
:type number_of_pixels_tolerance: int
:param ignore_boundary_pixels: Ignore boundary pixels. Useful when resampling may have introduced difference pixel values along the image edge.
:type ignore_boundary_pixels: bool
:return: Metrics for the baseline with the fewest number of pixels outside the tolerances.
:rtype: Dict
:return: Absolute difference image
:rtype: Image
:return: Unsigned char, 2D difference image for rendering
:rtype: Image
"""
js_module = await js_package.js_module
web_worker = js_resources.web_worker

kwargs = {}
if baseline_images is not None:
kwargs["baselineImages"] = to_js(baseline_images)
if difference_threshold:
kwargs["differenceThreshold"] = to_js(difference_threshold)
if radius_tolerance:
kwargs["radiusTolerance"] = to_js(radius_tolerance)
if number_of_pixels_tolerance:
kwargs["numberOfPixelsTolerance"] = to_js(number_of_pixels_tolerance)
if ignore_boundary_pixels:
kwargs["ignoreBoundaryPixels"] = to_js(ignore_boundary_pixels)

outputs = await js_module.compareImages(web_worker, to_js(test_image), **kwargs)

output_web_worker = None
output_list = []
outputs_object_map = outputs.as_object_map()
for output_name in outputs.object_keys():
if output_name == 'webWorker':
output_web_worker = outputs_object_map[output_name]
else:
output_list.append(to_py(outputs_object_map[output_name]))

js_resources.web_worker = output_web_worker

if len(output_list) == 1:
return output_list[0]
return tuple(output_list)
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@

@run_in_pyodide(packages=['micropip', 'numpy'])
async def test_compare_double_images_async(selenium, package_wheel, input_data):
import json

import micropip
await micropip.install(package_wheel, 'numpy', 'itkwasm')

Expand All @@ -34,4 +32,68 @@ async def test_compare_double_images_async(selenium, package_wheel, input_data):
assert metrics['meanDifference'] == 34.02259203227433

assert difference_image.imageType.componentType == 'float64'
assert difference_image_rendering.imageType.componentType == 'uint8'
assert difference_image_rendering.imageType.componentType == 'uint8'

@run_in_pyodide(packages=['micropip', 'numpy'])
async def test_compare_images_async(selenium, package_wheel, input_data):
import micropip
await micropip.install(package_wheel, 'numpy', 'itkwasm')

from itkwasm_compare_images_emscripten import compare_images_async
import numpy as np
from itkwasm import Image
from itkwasm.pyodide import to_js as itkwasm_to_js

test_image_file = 'cake_easy.iwi.cbor'
test_image = Image(**input_data[test_image_file])

baseline_image_file = 'cake_hard.iwi.cbor'
baseline_image = Image(**input_data[baseline_image_file])

metrics, difference_image, difference_image_rendering = await compare_images_async(test_image, baseline_images=[baseline_image])

assert metrics['almostEqual'] == False
assert metrics['numberOfPixelsWithDifferences'] == 9915
assert metrics['minimumDifference'] == 1.0
assert metrics['maximumDifference'] == 107.0
assert metrics['totalDifference'] == 337334.0
assert metrics['meanDifference'] == 34.02259203227433

assert difference_image.imageType.componentType == 'float64'
assert difference_image_rendering.imageType.componentType == 'uint8'

test_image_file = 'cake_easy.png'
test_image = Image(**input_data[test_image_file])

baseline_image_file = 'cake_hard.png'
baseline_image = Image(**input_data[baseline_image_file])

metrics, difference_image, difference_image_rendering = await compare_images_async(test_image, baseline_images=[baseline_image])

assert metrics['almostEqual'] == False
assert metrics['numberOfPixelsWithDifferences'] == 9915
assert metrics['minimumDifference'] == 1.0
assert metrics['maximumDifference'] == 107.0
assert metrics['totalDifference'] == 337334.0
assert metrics['meanDifference'] == 34.02259203227433

assert difference_image.imageType.componentType == 'float64'
assert difference_image_rendering.imageType.componentType == 'uint8'

test_image_file = 'apple.jpg'
test_image = Image(**input_data[test_image_file])

baseline_image_file = 'orange.jpg'
baseline_image = Image(**input_data[baseline_image_file])

metrics, difference_image, difference_image_rendering = await compare_images_async(test_image, baseline_images=[baseline_image])

assert metrics['almostEqual'] == False
assert metrics['numberOfPixelsWithDifferences'] == 26477
assert metrics['minimumDifference'] == 0.002273026683894841
assert metrics['maximumDifference'] == 312.2511648746159
assert metrics['totalDifference'] == 3121656.100202402
assert metrics['meanDifference'] == 117.90067228924735

assert difference_image.imageType.componentType == 'float64'
assert difference_image_rendering.imageType.componentType == 'uint8'

0 comments on commit 9b20e09

Please sign in to comment.