Skip to content

Color Conversion

Class representing a color conversion between stain space and RGB space.

Source code in rationai/staining/color_conversion.py
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
class ColorConversion:
    """Class representing a color conversion between stain space and RGB space."""

    def __init__(
        self,
        conversion_matrix: StainTupleMatrix,
        conversion_direction: ConversionDirection,
    ):
        """Initializes a ColorConversion instance.

        Args:
            conversion_matrix: Matrix defining the color conversion.
            conversion_direction: Direction of the conversion.
        """
        self._matrix = conversion_matrix
        self._direction = conversion_direction
        self._matrix_array = cast("StainArray", np.stack(self._matrix))

    def __repr__(self) -> str:
        return f"ColorConversion(direction={self.direction.name}, matrix_shape={np.shape(self._matrix)})"

    @property
    def matrix(self) -> StainArray:
        """Returns the conversion matrix in a form of a numpy array."""
        return self._matrix_array

    @property
    def direction(self) -> ConversionDirection:
        """Returns the conversion direction."""
        return self._direction

    @property
    def inverse(self) -> "ColorConversion":
        """Returns the inverse of the current color conversion."""
        inv_matrix = inv_mat(self._matrix, round_result=True)
        inv_direction = self.direction.inverse

        return ColorConversion(inv_matrix, inv_direction)

    @staticmethod
    def from_stain_vectors(
        stain1: StainTuple,
        stain2: StainTuple,
        stain3: StainTuple | None = None,
        conversion_direction: ConversionDirection = ConversionDirection.RGB2STAIN,
    ) -> "ColorConversion":
        """Creates a `ColorConversion` instance from the given stain vectors.

        The provided stain vectors are **assumed to be in stain space**.
        This allows to specify the stain vectors in the same format as they are detected
        by the `estimate_stain_vectors` function, making it more convenient to create custom
        color conversions from reference images.

        Args:
            stain1: First stain vector.
            stain2: Second stain vector.
            stain3: Optional third stain vector. If not provided, it will be computed
                as the residual vector orthogonal to the first two.
            conversion_direction: Desired conversion direction of the resulting `ColorConversion` instance.

        Returns:
            `ColorConversion` instance with the specified direction.
        """
        stain3 = stain3 or residual(stain1, stain2)
        conversion = ColorConversion(
            (stain1, stain2, stain3), ConversionDirection.STAIN2RGB
        )

        match conversion_direction:
            case ConversionDirection.STAIN2RGB:
                return conversion

            case ConversionDirection.RGB2STAIN:
                return conversion.inverse

direction property

Returns the conversion direction.

inverse property

Returns the inverse of the current color conversion.

matrix property

Returns the conversion matrix in a form of a numpy array.

__init__(conversion_matrix, conversion_direction)

Initializes a ColorConversion instance.

Parameters:

Name Type Description Default
conversion_matrix StainTupleMatrix

Matrix defining the color conversion.

required
conversion_direction ConversionDirection

Direction of the conversion.

required
Source code in rationai/staining/color_conversion.py
32
33
34
35
36
37
38
39
40
41
42
43
44
45
def __init__(
    self,
    conversion_matrix: StainTupleMatrix,
    conversion_direction: ConversionDirection,
):
    """Initializes a ColorConversion instance.

    Args:
        conversion_matrix: Matrix defining the color conversion.
        conversion_direction: Direction of the conversion.
    """
    self._matrix = conversion_matrix
    self._direction = conversion_direction
    self._matrix_array = cast("StainArray", np.stack(self._matrix))

__repr__()

Source code in rationai/staining/color_conversion.py
47
48
def __repr__(self) -> str:
    return f"ColorConversion(direction={self.direction.name}, matrix_shape={np.shape(self._matrix)})"

from_stain_vectors(stain1, stain2, stain3=None, conversion_direction=ConversionDirection.RGB2STAIN) staticmethod

Creates a ColorConversion instance from the given stain vectors.

The provided stain vectors are assumed to be in stain space. This allows to specify the stain vectors in the same format as they are detected by the estimate_stain_vectors function, making it more convenient to create custom color conversions from reference images.

Parameters:

Name Type Description Default
stain1 StainTuple

First stain vector.

required
stain2 StainTuple

Second stain vector.

required
stain3 StainTuple | None

Optional third stain vector. If not provided, it will be computed as the residual vector orthogonal to the first two.

None
conversion_direction ConversionDirection

Desired conversion direction of the resulting ColorConversion instance.

RGB2STAIN

Returns:

Type Description
ColorConversion

ColorConversion instance with the specified direction.

Source code in rationai/staining/color_conversion.py
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
@staticmethod
def from_stain_vectors(
    stain1: StainTuple,
    stain2: StainTuple,
    stain3: StainTuple | None = None,
    conversion_direction: ConversionDirection = ConversionDirection.RGB2STAIN,
) -> "ColorConversion":
    """Creates a `ColorConversion` instance from the given stain vectors.

    The provided stain vectors are **assumed to be in stain space**.
    This allows to specify the stain vectors in the same format as they are detected
    by the `estimate_stain_vectors` function, making it more convenient to create custom
    color conversions from reference images.

    Args:
        stain1: First stain vector.
        stain2: Second stain vector.
        stain3: Optional third stain vector. If not provided, it will be computed
            as the residual vector orthogonal to the first two.
        conversion_direction: Desired conversion direction of the resulting `ColorConversion` instance.

    Returns:
        `ColorConversion` instance with the specified direction.
    """
    stain3 = stain3 or residual(stain1, stain2)
    conversion = ColorConversion(
        (stain1, stain2, stain3), ConversionDirection.STAIN2RGB
    )

    match conversion_direction:
        case ConversionDirection.STAIN2RGB:
            return conversion

        case ConversionDirection.RGB2STAIN:
            return conversion.inverse