Buckets:
| """Render train-only DOTA review-queue candidates for manual adjudication.""" | |
| import argparse | |
| import json | |
| from pathlib import Path | |
| from PIL import Image, ImageDraw | |
| from load_dataset import dataset, load_sample | |
| from training.model_factory import ROOT | |
| NAMES = {"3": "bridge", "4": "vehicle", "5": "large_vehicle", "6": "aircraft", | |
| "7": "vessel", "8": "storage_tank"} | |
| def draw_polygon(draw, points, color, width=3): | |
| vertices = list(zip(points[::2], points[1::2])) | |
| draw.line(vertices + vertices[:1], fill=color, width=width) | |
| def main(): | |
| parser = argparse.ArgumentParser() | |
| parser.add_argument("queue", type=Path) | |
| parser.add_argument("output_dir", type=Path) | |
| args = parser.parse_args() | |
| if args.output_dir.exists(): | |
| raise FileExistsError("output directory already exists") | |
| queue = json.loads(args.queue.read_text())["candidates"] | |
| data = dataset(ROOT / "datasets/corpus", "detection", "train", license_scope="all") | |
| samples = {row["id"]: row for row in data.samples} | |
| args.output_dir.mkdir(parents=True) | |
| for class_id, records in queue.items(): | |
| panels = [] | |
| for record in records: | |
| sample = load_sample(data.root, samples[record["sample_id"]], data.expected_hashes) | |
| image = Image.fromarray(sample["image"]).convert("RGB") | |
| draw = ImageDraw.Draw(image) | |
| for target in sample["annotations"]: | |
| x0, y0 = sample["metadata"]["tile_coordinates"][:2] | |
| local = [value - (x0 if index % 2 == 0 else y0) | |
| for index, value in enumerate(target["obb_polygon"])] | |
| draw_polygon(draw, local, "#25d366", 2) | |
| draw_polygon(draw, record["obb_polygon"], "#ffd600", 5) | |
| image.thumbnail((320, 320)) | |
| panel = Image.new("RGB", (336, 360), "black") | |
| panel.paste(image, (8, 32)) | |
| ImageDraw.Draw(panel).text((8, 8), f"{NAMES[class_id]} conf={record['confidence']:.3f}\n{record['sample_id']}", fill="white") | |
| panels.append(panel) | |
| columns, rows = 4, (len(panels) + 3) // 4 | |
| sheet = Image.new("RGB", (columns * 336, rows * 360), "black") | |
| for index, panel in enumerate(panels): | |
| sheet.paste(panel, ((index % columns) * 336, (index // columns) * 360)) | |
| sheet.save(args.output_dir / f"{NAMES[class_id]}.jpg") | |
| print(json.dumps({"output_dir": str(args.output_dir), "classes": list(queue)})) | |
| if __name__ == "__main__": | |
| main() | |
Xet Storage Details
- Size:
- 2.5 kB
- Xet hash:
- c3de53050cee093479d1d2b214085d67a515705e7aed3b8939c45e5bcd112d89
·
Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.