Skip to content

gdf2inst

Converts a GeoDataFrame to an instance segmentation raster mask.

Parameters:

Name Type Description Default
gdf GeoDataFrame

GeoDataFrame to convert to an instance segmentation mask.

required
xoff int

X offset. This is used to translate the geometries in the GeoDataFrame to burn the geometries in correctly to the raster mask.

0
yoff int

Y offset. This is used to translate the geometries in the GeoDataFrame to burn the geometries in correctly to the raster mask.

0
width int

Width of the output. This should match with the underlying image width. If None, the width will be calculated from the input gdf.

None
height int

Height of the output. This should match with the underlying image height. If None, the height will be calculated from the input gdf.

None
reset_index bool

Whether to reset the index of the output GeoDataFrame.

False

Returns:

Type Description
GeoDataFrame

np.ndarray: Instance segmentation mask of the input gdf. Shape (height, width).

Examples:

>>> from histolytics.data import hgsc_cancer_nuclei
>>> from histolytics.utils.raster import gdf2inst
>>> from skimage.measure import label
>>> from skimage.color import label2rgb
>>> import matplotlib.pyplot as plt
>>>
>>> nuc = hgsc_cancer_nuclei()
>>> # Convert the GeoDataFrame to an instance segmentation raster
>>> nuc_raster = gdf2inst(nuc, xoff=0, yoff=0, width=1500, height=1500)
>>> # Visualize the instance segmentation raster and the GeoDataFrame
>>> fig, ax = plt.subplots(1, 2, figsize=(8, 4))
>>> ax[0].imshow(label2rgb(label(nuc_raster), bg_label=0))
>>> ax[0].set_axis_off()
>>> nuc.plot(column="class_name", ax=ax[1])
>>> ax[1].set_axis_off()
>>> fig.tight_layout()

out

Source code in src/histolytics/utils/raster.py
def gdf2inst(
    gdf: gpd.GeoDataFrame,
    xoff: int = 0,
    yoff: int = 0,
    width: int = None,
    height: int = None,
    reset_index: bool = False,
) -> gpd.GeoDataFrame:
    """Converts a GeoDataFrame to an instance segmentation raster mask.

    Parameters:
        gdf (gpd.GeoDataFrame):
            GeoDataFrame to convert to an instance segmentation mask.
        xoff (int):
            X offset. This is used to translate the geometries in the GeoDataFrame to
            burn the geometries in correctly to the raster mask.
        yoff (int):
            Y offset. This is used to translate the geometries in the GeoDataFrame to
            burn the geometries in correctly to the raster mask.
        width (int):
            Width of the output. This should match with the underlying image width.
            If None, the width will be calculated from the input gdf.
        height (int):
            Height of the output. This should match with the underlying image height.
            If None, the height will be calculated from the input gdf.
        reset_index (bool):
            Whether to reset the index of the output GeoDataFrame.

    Returns:
        np.ndarray:
            Instance segmentation mask of the input gdf. Shape (height, width).

    Examples:
        >>> from histolytics.data import hgsc_cancer_nuclei
        >>> from histolytics.utils.raster import gdf2inst
        >>> from skimage.measure import label
        >>> from skimage.color import label2rgb
        >>> import matplotlib.pyplot as plt
        >>>
        >>> nuc = hgsc_cancer_nuclei()
        >>> # Convert the GeoDataFrame to an instance segmentation raster
        >>> nuc_raster = gdf2inst(nuc, xoff=0, yoff=0, width=1500, height=1500)
        >>> # Visualize the instance segmentation raster and the GeoDataFrame
        >>> fig, ax = plt.subplots(1, 2, figsize=(8, 4))
        >>> ax[0].imshow(label2rgb(label(nuc_raster), bg_label=0))
        >>> ax[0].set_axis_off()
        >>> nuc.plot(column="class_name", ax=ax[1])
        >>> ax[1].set_axis_off()
        >>> fig.tight_layout()
    ![out](../../img/gdf2inst.png)
    """
    xmin, ymin, xmax, ymax = gdf.total_bounds
    xoff = xoff - xmin
    yoff = yoff - ymin

    if width is None:
        width = int(xmax - xmin)
    if height is None:
        height = int(ymax - ymin)

    image_shape = (int(height), int(width))
    out_mask = np.zeros(image_shape, dtype=np.int32)
    for i, (ix, row) in enumerate(gdf.iterrows()):
        mask = geometry_mask(
            [shapely.affinity.translate(row.geometry, -xmin - xoff, -ymin - yoff)],
            out_shape=image_shape,
            transform=rasterio.Affine(1, 0, 0, 0, 1, 0),
            invert=True,
            all_touched=True,
        )
        if reset_index:
            out_mask[mask] = int(i + 1)
        else:
            out_mask[mask] = int(ix)

    return out_mask