fix: absolute OUTPUT_DIR, resolution scaling for zones, full reference repo values

This commit is contained in:
jetson committed 2026-09-22 14:30:05 +07:00
1 parent 2b462318ac
commit 35cccd03b3
4 files changed
+39 -10

No files matched your search

+1 -1
View File
@@ -29,7 +29,7 @@ app.config["MAX_CONTENT_LENGTH"] = 2 * 1024 * 1024 * 1024 # 2GB
MODELS_DIR = os.getenv("MODELS_DIR", "./models")
UPLOAD_DIR = os.getenv("UPLOAD_DIR", "./uploads")
OUTPUT_DIR = os.getenv("OUTPUT_DIR", "./output")
OUTPUT_DIR = os.path.abspath(os.getenv("OUTPUT_DIR", "./output"))
os.makedirs(UPLOAD_DIR, exist_ok=True)
os.makedirs(OUTPUT_DIR, exist_ok=True)
+15 -8
View File
@@ -22,31 +22,38 @@ def save_zone_config(config: dict[str, Any], path: str) -> None:
def build_static_roi(zone: dict[str, Any], video_w: int, video_h: int) -> TruckROI:
"""Build a TruckROI from a zone config dict.
"""Build a TruckROI from a zone config dict, scaling from reference resolution.
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).
- reference_resolution: [w, h] (optional, default [1920, 1080])
Coordinates are stored at reference_resolution and scaled to actual video_w/video_h.
"""
truck_pts = zone.get("truck_area", [])
count_line = zone.get("count_line", {})
ref_w, ref_h = zone.get("reference_resolution", [1920, 1080])
# Compute bounding box of truck_area polygon
# Scale factors from reference resolution to actual video
sx = video_w / ref_w if ref_w else 1.0
sy = video_h / ref_h if ref_h else 1.0
# Compute bounding box of truck_area polygon (scaled)
if truck_pts and len(truck_pts) >= 4:
xs = [p[0] for p in truck_pts]
ys = [p[1] for p in truck_pts]
xs = [int(p[0] * sx) for p in truck_pts]
ys = [int(p[1] * sy) 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))
line_y = int(count_line.get("y", (y1 + y2) // 2) * sy)
line_x_start = int(count_line.get("x_start", x1) * sx)
line_x_end = int(count_line.get("x_end", x2) * sx)
return TruckROI(
x1=x1, y1=y1, x2=x2, y2=y2,
+13
View File
@@ -17,6 +17,7 @@ def test_build_static_roi_from_zone_config():
zone = {
"truck_area": [[100, 50], [110, 300], [400, 310], [390, 40]],
"count_line": {"x_start": 110, "x_end": 400, "y": 150},
"reference_resolution": [640, 480],
}
roi = build_static_roi(zone, video_w=640, video_h=480)
assert roi.line_y == 150
@@ -36,6 +37,18 @@ def test_build_static_roi_scales_coords():
assert roi.x2 == 1404
def test_build_static_roi_scales_from_1080p_to_720p():
zone = {
"truck_area": [[600, 385], [609, 1076], [1404, 1078], [1381, 343]],
"count_line": {"x_start": 577, "x_end": 1401, "y": 330},
"reference_resolution": [1920, 1080],
}
roi = build_static_roi(zone, video_w=1280, video_h=720)
assert roi.line_y == int(330 * 720 / 1080)
assert roi.x1 == int(600 * 1280 / 1920)
assert roi.x2 == int(1404 * 1280 / 1920)
def test_list_zone_presets(tmp_path):
cfg = {"presets": {"p1": {"description": "Zone 1"}, "p2": {"description": "Zone 2"}}}
p = tmp_path / "zones.json"
+10 -1
View File
@@ -3,11 +3,20 @@
"default": {
"truck_area": [[600, 385], [609, 1076], [1404, 1078], [1381, 343]],
"counting_area": [[574, 50], [586, 1077], [1418, 1076], [1397, 50]],
"palet": [[612, 628], [1454, 630], [1458, 1074], [608, 1071]],
"count_line": {"x_start": 577, "x_end": 1401, "y": 330},
"reference_resolution": [1920, 1080],
"left_limit": 0.27578,
"right_limit": 0.72578,
"duplicate_circle_radius": 30,
"description": "Default zone for 1920x1080 camera"
"min_valid_area": 15000,
"jarak_toleransi_duplikat": 30,
"max_reid_transit_distance": 400,
"circle_stay_timeout_sec": 10.0,
"inference_stride": 2,
"confirm_delay_sec": 0.5,
"exit_confirm_delay_sec": 6.0,
"description": "Default zone from karung-counting-feedmill-semarang (1920x1080 native)"
}
},
"active_preset": "default"