""" HaramGuard — Dashboard Entry Point ===================================== """ import cv2 import streamlit as st import numpy as np from config import VIDEO_PATH, DB_PATH, MODEL_PATH, OPENAI_KEY, ANTHROPIC_KEY from pipeline import RealTimePipeline # ── Init ────────────────────────────────────────────────────────────── st.set_page_config(page_title='HaramGuard', layout='wide') st.title('🕌 HaramGuard — Real-Time Crowd Safety') pipeline = RealTimePipeline( video_path = VIDEO_PATH, openai_key = OPENAI_KEY, anthropic_key = ANTHROPIC_KEY, # enables Claude Vision counting model_path = MODEL_PATH, db_path = DB_PATH, ) cap = pipeline.get_video_capture() # ── Placeholders ────────────────────────────────────────────────────── col1, col2 = st.columns([2, 1]) with col1: ph_video = st.empty() with col2: ph_risk = st.empty() ph_count = st.empty() ph_trend = st.empty() ph_alert = st.empty() ph_reflect = st.empty() # ── Main loop ───────────────────────────────────────────────────────── while cap.isOpened(): ret, frame = cap.read() if not ret: break pipeline.process_one_frame(frame) s = pipeline.state # Video feed ph_video.image( cv2.cvtColor(s['annotated'], cv2.COLOR_BGR2RGB), use_column_width=True, caption=f"Frame {s['frame_id']} | {s['fps']} FPS" ) # Risk metrics risk_color = '🔴' if s['risk_level'] == 'HIGH' else '🟡' if s['risk_level'] == 'MEDIUM' else '🟢' ph_risk.metric('Risk Level', f"{risk_color} {s['risk_level']}", f"score: {s['risk_score']:.3f}") ph_count.metric('Pilgrims Detected', s['person_count']) ph_trend.metric('Trend', s['trend'].upper()) # Arabic P0 alert if s.get('arabic_alert'): ph_alert.error(f"🚨 {s['arabic_alert']}") pipeline.state['arabic_alert'] = '' # Reflection summary rs = s.get('reflection_summary', {}) if rs: ph_reflect.info( f"🪞 Reflection: {rs.get('bias_events', 0)} bias events / " f"{rs.get('total_reflections', 0)} frames " f"({rs.get('bias_rate_pct', 0):.1f}%)" ) cap.release()