diff --git a/python/cucim/src/cucim/core/operations/color/stain_normalizer.py b/python/cucim/src/cucim/core/operations/color/stain_normalizer.py index a58d26bc7..3b2ec3298 100644 --- a/python/cucim/src/cucim/core/operations/color/stain_normalizer.py +++ b/python/cucim/src/cucim/core/operations/color/stain_normalizer.py @@ -57,7 +57,7 @@ def image_to_absorbance(image, source_intensity=255.0, dtype=cp.float32): "Source transmitted light intensity must be a positive value." ) source_intensity = float(source_intensity) - if input_dtype == "f": + if input_dtype.kind == "f": min_val = source_intensity / 255.0 max_val = source_intensity else: diff --git a/python/cucim/tests/unit/core/test_stain_normalizer.py b/python/cucim/tests/unit/core/test_stain_normalizer.py index 724135cf0..0e3f539e1 100644 --- a/python/cucim/tests/unit/core/test_stain_normalizer.py +++ b/python/cucim/tests/unit/core/test_stain_normalizer.py @@ -6,11 +6,31 @@ import pytest from cucim.core.operations.color import ( + image_to_absorbance, normalize_colors_pca, stain_extraction_pca, ) +class TestImageToAbsorbance: + @pytest.mark.parametrize("dtype", [cp.float32, cp.float64]) + def test_should_clip_normalized_float_input_if_dtype_is_float(self, dtype): + image = cp.asarray( + [0.0, 1.0 / 510.0, 1.0 / 255.0, 0.5, 1.5], + dtype=dtype, + ) + + result = image_to_absorbance( + image, + source_intensity=1.0, + dtype=dtype, + ) + expected = -cp.log(cp.clip(image, 1.0 / 255.0, 1.0)) + + assert result.dtype == cp.dtype(dtype) + cp.testing.assert_allclose(result, expected, rtol=1e-6, atol=1e-6) + + class TestStainExtractorMacenko: @pytest.mark.parametrize( "image, ErrorClass",