diff --git a/lib/galaxy/tool_util/verify/asserts/image.py b/lib/galaxy/tool_util/verify/asserts/image.py
index 76ff0425da9..622758395e9 100644
--- a/lib/galaxy/tool_util/verify/asserts/image.py
+++ b/lib/galaxy/tool_util/verify/asserts/image.py
@@ -2,7 +2,8 @@ import io
from typing import (
Optional,
Union,
- List
+ List,
+ Tuple,
)
import numpy
@@ -32,6 +33,53 @@ def assert_image_has_metadata(
f"Image has wrong number of channels: {actual_channels} (expected {int(channels)})"
+def _compute_center_of_mass(im_arr):
+ while im_arr.ndim > 2:
+ im_arr = im_arr.sum(axis=2)
+ im_arr = numpy.abs(im_arr)
+ if im_arr.sum() == 0:
+ return (numpy.nan, numpy.nan)
+ im_arr = im_arr / im_arr.sum()
+ yy, xx = numpy.indices(im_arr.shape)
+ return (im_arr * xx).sum(), (im_arr * yy).sum()
+
+
+def assert_image_has_intensities(
+ output_bytes: bytes,
+ channel: Optional[Union[int, str]] = None,
+ mean_intensity: Optional[Union[float, str]] = None,
+ center_of_mass: Optional[Union[Tuple[float], str]] = None,
+ eps: Optional[Union[float, str]] = 1e-8,
+) -> None:
+ """
+ Assert the image output has specific intensity content.
+ """
+ buf = io.BytesIO(output_bytes)
+ with Image.open(buf) as im:
+ im_arr = numpy.array(im)
+
+ # Select the specified channel (if any).
+ if channel is not None:
+ im_arr = im_arr[:, :, channel]
+
+ # Perform `mean_intensity` assertion.
+ if mean_intensity is not None:
+ actual = im_arr.mean()
+ expected = float(mean_intensity)
+ assert abs(actual - expected) <= float(eps), \
+ f"Wrong mean intensity: {actual} (expected {expected})"
+
+ # Perform `center_of_mass` assertion.
+ if center_of_mass is not None:
+ if isinstance(center_of_mass, str):
+ center_of_mass = [float(c.strip()) for c in center_of_mass.split(",")]
+ assert len(center_of_mass) == 2, "center_of_mass must have two components"
+ actual = _compute_center_of_mass(im_arr)
+ distance = numpy.linalg.norm(numpy.subtract(center_of_mass, expected))
+ assert distance <= float(eps), \
+ f"Wrong center of mass: {actual} (expected {center_of_mass})"
+
+
def assert_image_has_labels(
output_bytes: bytes,
number_of_objects: Optional[Union[int, str]] = None,
diff --git a/test/functional/tools/validation_image.xml b/test/functional/tools/validation_image.xml
index 23cc130136b..7a0c561426a 100644
--- a/test/functional/tools/validation_image.xml
+++ b/test/functional/tools/validation_image.xml
@@ -14,7 +14,7 @@
@@ -23,6 +23,25 @@
+
+
+
+
+
+
+
+