Netra / backend /app /models /rules /red_light.py
chikentikka's picture
plate recog by TrOCR and frontend and some other things updated
f09c2db
Raw
History Blame Contribute Delete
1.49 kB
"""Red-light running.
Classifies each detected traffic light by HSV colour. When a red signal is
present, vehicles past the configured stop line are flagged. Opt-in via
`settings.red_light_enforcement` since the stop line is camera-specific.
"""
import cv2
import numpy as np
from app.config import settings
from .base import Scene, violation
CODE = "RED_LIGHT_VIOLATION"
NAME = "Red-light running"
SEVERITY = "HIGH"
def status() -> str:
return "active" if settings.red_light_enforcement else "needs-config"
def _is_red(crop: np.ndarray) -> bool:
hsv = cv2.cvtColor(crop, cv2.COLOR_BGR2HSV)
red = cv2.inRange(hsv, (0, 90, 90), (10, 255, 255)) | cv2.inRange(
hsv, (160, 90, 90), (179, 255, 255)
)
green = cv2.inRange(hsv, (40, 60, 60), (90, 255, 255))
return int(red.sum()) > int(green.sum()) and red.sum() > 0
def check(scene: Scene) -> list[dict]:
if status() != "active" or not scene.signals:
return []
red_on = any(
_is_red(scene.image[max(0, s["bbox"][1]):s["bbox"][3], max(0, s["bbox"][0]):s["bbox"][2]])
for s in scene.signals
if scene.image[max(0, s["bbox"][1]):s["bbox"][3], max(0, s["bbox"][0]):s["bbox"][2]].size
)
if not red_on:
return []
stop_line = int(scene.image.shape[0] * settings.stop_line_frac)
return [
violation(CODE, SEVERITY, v, "Vehicle past the stop line on a red signal")
for v in scene.vehicles
if v["bbox"][3] > stop_line
]