smart-parking-api / src /parse_slots.py
rohanv56's picture
Upload 380 files
2d30bad verified
Raw
History Blame Contribute Delete
3.41 kB
import json
import os
from pathlib import Path
from collections import defaultdict
# ---------------------------------------------------------------------------
# Paths
# ---------------------------------------------------------------------------
RAW_DIR = Path(__file__).resolve().parents[1] / "data" / "raw"
TRAIN_DIR = RAW_DIR / "train"
COCO_FILE = TRAIN_DIR / "_annotations.coco.json"
OUTPUT = RAW_DIR / "slot_map.json"
# ---------------------------------------------------------------------------
# Loaders
# ---------------------------------------------------------------------------
def load_coco(path: Path) -> dict:
with open(path, "r") as f:
return json.load(f)
# ---------------------------------------------------------------------------
# Core logic
# ---------------------------------------------------------------------------
def build_slot_map(coco: dict) -> list[dict]:
"""
The parking lot camera is fixed, so every frame shows the same physical
slots. We pick the image that has the most annotations as our reference
frame (most complete view), extract each slot's bounding box, sort them
top-to-bottom then left-to-right, and assign stable slot_ids starting at 1.
"""
# Group annotation counts per image
ann_count: dict[int, int] = defaultdict(int)
ann_by_image: dict[int, list] = defaultdict(list)
for ann in coco["annotations"]:
iid = ann["image_id"]
ann_count[iid] += 1
ann_by_image[iid].append(ann)
# Pick reference image — the one with the most annotations
ref_image_id = max(ann_count, key=ann_count.get)
ref_image = next(img for img in coco["images"] if img["id"] == ref_image_id)
ref_anns = ann_by_image[ref_image_id]
print(f"Reference frame : {ref_image['file_name']}")
print(f"Slots in frame : {len(ref_anns)}")
# Sort slots: top-to-bottom (y), then left-to-right (x)
sorted_anns = sorted(ref_anns, key=lambda a: (round(a["bbox"][1] / 20), a["bbox"][0]))
slots = []
for idx, ann in enumerate(sorted_anns):
x, y, w, h = ann["bbox"]
slots.append({
"slot_id" : idx + 1,
"x" : round(x, 2),
"y" : round(y, 2),
"w" : round(w, 2),
"h" : round(h, 2),
"cx" : round(x + w / 2, 2),
"cy" : round(y + h / 2, 2),
})
return slots, ref_image["file_name"]
# ---------------------------------------------------------------------------
# Main
# ---------------------------------------------------------------------------
def main():
print("Loading COCO annotations ...")
coco = load_coco(COCO_FILE)
print(f"Total images : {len(coco['images'])}")
print(f"Total annotations : {len(coco['annotations'])}")
print(f"Categories : {[c['name'] for c in coco['categories']]}")
print()
slots, ref_frame = build_slot_map(coco)
output = {
"reference_frame" : ref_frame,
"total_slots" : len(slots),
"slots" : slots,
}
with open(OUTPUT, "w") as f:
json.dump(output, f, indent=2)
print(f"\nslot_map.json written to : {OUTPUT}")
print(f"Total slots mapped : {len(slots)}")
if __name__ == "__main__":
main()