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
parent
ea349663fd
commit
50ecbdcc50
|
|
@ -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:
|
||||
|
|
|
|||
Loading…
Reference in New Issue