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.
main
bahawal.baloch 2026-04-02 14:36:18 +05:00
parent ea349663fd
commit 50ecbdcc50
1 changed files with 30 additions and 18 deletions

View File

@ -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: