def pixelwise_vector_f1(gt: List[Polygon], pred: List[Polygon], v: bool = True): """ Measures pixelwise f1-score, but for vector representation instead of raster. :param gt: list of shapely Polygons, represents ground truth; :param pred: list of shapely Polygons or Points (according to the 'format' param, represents prediction; :param format: 'vector' or 'point', means format of prediction and corresponding variant of algorithm; :param v: is_verbose :return: float, f1-score and string, log """ log = '' gt_mp = MultiPolygon(gt) pred_mp = MultiPolygon(pred) # try making polygons valid gt_mp = gt_mp.buffer(0) pred_mp = pred_mp.buffer(0) tp = gt_mp.intersection(pred_mp).area fp = pred_mp.area - tp fn = gt_mp.area - tp if tp == 0: f1 = 0. else: precision = tp / (tp + fp) recall = tp / (tp + fn) f1 = 2 * (precision * recall) / (precision + recall) if v: log += 'True Positive = ' + str(tp) + ', False Negative = ' + str( fn) + ', False Positive = ' + str(fp) + '\n' return f1, log
def log_jaccard(im_id: str, cls: int, true_mask: np.ndarray, mask: np.ndarray, poly_mask: np.ndarray, true_poly: MultiPolygon, poly: MultiPolygon, valid_polygons=False): assert len(mask.shape) == 2 pixel_jc = utils.mask_tp_fp_fn(mask, true_mask, 0.5) if valid_polygons: if not true_poly.is_valid: true_poly = utils.to_multipolygon(true_poly.buffer(0)) if not poly.is_valid: poly = utils.to_multipolygon(poly.buffer(0)) tp = true_poly.intersection(poly).area fn = true_poly.difference(poly).area fp = poly.difference(true_poly).area poly_jc = tp, fp, fn else: poly_jc = utils.mask_tp_fp_fn(poly_mask, true_mask, 0.5) logger.info( '{} cls-{} pixel jaccard: {:.5f}, polygon jaccard: {:.5f}'.format( im_id, cls, jaccard(pixel_jc), jaccard(poly_jc))) return pixel_jc, poly_jc
def X_and_Y_polygon(left: geometry.MultiPolygon, right: geometry.MultiPolygon) -> float: try: return left.intersection(right).area except TopologicalError: logger.error(f"Polygonal error") return 0
def calculate_intersection(gj, gj1): g1 = MultiPolygon( [shape(feature["geometry"]).buffer(0) for feature in gj['features']]) g2 = MultiLineString([ shape(feature["geometry"]) for feature in gj1['features'] if feature['geometry']['coordinates'] ]) return g1.intersection(g2)
def iou(target_bboxes, predicted_bboxes): target_polys = MultiPolygon([Polygon(i) for i in target_bboxes]).buffer(0) predicted_polys = MultiPolygon([Polygon(i) for i in predicted_bboxes]).buffer(0) intersection = target_polys.intersection(predicted_polys).area union = target_polys.union(predicted_polys).area try: return intersection / union except ZeroDivisionError as e: return 0
def test_intersection(): polygon1 = Polygon([(0, 0), (0, 2), (2, 2), (2, 0)]) polygon2 = Polygon([(1, 1), (1, 3), (3, 3), (3, 1)]) # assert polygon1.intersection(polygon2).bounds == (1.0, 1.0, 2.0, 2.0) # Make sure intersection of just one multi is itself multi1 = MultiPolygon([polygon1]) expected_inters = multi1 inters = intersection(multi1, None) _compare_multipolygons(inters, expected_inters) # Basic test of two overlapping multis multi2 = MultiPolygon([polygon2]) inters1 = intersection(multi1, multi2) expected_inters = MultiPolygon([Polygon([(1, 1), (1, 2), (2, 2), (2, 1)])]) _compare_multipolygons(inters1, expected_inters) # Make sure polys of a multi are unioned before intersection with other multi is taken # (verifies fix for GTC-1236) polygon4 = Polygon([(2, 2), (2, 4), (4, 4), (4, 2)]) multi3 = MultiPolygon([polygon1, polygon4]) inters2 = intersection(multi2, multi3) expected_inters = MultiPolygon( [ Polygon([(1, 1), (1, 2), (2, 2), (2, 1)]), Polygon([(2, 2), (2, 3), (3, 3), (3, 2)]), ] ) _compare_multipolygons(inters2, expected_inters) # Sometimes Shapely generates GeometryCollections because of funky intersections # (for example when polygons intersect on an edge but also overlap elsewhere) # Our intersection function should filter out extraneous bits so the result fits in # a MultiPolygon multi6 = MultiPolygon( [ Polygon([(0, 0), (0, 2), (1, 2), (1, 0)]).union( Polygon([(1, 0), (1, 1), (2, 1), (2, 0)]) ) ] ) multi7 = MultiPolygon([Polygon([(1, 0), (1, 2), (2, 2), (2, 0)])]) # This doesn't test OUR code, just making sure it does what I think it does geo_col = multi6.intersection(multi7) assert geo_col.type == "GeometryCollection" assert any(geo.type == "LineString" for geo in geo_col.geoms) # Now test our function inters3 = intersection(multi6, multi7) expected_inters = MultiPolygon([Polygon([(1, 0), (1, 1), (2, 1), (2, 0)])]) _compare_multipolygons(inters3, expected_inters)
def getRemovedBuildings(year, shed): watershed = shape(shed) with fiona.open('data/shp/buildings.shp') as b_source: print 'Filtering buildings to ' + str(year) buildings = MultiPolygon([ shape(b['geometry']) for b in b_source if b['properties']['FirstYear'] <= year and b['properties']['LastYear'] >= year ]) print 'Clipping buildings to watershed' buildings_shed = buildings.intersection(watershed) with fiona.open('data/shp/buildings_test2.shp', 'w', driver='ESRI Shapefile', schema=b_source.schema) as w: w.writerecords(buildings_shed)
def intersection(a: MultiPolygon, b: Optional[MultiPolygon]) -> MultiPolygon: if not b: geom: MultiPolygon = a else: _geom = a.intersection(b) # Sometimes the intersection results in a GeometryCollection and # includes things like LineStrings (like when two polygons both share # an edge and overlap elsewhere), which we don't care about. Filter # that stuff out to return a MultiPolygon. if _geom.type == "GeometryCollection": geom_pieces: List[Union[MultiPolygon, Polygon]] = list() for g in _geom.geoms: if g.type == "MultiPolygon" or g.type == "Polygon": geom_pieces.append(g) geom = unary_union(geom_pieces) else: geom = _geom if geom.type == "Polygon": geom = MultiPolygon([geom]) return geom
def is_subset_polygon(left: geometry.MultiPolygon, right: geometry.MultiPolygon) -> bool: area_union = left.union(right).area area_intersection = left.intersection(right).area area_left = left.area area_right = right.area result = math.isclose(area_intersection, area_right, abs_tol=0.03**2) jaccard_expected = (area_left - area_right) / area_left jaccard_actual = (area_union - area_intersection) / area_union if DEBUG: logger.debug(f"left, right -> {area_left}, {area_right}") logger.debug( f"Je = ({area_left:.2f} - {area_right:.2f}) / {area_left:.2f} = {jaccard_expected:.2f}" ) logger.debug( f"Ja = ({area_union:.2f} - {area_intersection:.2f}) / {area_union:.2f} = {jaccard_actual:.2f}" ) logger.debug(f"{jaccard_expected} == {jaccard_actual} -> {result}") result = math.isclose(jaccard_expected, jaccard_actual, abs_tol=0.1) return result
# first, calculate a bounding box to restrict the diagram min_x = min(stops_pts[:,0]) - 5000 max_x = max(stops_pts[:,0]) + 5000 min_y = min(stops_pts[:,1]) - 5000 max_y = max(stops_pts[:,1]) + 5000 bbox = np.array([[min_x,min_y], [max_x,max_y], [min_x,max_y], [max_x,min_y]]) # find the voronoi coords = np.vstack([stops_pts, bbox]) vor = Voronoi(coords) # rearrange, so that regions are in the same order as their corresponding # points, so the last four are the bbox dummy observations, and remove them regions = np.array(vor.regions)[vor.point_region] regions = regions[:-4] clipped = [] for region in regions: region_vertices = vor.vertices[region] region_polygon = Polygon(region_vertices) if nyc.intersects(region_polygon): clipped.append(nyc.intersection(region_polygon)) clipped = GeoSeries(clipped) stops = GeoDataFrame(stops) stops.index = np.arange(stops.shape[0]) stops['region'] = clipped pickle.dump(stops,open('save/stops.p','wb')) pickle.dump(nyc,open('save/nyc.p','wb'))
min_x = min(stops_pts[:, 0]) - 5000 max_x = max(stops_pts[:, 0]) + 5000 min_y = min(stops_pts[:, 1]) - 5000 max_y = max(stops_pts[:, 1]) + 5000 bbox = np.array([[min_x, min_y], [max_x, max_y], [min_x, max_y], [max_x, min_y]]) # find the voronoi coords = np.vstack([stops_pts, bbox]) vor = Voronoi(coords) # rearrange, so that regions are in the same order as their corresponding # points, so the last four are the bbox dummy observations, and remove them regions = np.array(vor.regions)[vor.point_region] regions = regions[:-4] clipped = [] for region in regions: region_vertices = vor.vertices[region] region_polygon = Polygon(region_vertices) if nyc.intersects(region_polygon): clipped.append(nyc.intersection(region_polygon)) clipped = GeoSeries(clipped) stops = GeoDataFrame(stops) stops.index = np.arange(stops.shape[0]) stops['region'] = clipped pickle.dump(stops, open('save/stops.p', 'wb')) pickle.dump(nyc, open('save/nyc.p', 'wb'))