Get perpendicular lines to the input lines starting from the line midpoints.
Parameters:
Name |
Type |
Description |
Default |
lines |
GeoDataFrame
|
GeoDataFrame of the input lines.
|
required
|
polygon |
Polygon
|
Polygon to clip the perpendicular lines to.
|
None
|
Returns:
Type |
Description |
GeoDataFrame
|
gpd.GeoDataFrame:
GeoDataFrame of the perpendicular lines.
|
Source code in cellseg_gsontools/lines.py
| def perpendicular_lines(
lines: gpd.GeoDataFrame, polygon: shapely.Polygon = None
) -> gpd.GeoDataFrame:
"""Get perpendicular lines to the input lines starting from the line midpoints.
Parameters:
lines (gpd.GeoDataFrame):
GeoDataFrame of the input lines.
polygon (shapely.Polygon):
Polygon to clip the perpendicular lines to.
Returns:
gpd.GeoDataFrame:
GeoDataFrame of the perpendicular lines.
"""
# create perpendicular lines to the medial lines
if polygon is None:
polygon = lines.unary_union.convex_hull
seg_len = major_axis_len(polygon)
func = partial(perpendicular_line, seg_length=seg_len)
perp_lines = gdf_apply(lines, func, columns=["geometry"])
# clip the perpendicular lines to the polygon
perp_lines = gpd.GeoDataFrame(perp_lines, columns=["geometry"]).clip(polygon)
# explode perpendicular lines & take only the ones that intersect w/ medial lines
perp_lines = perp_lines.explode(index_parts=False).reset_index(drop=True)
# drop the perpendicular lines that are too short or too long
# since these are likely artefacts
perp_lines["len"] = perp_lines.geometry.length
low, high = perp_lines.len.quantile([0.05, 0.85])
perp_lines = perp_lines.query(f"{low}<len<{high}")
return perp_lines
|