Skip to content

folding

Creates a binary mask of folding artifacts.

Parameters:

Name Type Description Default
img RGBImage

RGB image of the tissue.

required
mpp float

Number of microns per pixel of image.

required
hematoxylin_eosin_stained bool

True if image is stained using Hematoxylin and Eosin.

required
tissue_mask BinaryMask

A mask, where the tissue is labeled 1 and the background 0, should be as pixel-precise as possible.

required
local_tiles RGBImage | None

A local area surrounding the given tile.

None
local_mask BinaryMask | None

Tissue mask of local_tiles.

None
cell_nucleus_size float

Cell nucleus size in microns. This value is used for morphological operations. If estimating the value, it is better to overestimate the value. The default value is 7 based on empirical observations.

7

Returns:

Type Description
FoldArtifacts

Dictionary with a binary mask of folds.

Note

The returned dictionary contains the following values:

Key Description
folding Binary mask of the detected folds.
thresholded_saturation
thresholded_value
thresholded_eosin

Examples:

from skimage.data import immunohistochemistry

from rationai.qc import folding


img = immunohistochemistry()
tissue_mask = function_for_tissue_mask(img)

result = folding(img, 8, False, tissue_mask)

mask = result["folding"]  # Contains values 0 and 1

Source code in rationai/qc/folding/folding.py
 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
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
def folding(
    img: RGBImage,
    mpp: float,
    hematoxylin_eosin_stained: bool,
    tissue_mask: BinaryMask,
    local_tiles: RGBImage | None = None,
    local_mask: BinaryMask | None = None,
    cell_nucleus_size: float = 7,
) -> FoldArtifacts:
    """Creates a binary mask of folding artifacts.

    Args:
        img: RGB image of the tissue.
        mpp: Number of microns per pixel of image.
        hematoxylin_eosin_stained: True if image is stained using Hematoxylin and Eosin.
        tissue_mask: A mask, where the tissue is labeled 1 and the background 0,
            should be as pixel-precise as possible.
        local_tiles: A local area surrounding the given tile.
        local_mask: Tissue mask of local_tiles.
        cell_nucleus_size: Cell nucleus size in microns. This value is used for morphological operations.
            If estimating the value, it is better to overestimate the value.
            The default value is 7 based on empirical observations.

    Returns:
        Dictionary with a binary mask of folds.

    Note:
        The returned dictionary contains the following values:

        | Key                       | Description                           |
        |---------------------------|---------------------------------------|
        | `folding`                 | Binary mask of the detected folds.    |
        | `thresholded_saturation`  |                                       |
        | `thresholded_value`       |                                       |
        | `thresholded_eosin`       |                                       |

    Examples:
    ```python
    from skimage.data import immunohistochemistry

    from rationai.qc import folding


    img = immunohistochemistry()
    tissue_mask = function_for_tissue_mask(img)

    result = folding(img, 8, False, tissue_mask)

    mask = result["folding"]  # Contains values 0 and 1
    ```

    """
    tile = img
    hsv_tile = rgb2hsv(tile)
    saturation_channel, value_channel = hsv_tile[:, :, 1], hsv_tile[:, :, 2]
    local_saturation_channel, local_value_channel, local_eosin_channel = (
        None,
        None,
        None,
    )
    if local_tiles is not None:
        hsv_local = rgb2hsv(local_tiles)
        local_saturation_channel, local_value_channel = (
            hsv_local[:, :, 1],
            hsv_local[:, :, 2],
        )
        local_value_channel = 1 - local_value_channel
    if hematoxylin_eosin_stained:
        _, eosin_channel, _ = convert_color(tile, ColorConversion.RGB2HER)
        if local_tiles is not None:
            _, local_eosin_channel, _ = convert_color(
                local_tiles, ColorConversion.RGB2HER
            )
    else:
        eosin_channel = np.ones_like(tissue_mask)
        if local_tiles is not None:
            local_eosin_channel = np.ones_like(local_tiles)

    inverted_value_channel = 1 - value_channel

    value_threshold = _get_threshold(
        inverted_value_channel, tissue_mask, local_value_channel, local_mask
    )
    saturation_threshold = _get_threshold(
        saturation_channel, tissue_mask, local_saturation_channel, local_mask
    )
    if hematoxylin_eosin_stained:
        eosin_threshold = _get_threshold(
            eosin_channel, tissue_mask, local_eosin_channel, local_mask
        )
    else:
        eosin_threshold = 0

    thresholded_saturation = saturation_channel > saturation_threshold
    thresholded_value = inverted_value_channel > value_threshold
    thresholded_eosin = eosin_channel > eosin_threshold

    if (
        np.sum(thresholded_value) * 2 > tile.size
        or np.sum(thresholded_saturation) * 2 > tile.size
        or (hematoxylin_eosin_stained and np.sum(thresholded_eosin) * 2 > tile.size)
    ):
        thresholded_value = np.zeros(tile.shape)

    folding_test_markers = binary_opening(
        thresholded_eosin & thresholded_saturation & thresholded_value,
        disk(cell_nucleus_size // (mpp)),
    )

    if hematoxylin_eosin_stained:
        folding_test = reconstruction(folding_test_markers, thresholded_eosin)
        result: FoldArtifacts = {
            "folding": folding_test,
            "thresholded_saturation": thresholded_saturation,
            "thresholded_eosin": thresholded_eosin,
            "thresholded_value": thresholded_value,
        }
        return result
    result: FoldArtifacts = {
        "folding": folding_test,
        "thresholded_saturation": thresholded_saturation,
        "thresholded_eosin": thresholded_eosin,
        "thresholded_value": thresholded_value,
    }
    return result