SBU-BMI / wsinfer

🔥 🚀 Blazingly fast pipeline for patch-based classification in whole slide images
https://wsinfer.readthedocs.io
Apache License 2.0
56 stars 10 forks source link

accept a ROI as a geojson #108

Closed kaczmarj closed 1 year ago

kaczmarj commented 1 year ago

use case here is in qupath. one would be in qupath and would annotate a region of interest. this roi would be run by wsinfer.

the roi would be encoded as geojson. we can check if the patches overlap with the ROI and apply the model to those patches.

kaczmarj commented 1 year ago

the ROI would be in geojson format. it could include multiple regions potentially. here's a tentative plan:

  1. encode the ROI as a shapely polygon.
  2. encode all of the patches as shapely polygons (boxes).
  3. use shapely STRTree to find patches that intersect with the ROI.
  4. keep the patches that intersect and throw away patches that do not.
  5. save those patches and carry on!
def get_patches_in_rois(geojson_path: str, coords: np.ndarray, patch_size: int):
    with open(geojson_path) as f:
        geo = geojson.load(f)
    num_rois = len(geo["features"])
    print(f"Processing {num_rois} rois")
    for roi in geo["features"]:
        assert roi.is_valid, "an ROI geometry is not valid"
    # Each geom is a shapely Polygon type.
    geoms_rois = [shape(roi["geometry"]) for roi in geo["features"]]
    boxes = [box(x, y, x+patch_size, y+patch_size) for x, y in coords]
    tree = shapely.STRtree(boxes)
    _, intersecting_ids = tree.query([geom, geom], predicate="intersects")
    intersecting_ids = np.sort(np.unique(intersecting_ids))
    return coords[intersecting_ids]
kaczmarj commented 1 year ago

it works!

image