Hsyshasuzh/longmemory-geo / project /evaluation /render_fullscene_bridge_errors.py
Hsyshasuzh's picture
download
raw
3.24 kB
"""Render native-resolution bridge FN/FP crops from full-scene development records."""
import argparse
import json
from pathlib import Path
import numpy as np
from PIL import Image, ImageDraw
from evaluation.locate_detection_errors import locate
from training.model_factory import ROOT
SCENES = ROOT / "datasets/external/dota-fullscene-dev/images"
def draw(draw, points, colour, offset):
vertices = [(x - offset[0], y - offset[1]) for x, y in zip(points[::2], points[1::2])]
if vertices:
draw.line(vertices + vertices[:1], fill=colour, width=4)
def main() -> None:
parser = argparse.ArgumentParser()
parser.add_argument("records", type=Path)
parser.add_argument("output", type=Path)
parser.add_argument("--per-kind", type=int, default=20)
parser.add_argument("--crop-size", type=int, default=1024)
args = parser.parse_args()
if args.output.exists():
raise FileExistsError("choose a fresh output directory")
data = json.loads(args.records.read_text())
bridge = locate(data)["3"]
targets = {row["sample_id"]: row["annotations"] for row in data["targets"]}
predictions = {row["sample_id"]: row["annotations"] for row in data["predictions"]}
args.output.mkdir(parents=True)
manifest = {"status": "PENDING_SOURCE_LABEL_REVIEW", "class": "bridge", "records": str(args.records),
"items": []}
for kind in ("false_positives", "missed_targets"):
for index, item in enumerate(bridge[kind][:args.per_kind]):
scene = item["sample_id"]
image_path = next(SCENES.rglob(scene + ".png"))
image = Image.open(image_path).convert("RGB")
points = np.asarray(item["obb_polygon"], dtype=float).reshape(-1, 2)
cx, cy = points.mean(axis=0)
left = max(0, min(round(cx - args.crop_size / 2), image.width - args.crop_size))
top = max(0, min(round(cy - args.crop_size / 2), image.height - args.crop_size))
crop = image.crop((left, top, left + args.crop_size, top + args.crop_size))
drawer = ImageDraw.Draw(crop)
for target in targets[scene]:
if target["category_id"] == 3:
draw(drawer, target["obb_polygon"], "#25d366", (left, top))
for prediction in predictions[scene]:
if prediction["category_id"] == 3:
draw(drawer, prediction["obb_polygon"], "#f44336", (left, top))
draw(drawer, item["obb_polygon"], "#ffd600", (left, top))
name = f"bridge-{kind}-{index:02d}-{scene}.jpg"
crop.save(args.output / name)
manifest["items"].append({"kind": kind, "scene_id": scene, "file": name,
"confidence": item.get("confidence"), "best_iou": item.get("best_iou"),
"crop_box": [left, top, left + args.crop_size, top + args.crop_size],
"review_status": "PENDING", "training_eligible": False})
(args.output / "manifest.json").write_text(json.dumps(manifest, indent=2) + "\n")
print(json.dumps({"items": len(manifest["items"]), "output": str(args.output)}))
if __name__ == "__main__":
main()

Xet Storage Details

Size:
3.24 kB
·
Xet hash:
5c0b8507eb5c21671895c06c309a5691b146b2a026a43f09e4caf1c9211ae00b

Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.