From 50ecbdcc50b894d318e4af3dd350e400ba594184 Mon Sep 17 00:00:00 2001 From: "bahawal.baloch" Date: Thu, 2 Apr 2026 14:36:18 +0500 Subject: [PATCH] Enhance alert processing in camera stream - Added debug print statements for camera IP configuration at load time. - Modified CAMERA_IPS initialization to correctly reference environment variables. - Adjusted YOLO_CONF value for improved detection sensitivity. - Refactored alert logic to accumulate pending alerts before saving, allowing for better management of alert metadata and image saving. - Implemented saving of annotated alerts with unique filenames to prevent collisions. --- camera_stream.py | 48 ++++++++++++++++++++++++++++++------------------ 1 file changed, 30 insertions(+), 18 deletions(-) diff --git a/camera_stream.py b/camera_stream.py index 4cd0ce6..b27dcee 100644 --- a/camera_stream.py +++ b/camera_stream.py @@ -13,12 +13,18 @@ load_dotenv(override=True) app = Flask(__name__) +# Load-time debug for camera config (safe to leave; only prints on startup) +print( + "[Surveillance] camera_ip_1=" + str(os.getenv("camera_ip_1")) + + " camera_ip_2=" + str(os.getenv("camera_ip_2")) +) + # --------------------------------------------------------------------------- # Configuration # --------------------------------------------------------------------------- USERNAME = os.getenv("username") PASSWORD = os.getenv("password") -CAMERA_IPS = [os.getenv(f"camera_ip_{i+1}") for i in range(1, 3)] +CAMERA_IPS = [os.getenv(f"camera_ip_{i}") for i in range(1, 3)] CAMERAS = [ { "id": f"cam{i + 1}", @@ -34,7 +40,7 @@ PROXIMITY_PX = 200 # max pixel distance to consider two people "together" GROUP_TIME_THRESHOLD = 20 # seconds before an alert fires ALERT_COOLDOWN = 60 # seconds between successive alerts MIN_GROUP_SIZE = 2 -YOLO_CONF = 0.5 +YOLO_CONF = 0.25 INFERENCE_DEVICE = 0 # --------------------------------------------------------------------------- @@ -249,8 +255,9 @@ def _process_stream(): for gid in stale: del _group_trackers[gid] - # --- Alert logic --- + # --- Alert logic (mark + metadata; save after drawing overlays) --- alert_this_frame = False + pending_alerts = [] # list of (gid, people_count, duration_seconds) for gid, gdata in _group_trackers.items(): duration = gdata["last_seen"] - gdata["first_seen"] if duration >= GROUP_TIME_THRESHOLD and not gdata["alerted"]: @@ -258,21 +265,7 @@ def _process_stream(): gdata["alerted"] = True alert_this_frame = True _last_alert_time = now - - os.makedirs("alerts", exist_ok=True) - ts = datetime.now().strftime("%Y%m%d_%H%M%S") - alert_path = f"alerts/alert_{ts}.jpg" - cv2.imwrite(alert_path, frame) - - alert_info = { - "time": datetime.now().strftime("%Y-%m-%d %H:%M:%S"), - "people": gdata["member_count"], - "duration": round(duration, 1), - "image": alert_path, - } - with lock: - state["alerts"].insert(0, alert_info) - state["alerts"] = state["alerts"][:50] + pending_alerts.append((gid, gdata["member_count"], duration)) # --- Draw overlays --- display = frame.copy() @@ -308,6 +301,25 @@ def _process_stream(): cv2.FONT_HERSHEY_SIMPLEX, 0.8, (0, 0, 255), 3, ) + # --- Save annotated alerts --- + if pending_alerts: + os.makedirs("alerts", exist_ok=True) + ts = datetime.now().strftime("%Y%m%d_%H%M%S") + for gid, people, duration in pending_alerts: + # Include group id to avoid collisions when multiple groups alert in one second. + alert_path = f"alerts/alert_{ts}_gid{gid}.jpg" + cv2.imwrite(alert_path, display) + + alert_info = { + "time": datetime.now().strftime("%Y-%m-%d %H:%M:%S"), + "people": people, + "duration": round(duration, 1), + "image": alert_path, + } + with lock: + state["alerts"].insert(0, alert_info) + state["alerts"] = state["alerts"][:50] + # --- Update shared state --- groups_json = [] for gid, gi, gc in frame_group_data: