Hsyshasuzh/longmemory-geo / project /evaluation /render_kfgod_source_review_queue.py
Hsyshasuzh's picture
download
raw
2.59 kB
"""Render target-centered, source-label review sheets for the KFGOD audit queue."""
from __future__ import annotations
import argparse
import json
from math import ceil
from pathlib import Path
from PIL import Image, ImageDraw
def crop_bounds(vertices: list[list[float]], width: int, height: int) -> tuple[int, int, int, int]:
xs, ys = zip(*vertices)
side = max(256, max(xs) - min(xs), max(ys) - min(ys)) * 2.2
side = min(768, side)
cx, cy = (min(xs) + max(xs)) / 2, (min(ys) + max(ys)) / 2
left = max(0, min(width - side, cx - side / 2))
top = max(0, min(height - side, cy - side / 2))
return round(left), round(top), round(left + side), round(top + side)
def main() -> None:
parser = argparse.ArgumentParser()
parser.add_argument("--queue", type=Path, required=True)
parser.add_argument("--output-dir", type=Path, required=True)
args = parser.parse_args()
queue = json.loads(args.queue.read_text())
records = queue["records"]
columns, rows, cell = 4, 4, 320
header = 38
args.output_dir.mkdir(parents=True, exist_ok=True)
for page_index in range(ceil(len(records) / (columns * rows))):
page_records = records[page_index * columns * rows:(page_index + 1) * columns * rows]
sheet = Image.new("RGB", (columns * cell, rows * (cell + header)), "white")
draw = ImageDraw.Draw(sheet)
for index, record in enumerate(page_records):
with Image.open(record["image"]) as image:
image = image.convert("RGB")
bounds = crop_bounds(record["vertices"], image.width, image.height)
crop = image.crop(bounds)
scale_x, scale_y = cell / crop.width, cell / crop.height
crop = crop.resize((cell, cell))
crop_draw = ImageDraw.Draw(crop)
polygon = [((x - bounds[0]) * scale_x, (y - bounds[1]) * scale_y) for x, y in record["vertices"]]
crop_draw.line(polygon + [polygon[0]], fill=(0, 220, 0), width=3)
x = (index % columns) * cell
y = (index // columns) * (cell + header)
sheet.paste(crop, (x, y + header))
draw.text((x + 6, y + 6), f"{record['canonical_class']} / {record['source_label']}", fill="black")
draw.text((x + 6, y + 20), f"{record['scene_id']} #{record['object_index']}", fill="black")
sheet.save(args.output_dir / f"page-{page_index + 1:02d}.jpg", "JPEG", quality=92)
print(json.dumps({"records": len(records), "pages": ceil(len(records) / (columns * rows))}))
if __name__ == "__main__":
main()

Xet Storage Details

Size:
2.59 kB
·
Xet hash:
4a42aca9466c994b1a917f9eb2ca6d3517b1b1e955101746f1469aac8b6474c2

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