Files
feedmill-recounter/src/zone_config.py
T

74 lines
2.3 KiB
Python

"""Zone configuration — load/save counting zone presets from zones.json."""
from __future__ import annotations
import json
import os
from typing import Any
from src.truck_roi import TruckROI
def load_zone_config(path: str) -> dict[str, Any]:
"""Load zones.json and return full config dict."""
with open(path) as f:
return json.load(f)
def save_zone_config(config: dict[str, Any], path: str) -> None:
"""Save zone config dict to zones.json."""
with open(path, "w") as f:
json.dump(config, f, indent=2)
def build_static_roi(zone: dict[str, Any], video_w: int, video_h: int) -> TruckROI:
"""Build a TruckROI from a zone config dict.
The zone dict should have:
- truck_area: [[x1,y1], [x2,y2], [x3,y3], [x4,y4]] (4-point polygon)
- count_line: {"x_start": int, "x_end": int, "y": int}
Coordinates are in the video's native resolution (no scaling needed
if the zone was calibrated for this resolution).
"""
truck_pts = zone.get("truck_area", [])
count_line = zone.get("count_line", {})
# Compute bounding box of truck_area polygon
if truck_pts and len(truck_pts) >= 4:
xs = [p[0] for p in truck_pts]
ys = [p[1] for p in truck_pts]
x1 = max(0, min(xs))
y1 = max(0, min(ys))
x2 = min(video_w, max(xs))
y2 = min(video_h, max(ys))
else:
# Fallback: use 50% of frame
x1, y1 = int(video_w * 0.3), int(video_h * 0.1)
x2, y2 = int(video_w * 0.75), int(video_h * 0.95)
line_y = count_line.get("y", int((y1 + y2) / 2))
return TruckROI(
x1=x1, y1=y1, x2=x2, y2=y2,
line_y=line_y,
confidence=1.0,
)
def list_zone_presets(path: str) -> list[dict[str, Any]]:
"""Return list of preset summaries: [{"name": str, "description": str, ...}]."""
config = load_zone_config(path)
presets = config.get("presets", {})
return [
{"name": name, "description": vals.get("description", ""), **vals}
for name, vals in presets.items()
]
def get_active_zone(path: str, preset_name: str | None = None) -> dict[str, Any] | None:
"""Get the active preset dict. Falls back to active_preset field if name not given."""
config = load_zone_config(path)
presets = config.get("presets", {})
name = preset_name or config.get("active_preset")
return presets.get(name)