Skip to content

medial_lines

cellseg_gsontools.lines.medial_lines(polygon, n=None, delta=None, rm_branches=False)

Get the medial lines of a polygon using a voronoi diagram.

Parameters:

Name Type Description Default
polygon Polygon

Polygon to compute the medial lines of.

required
n int

Number of resampled points in the input polygon, defaults to None

None
delta float

Distance between resampled polygon points, defaults to None. Ignored if n is not None.

None
rm_branches bool

Whether to remove the branches of the medial lines, defaults to False.

False

Returns:

Type Description
GeoDataFrame

gpd.GeoDataFrame: GeoDataFrame of the medial lines.

Examples:

>>> import geopandas as gpd
>>> import shapely
>>> from cellseg_gsontools.lines import medial_lines
>>> from cellseg_gsontools.data import cervix_tissue
>>> tissues = cervix_tissue()
>>> tumor = tissues[tissues["class_name"] == "area_cin"]
>>> tumor_poly = tumor.geometry.iloc[0]  # get the first tumor polygon
>>> polygon = shapely.Polygon(tumor_poly.exterior)
>>> med_lines = medial_lines(polygon, delta=500, rm_branches=False)
>>> med_lines.head()
geometry
    0  LINESTRING (10789.887 49746.299, 10910.622 493...
    1  LINESTRING (10789.887 49746.299, 10926.865 498...
    2  LINESTRING (10924.971 48929.809, 10829.145 492...
    3  LINESTRING (10910.622 49332.471, 10829.145 492...
    4  LINESTRING (10926.865 49843.003, 10794.602 502...
Source code in cellseg_gsontools/lines.py
def medial_lines(
    polygon: shapely.Polygon,
    n: int = None,
    delta: float = None,
    rm_branches: bool = False,
) -> gpd.GeoDataFrame:
    """Get the medial lines of a polygon using a voronoi diagram.

    Parameters:
        polygon (shapely.Polygon):
            Polygon to compute the medial lines of.
        n (int):
            Number of resampled points in the input polygon, defaults to None
        delta (float):
            Distance between resampled polygon points, defaults to None. Ignored
            if n is not None.
        rm_branches (bool):
            Whether to remove the branches of the medial lines, defaults to False.

    Returns:
        gpd.GeoDataFrame:
            GeoDataFrame of the medial lines.

    Examples:
        >>> import geopandas as gpd
        >>> import shapely
        >>> from cellseg_gsontools.lines import medial_lines
        >>> from cellseg_gsontools.data import cervix_tissue
        >>> tissues = cervix_tissue()
        >>> tumor = tissues[tissues["class_name"] == "area_cin"]
        >>> tumor_poly = tumor.geometry.iloc[0]  # get the first tumor polygon
        >>> polygon = shapely.Polygon(tumor_poly.exterior)
        >>> med_lines = medial_lines(polygon, delta=500, rm_branches=False)
        >>> med_lines.head()
        geometry
            0  LINESTRING (10789.887 49746.299, 10910.622 493...
            1  LINESTRING (10789.887 49746.299, 10926.865 498...
            2  LINESTRING (10924.971 48929.809, 10829.145 492...
            3  LINESTRING (10910.622 49332.471, 10829.145 492...
            4  LINESTRING (10926.865 49843.003, 10794.602 502...
    """
    # get the medial lines
    vertices, edges = voronoi_medial(polygon, n=n, delta=delta)

    # remove lone branches of the medial lines
    if rm_branches:
        # get the line paths and branches of the medial lines
        paths = line_branches(edges)
        edges = np.vstack(
            [
                np.array(list(zip(branch, branch[1:])))
                for branch in paths
                if len(branch) > 2
            ]
        )

    med_lines = gpd.GeoDataFrame(
        [shapely.LineString(vertices[line]) for line in edges], columns=["geometry"]
    )
    # clip the medial lines to the polygon
    med_lines = med_lines.loc[med_lines.within(polygon)]

    return med_lines