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.
This commit is contained in:
@@ -0,0 +1,51 @@
|
||||
"""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)
|
||||
Reference in New Issue
Block a user