Buckets:
| """Create a blank, reviewer-ready annotation package from a non-eligible pilot.""" | |
| from __future__ import annotations | |
| import argparse | |
| import hashlib | |
| import json | |
| from pathlib import Path | |
| CLASSES = ( | |
| "bridge", "vehicle", "large_vehicle", "aircraft", "vessel", "storage_tank", | |
| ) | |
| def sha256(path: Path) -> str: | |
| return hashlib.sha256(path.read_bytes()).hexdigest() | |
| def main() -> None: | |
| parser = argparse.ArgumentParser() | |
| parser.add_argument("--pilot-manifest", type=Path, required=True) | |
| parser.add_argument("--output", type=Path, required=True) | |
| args = parser.parse_args() | |
| pilot = json.loads(args.pilot_manifest.read_text()) | |
| if pilot.get("status") != "label_free_provenance_pilot": | |
| raise ValueError("annotation package requires a label-free pilot") | |
| scenes = [] | |
| for record in pilot.get("records", []): | |
| if record.get("role") != "unassigned_pilot": | |
| raise ValueError(f"scene role is no longer unassigned: {record.get('id')}") | |
| if record.get("training_eligible") or record.get("final_test_eligible"): | |
| raise ValueError(f"scene eligibility changed: {record.get('id')}") | |
| image = Path(record["image"]) | |
| if sha256(image) != record["sha256"]: | |
| raise ValueError(f"image hash mismatch: {image}") | |
| scenes.append({ | |
| "scene_id": record["id"], | |
| "group": record["group"], | |
| "image": record["image"], | |
| "image_sha256": record["sha256"], | |
| "primary_annotator": None, | |
| "independent_reviewer": None, | |
| "annotation_status": "NOT_STARTED", | |
| "review_status": "NOT_STARTED", | |
| "objects": [], | |
| "ignored_regions": [], | |
| "review_notes": [], | |
| }) | |
| if len(scenes) != 6: | |
| raise ValueError("expected exactly six pilot scenes") | |
| package = { | |
| "schema_version": "1.0.0", | |
| "purpose": "Blank primary-annotation and independent-review handoff; no scene is eligible for any role.", | |
| "pilot_manifest": str(args.pilot_manifest), | |
| "pilot_manifest_sha256": sha256(args.pilot_manifest), | |
| "classes": list(CLASSES), | |
| "geometry": { | |
| "format": "ordered_oriented_box", | |
| "coordinates": "source-image pixels; four ordered [x, y] vertices", | |
| "minimum_fields": ["class", "vertices", "annotator", "annotation_version"], | |
| }, | |
| "independence_requirements": [ | |
| "Primary annotator and independent reviewer must be different people or separately accountable organizations.", | |
| "Reviewer must inspect whole scenes and model-independent regions, not only candidate predictions.", | |
| "No scene may be assigned a training, development, calibration, or final-test role until provenance, overlap, exposure, annotation, and review gates all pass.", | |
| "These blank objects are not negative labels; natural background may be declared only after whole-scene annotation and review.", | |
| ], | |
| "scenes": scenes, | |
| } | |
| if args.output.exists(): | |
| raise FileExistsError(args.output) | |
| args.output.parent.mkdir(parents=True, exist_ok=True) | |
| args.output.write_text(json.dumps(package, indent=2) + "\n") | |
| print(json.dumps({"output": str(args.output), "scenes": len(scenes), "sha256": sha256(args.output)})) | |
| if __name__ == "__main__": | |
| main() | |
Xet Storage Details
- Size:
- 3.38 kB
- Xet hash:
- 32d8a5dac6507d8616befeb61e7d6b48fc7b4478b983cbca775a8d9976bbf8bd
·
Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.