Files
mohamad bcaae5ec22 feat: initialize standalone image-filter
Rename the distribution to image-filter and imports to image_filter.
Keep medical fixtures local and document their setup for fresh clones.
Include composite pipelines, consistent examples, and class diagrams.
2026-09-10 01:58:07 +03:30

52 lines
2.3 KiB
Python

"""Composite behavior: substitution, ordering, metadata, and adapters."""
import json
import numpy as np
import pytest
from image_filter import (
CannyFilter, GaussianFilter, ImageFilter, ImageItem, InvalidConfigurationError,
MeanFilter, Pipeline, SliceWise, SobelFilter, UnsupportedDimensionError,
)
def test_nested_pipeline_matches_explicit_execution_and_preserves_metadata():
image = np.arange(120, dtype=float).reshape(10, 12)
metadata = {"patient": {"label": "test"}}
first, second, third = MeanFilter(3), GaussianFilter(0.8), SobelFilter()
operation = Pipeline([Pipeline([first, second]), third])
assert isinstance(operation, ImageFilter)
result = operation.apply(image, metadata)
expected = third.apply(second.apply(first.apply(image).image).image)
np.testing.assert_array_equal(result.image, expected.image)
assert [x["filter"] for x in result.metadata["processing_history"]] == [
"MeanFilter", "GaussianFilter", "SobelFilter",
]
assert metadata == {"patient": {"label": "test"}}
assert result.metadata["patient"] is not metadata["patient"]
np.testing.assert_array_equal(image, np.arange(120).reshape(10, 12))
for component in (first, operation):
batch = component.apply_batch([ImageItem(image), ImageItem(image[None])])
np.testing.assert_array_equal(batch[0].image, batch[1].image[0])
def test_pipeline_in_slicewise_preserves_boolean_output_and_serializable_history():
volume = np.random.default_rng(12).random((10, 12, 5))
pipeline = Pipeline([GaussianFilter(0.8), CannyFilter(use_quantiles=True)])
result = SliceWise(pipeline, axis=2).apply(volume)
expected = np.stack([pipeline.apply(volume[:, :, i]).image for i in range(5)], axis=2)
np.testing.assert_array_equal(result.image, expected)
assert result.image.dtype == bool
json.dumps(dict(result.metadata))
assert pipeline.capabilities.spatial_dimensions == frozenset({2})
with pytest.raises(UnsupportedDimensionError):
pipeline.apply(volume)
def test_invalid_composites_fail_at_construction():
for steps in ([], [object()], [Pipeline([MeanFilter()]), "invalid"]):
with pytest.raises(InvalidConfigurationError):
Pipeline(steps)
with pytest.raises(InvalidConfigurationError):
SliceWise(object(), axis=0)