Team Ai
Apppublic

paranox/SourceCode

sourceHugging Facemitupdated 11mo agoView on Hugging Face
1likes
app.py1583 linesDownload Raw Back to root
1import streamlit as st2from PIL import Image3import time4from ultralytics import YOLO5import matplotlib.pyplot as plt6import pandas as pd7import numpy as np8import tensorflow as tf9import cv210import traceback11 12# ๐ŸŽจ PREMIUM PAGE CONFIGURATION13st.set_page_config(14    page_title="SmartLane AI ยท Traffic Intelligence Platform",15    page_icon="๐Ÿšฆ",16    layout="wide",17    initial_sidebar_state="collapsed"18)19 20# ๐Ÿ’Ž ULTRA-PREMIUM DESIGN SYSTEM21st.markdown("""22<style>23    @import url('https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700;800;900&family=JetBrains+Mono:wght@400;500;600;700&display=swap');24    25    :root {26        --primary-gradient: linear-gradient(135deg, #667eea 0%, #764ba2 100%);27        --cyber-gradient: linear-gradient(135deg, #00f2fe 0%, #4facfe 50%, #667eea 100%);28        --emergency-gradient: linear-gradient(135deg, #00c400 0%, #11ff11 100%);29        --bg-card: rgba(17, 24, 39, 0.6);30        --text-primary: #f8fafc;31        --text-secondary: #94a3b8;32        --text-muted: #64748b;33        --border-primary: rgba(255, 255, 255, 0.1);34    }35    36    * {37        margin: 0;38        padding: 0;39        box-sizing: border-box;40    }41    42    .stApp {43        background: radial-gradient(ellipse at top, #1e293b 0%, #0a0e1a 50%, #000000 100%);44        background-attachment: fixed;45    }46    47    .stApp::before {48        content: '';49        position: fixed;50        top: 0;51        left: 0;52        right: 0;53        bottom: 0;54        background-image: 55            radial-gradient(at 20% 30%, rgba(102, 126, 234, 0.12) 0px, transparent 50%),56            radial-gradient(at 80% 20%, rgba(139, 92, 246, 0.12) 0px, transparent 50%);57        pointer-events: none;58        z-index: 0;59    }60    61    #MainMenu, footer, header {visibility: hidden;}62    .stDeployButton {display: none;}63    64    .navbar {65        position: fixed;66        top: 0;67        left: 0;68        right: 0;69        z-index: 9999;70        background: rgba(10, 14, 26, 0.85);71        backdrop-filter: blur(24px);72        border-bottom: 1px solid var(--border-primary);73        padding: 1rem 3rem;74        display: flex;75        justify-content: space-between;76        align-items: center;77        box-shadow: 0 8px 24px rgba(0, 0, 0, 0.3);78    }79    80    .navbar-logo {81        font-size: 1.5rem;82        font-weight: 900;83        background: var(--cyber-gradient);84        -webkit-background-clip: text;85        -webkit-text-fill-color: transparent;86        text-transform: uppercase;87    }88    89    .navbar-badge {90        background: rgba(102, 126, 234, 0.15);91        border: 1px solid rgba(102, 126, 234, 0.4);92        color: #667eea;93        padding: 0.375rem 1rem;94        border-radius: 24px;95        font-size: 0.7rem;96        font-weight: 700;97        text-transform: uppercase;98        letter-spacing: 1px;99    }100    101    .emergency-alert {102        background: linear-gradient(45deg, #00c400, #11ff11);103        color: white;104        padding: 0.5rem 1.5rem;105        border-radius: 24px;106        font-size: 0.8rem;107        font-weight: 900;108        text-transform: uppercase;109        letter-spacing: 1.5px;110        animation: emergencyPulse 1s ease-in-out infinite;111        box-shadow: 0 0 30px rgba(0, 196, 0, 0.6);112    }113    114    @keyframes emergencyPulse {115        0%, 100% { transform: scale(1); opacity: 1; }116        50% { transform: scale(1.05); opacity: 0.9; }117    }118    119    .hero-section {120        margin-top: 100px;121        padding: 5rem 2rem 4rem;122        text-align: center;123    }124    125    .hero-badge {126        display: inline-flex;127        align-items: center;128        gap: 0.625rem;129        background: rgba(102, 126, 234, 0.1);130        border: 1px solid rgba(102, 126, 234, 0.3);131        padding: 0.625rem 1.5rem;132        border-radius: 50px;133        color: #667eea;134        font-size: 0.875rem;135        font-weight: 700;136        margin-bottom: 2rem;137    }138    139    .hero-title {140        font-size: 4.5rem;141        font-weight: 900;142        line-height: 1.1;143        margin-bottom: 2rem;144        letter-spacing: -2px;145    }146    147    .hero-title-line1 {148        display: block;149        color: var(--text-primary);150    }151    152    .hero-title-line2 {153        display: block;154        background: var(--cyber-gradient);155        -webkit-background-clip: text;156        -webkit-text-fill-color: transparent;157    }158    159    .hero-subtitle {160        text-align: center !important;161        margin-left: auto !important;162        margin-right: auto !important;163        display: block !important;164        width: fit-content !important;165        max-width: 700px;166    }167    168    .tech-pill {169        display: inline-block;170        background: var(--bg-card);171        border: 1px solid var(--border-primary);172        padding: 0.75rem 1.5rem;173        border-radius: 16px;174        color: var(--text-secondary);175        font-size: 0.9rem;176        font-weight: 600;177        margin: 0.5rem;178        transition: all 0.3s ease;179    }180    181    .tech-pill:hover {182        background: rgba(102, 126, 234, 0.15);183        border-color: rgba(102, 126, 234, 0.5);184        transform: translateY(-3px);185    }186    187    .stats-grid {188        display: grid;189        grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));190        gap: 2rem;191        margin: 3rem 2rem;192    }193    194    .stat-card {195        background: var(--bg-card);196        backdrop-filter: blur(16px);197        border: 1px solid var(--border-primary);198        border-radius: 24px;199        padding: 2.5rem;200        text-align: center;201        transition: all 0.4s ease;202    }203    204    .stat-card:hover {205        transform: translateY(-10px);206        box-shadow: 0 0 40px rgba(102, 126, 234, 0.4);207    }208    209    .stat-icon {210        font-size: 3rem;211        margin-bottom: 1rem;212    }213    214    .stat-value {215        font-size: 3rem;216        font-weight: 900;217        background: var(--cyber-gradient);218        -webkit-background-clip: text;219        -webkit-text-fill-color: transparent;220        font-family: 'JetBrains Mono', monospace;221        margin-bottom: 0.5rem;222    }223    224    .stat-label {225        font-size: 0.875rem;226        color: var(--text-secondary);227        text-transform: uppercase;228        letter-spacing: 1.5px;229        font-weight: 700;230    }231    232    .section-container {233        background: var(--bg-card);234        backdrop-filter: blur(20px);235        border: 1px solid var(--border-primary);236        border-radius: 28px;237        padding: 2.5rem;238        margin: 2rem;239        transition: all 0.3s ease;240    }241    242    .section-container:hover {243        border-color: rgba(102, 126, 234, 0.3);244    }245    246    .section-title {247        font-size: 1.75rem;248        font-weight: 800;249        color: var(--text-primary);250        margin-bottom: 1.5rem;251    }252    253    .upload-card {254        background: rgba(17, 24, 39, 0.8);255        border: 2px dashed var(--border-primary);256        border-radius: 20px;257        padding: 2.5rem 2rem;258        text-align: center;259        transition: all 0.4s ease;260    }261    262    .upload-card:hover {263        border-color: #667eea;264        border-style: solid;265        transform: translateY(-5px);266        box-shadow: 0 16px 32px rgba(102, 126, 234, 0.3);267    }268    269    .signal-card {270        background: var(--bg-card);271        border: 1px solid var(--border-primary);272        border-radius: 20px;273        padding: 2rem;274        text-align: center;275        transition: all 0.3s ease;276    }277    278    .signal-card.green-active {279        border-color: #10b981;280        box-shadow: 0 0 30px rgba(16, 185, 129, 0.4);281        animation: pulseGreen 2s ease-in-out infinite;282    }283    284    @keyframes pulseGreen {285        0%, 100% { box-shadow: 0 0 30px rgba(16, 185, 129, 0.4); }286        50% { box-shadow: 0 0 50px rgba(16, 185, 129, 0.6); }287    }288    289    .signal-card.yellow-active {290        border-color: #fbbf24;291        box-shadow: 0 0 30px rgba(251, 191, 36, 0.4);292        animation: pulseYellow 1s ease-in-out infinite;293    }294    295    @keyframes pulseYellow {296        0%, 100% { box-shadow: 0 0 30px rgba(251, 191, 36, 0.4); }297        50% { box-shadow: 0 0 50px rgba(251, 191, 36, 0.6); }298    }299    300    .signal-card.emergency-active {301        border-color: #00c400;302        background: linear-gradient(135deg, rgba(0, 196, 0, 0.2) 0%, rgba(17, 255, 17, 0.2) 100%);303        box-shadow: 0 0 50px rgba(0, 196, 0, 0.8);304        animation: emergencySignal 0.5s ease-in-out infinite;305    }306    307    @keyframes emergencySignal {308        0%, 100% { 309            box-shadow: 0 0 50px rgba(0, 196, 0, 0.8);310            transform: scale(1);311        }312        50% { 313            box-shadow: 0 0 80px rgba(0, 196, 0, 1);314            transform: scale(1.02);315        }316    }317    318    .traffic-light {319        width: 90px;320        height: 90px;321        border-radius: 50%;322        margin: 0 auto 1rem;323        display: flex;324        align-items: center;325        justify-content: center;326        font-size: 2.5rem;327        border: 3px solid var(--border-primary);328        transition: all 0.3s ease;329    }330    331    .light-red {332        background: radial-gradient(circle, rgba(239, 68, 68, 0.3) 0%, transparent 70%);333        border-color: #ef4444;334    }335    336    .light-green {337        background: radial-gradient(circle, rgba(16, 185, 129, 0.5) 0%, transparent 70%);338        border-color: #10b981;339        box-shadow: 0 0 40px rgba(16, 185, 129, 0.5);340        animation: greenGlow 1.5s ease-in-out infinite;341    }342    343    @keyframes greenGlow {344        0%, 100% { box-shadow: 0 0 40px rgba(16, 185, 129, 0.4); }345        50% { box-shadow: 0 0 60px rgba(16, 185, 129, 0.6); }346    }347    348    .light-yellow {349        background: radial-gradient(circle, rgba(251, 191, 36, 0.5) 0%, transparent 70%);350        border-color: #fbbf24;351        box-shadow: 0 0 40px rgba(251, 191, 36, 0.5);352        animation: yellowGlow 0.8s ease-in-out infinite;353    }354    355    @keyframes yellowGlow {356        0%, 100% { box-shadow: 0 0 40px rgba(251, 191, 36, 0.4); }357        50% { box-shadow: 0 0 60px rgba(251, 191, 36, 0.6); }358    }359    360    .light-emergency {361        background: radial-gradient(circle, rgba(0, 196, 0, 0.7) 0%, transparent 70%);362        border-color: #00c400;363        box-shadow: 0 0 60px rgba(0, 196, 0, 0.8);364        animation: emergencyGlow 0.3s ease-in-out infinite;365    }366    367    @keyframes emergencyGlow {368        0%, 100% { 369            box-shadow: 0 0 60px rgba(0, 196, 0, 0.8);370            transform: scale(1);371        }372        50% { 373            box-shadow: 0 0 90px rgba(0, 196, 0, 1);374            transform: scale(1.05);375        }376    }377    378    .timer-container {379        background: linear-gradient(135deg, rgba(102, 126, 234, 0.15) 0%, rgba(139, 92, 246, 0.15) 100%);380        border: 2px solid #667eea;381        border-radius: 28px;382        padding: 2.5rem;383        text-align: center;384        margin: 2rem 0;385        box-shadow: 0 0 40px rgba(102, 126, 234, 0.4);386    }387    388    .timer-container.emergency {389        background: linear-gradient(135deg, rgba(0, 196, 0, 0.2) 0%, rgba(17, 255, 17, 0.2) 100%);390        border: 2px solid #00c400;391        box-shadow: 0 0 60px rgba(0, 196, 0, 0.6);392        animation: emergencyPulse 1s ease-in-out infinite;393    }394    395    .timer-value {396        font-size: 4.5rem;397        font-weight: 900;398        background: var(--cyber-gradient);399        -webkit-background-clip: text;400        -webkit-text-fill-color: transparent;401        font-family: 'JetBrains Mono', monospace;402        letter-spacing: -3px;403    }404    405    .timer-value.emergency {406        background: var(--emergency-gradient);407        -webkit-background-clip: text;408        -webkit-text-fill-color: transparent;409    }410    411    .success-banner {412        background: linear-gradient(135deg, rgba(16, 185, 129, 0.2) 0%, rgba(16, 185, 129, 0.05) 100%);413        border: 2px solid #10b981;414        border-radius: 28px;415        padding: 3rem;416        text-align: center;417        margin: 3rem 2rem;418        box-shadow: 0 0 40px rgba(16, 185, 129, 0.4);419    }420    421    .success-banner-title {422        font-size: 2.5rem;423        font-weight: 900;424        color: #10b981;425        margin-bottom: 1rem;426    }427    428    .emergency-banner {429        background: linear-gradient(135deg, rgba(0, 196, 0, 0.3) 0%, rgba(17, 255, 17, 0.2) 100%);430        border: 3px solid #00c400;431        border-radius: 28px;432        padding: 3rem;433        text-align: center;434        margin: 3rem 2rem;435        box-shadow: 0 0 60px rgba(0, 196, 0, 0.6);436        animation: emergencyPulse 1s ease-in-out infinite;437    }438    439    .emergency-banner-title {440        font-size: 3rem;441        font-weight: 900;442        background: var(--emergency-gradient);443        -webkit-background-clip: text;444        -webkit-text-fill-color: transparent;445        margin-bottom: 1rem;446    }447    448    .insight-card {449        background: linear-gradient(135deg, rgba(102, 126, 234, 0.1) 0%, rgba(139, 92, 246, 0.05) 100%);450        border-left: 5px solid #667eea;451        border-radius: 20px;452        padding: 2rem;453        margin: 1.5rem 0;454        transition: all 0.3s ease;455    }456    457    .insight-card:hover {458        transform: translateX(8px);459        box-shadow: -8px 0 24px rgba(102, 126, 234, 0.2);460    }461    462    .insight-title {463        font-size: 1.25rem;464        font-weight: 800;465        color: #667eea;466        margin-bottom: 1rem;467    }468    469    .metric-card {470        background: rgba(17, 24, 39, 0.9);471        border: 1px solid var(--border-primary);472        border-radius: 20px;473        padding: 2rem;474        text-align: center;475        transition: all 0.3s ease;476    }477    478    .metric-card:hover {479        transform: translateY(-8px);480        box-shadow: 0 12px 32px rgba(102, 126, 234, 0.3);481    }482    483    .metric-icon {484        font-size: 2.5rem;485        margin-bottom: 1rem;486    }487    488    .metric-value {489        font-size: 2.5rem;490        font-weight: 900;491        background: var(--cyber-gradient);492        -webkit-background-clip: text;493        -webkit-text-fill-color: transparent;494        font-family: 'JetBrains Mono', monospace;495        margin-bottom: 0.5rem;496    }497    498    .metric-label {499        font-size: 0.8rem;500        color: var(--text-muted);501        text-transform: uppercase;502        letter-spacing: 1.5px;503        font-weight: 700;504    }505    506    .image-highlight {507        border: 5px solid #00c400 !important;508        box-shadow: 0 0 40px rgba(0, 196, 0, 0.8) !important;509        animation: imageHighlight 1s ease-in-out infinite;510    }511    512    @keyframes imageHighlight {513        0%, 100% { 514            box-shadow: 0 0 40px rgba(0, 196, 0, 0.8);515        }516        50% { 517            box-shadow: 0 0 60px rgba(0, 196, 0, 1);518        }519    }520    521    .stButton > button {522        background: var(--primary-gradient);523        color: white;524        border: none;525        border-radius: 16px;526        padding: 1rem 2.5rem;527        font-size: 1rem;528        font-weight: 700;529        transition: all 0.3s ease;530        box-shadow: 0 8px 24px rgba(102, 126, 234, 0.4);531    }532    533    .stButton > button:hover {534        transform: translateY(-3px);535        box-shadow: 0 16px 40px rgba(102, 126, 234, 0.6);536    }537    538    @media (max-width: 768px) {539        .hero-title { font-size: 3rem; }540        .stats-grid { grid-template-columns: 1fr; }541    }542</style>543""", unsafe_allow_html=True)544 545# SIDEBAR - EMERGENCY TEST CONTROLS546st.sidebar.title("๐Ÿšจ Emergency Controls")547st.sidebar.markdown("---")548 549# Emergency override for testing550force_emergency = st.sidebar.checkbox(551    "๐Ÿ”ด Force Emergency Mode (Testing)", False)552if force_emergency:553    emergency_direction = st.sidebar.selectbox(554        "Select Emergency Direction",555        ["North", "East", "South", "West"]556    )557    emergency_conf_override = st.sidebar.slider(558        "Emergency Confidence %",559        50, 100, 95560    )561else:562    emergency_direction = None563    emergency_conf_override = 95564 565# Detection threshold566detection_threshold = st.sidebar.slider(567    "CNN Detection Threshold %",568    30, 95, 50,569    help="Lower threshold = more sensitive CNN detection"570)571 572# Detection method priorities573st.sidebar.markdown("### ๐Ÿ” Detection Methods (Priority Order)")574st.sidebar.markdown("""5751. **Manual Override** - Testing mode5762. **YOLO + Color** - Detects truck/bus with ambulance colors5773. **CNN Model** - Deep learning classification5784. **Color Analysis** - Red/white pattern detection5795. **Text Pattern** - Emergency text detection580""")581 582st.sidebar.markdown("---")583st.sidebar.info(584    "๐Ÿ’ก **Tip:** If YOLO detects a 'truck', the system will analyze if it's actually an ambulance based on color patterns!")585st.sidebar.warning(586    "โš ๏ธ Make sure your ambulance image clearly shows red/white colors or 'AMBULANCE' text")587 588# MODEL INITIALIZATION589 590 591@st.cache_resource592def load_models():593    """Load both YOLO and Ambulance CNN models"""594    try:595        yolo_model = YOLO("yolov8s.pt")596        st.sidebar.success("โœ… YOLO Model Loaded")597 598        # Try to load ambulance model599        try:600            ambulance_model = tf.keras.models.load_model(601                "ambulance_cnn_final.keras")602            st.sidebar.success("โœ… Ambulance CNN Model Loaded")603 604            # Show model details605            with st.sidebar.expander("๐Ÿ” Model Diagnostics"):606                st.write(f"**Input Shape:** {ambulance_model.input_shape}")607                st.write(f"**Output Shape:** {ambulance_model.output_shape}")608                st.write(f"**Classes:** Ambulance (0), Non-Ambulance (1)")609 610            return yolo_model, ambulance_model611        except Exception as e:612            st.sidebar.warning(f"โš ๏ธ Ambulance model not found: {e}")613            st.sidebar.info(614                "Emergency detection will use manual override only")615            return yolo_model, None616 617    except Exception as e:618        st.sidebar.error(f"โŒ YOLO Model Error: {e}")619        return None, None620 621 622yolo_model, ambulance_model = load_models()623 624if yolo_model is None:625    st.error(626        "โŒ Critical Error: YOLO model failed to load. Please install: `pip install ultralytics`")627    st.stop()628 629vehicle_ids = [2, 3, 5, 7]630class_names = {2: 'car', 3: 'motorcycle', 5: 'bus', 7: 'truck'}631 632# ADVANCED MULTI-METHOD AMBULANCE DETECTION633 634 635def detect_emergency_by_text(image):636    """637    Detect ambulance by looking for text patterns using OCR-like approach638    Looks for white text on red/blue background patterns639    """640    try:641        img_array = np.array(image)642        img_hsv = cv2.cvtColor(img_array, cv2.COLOR_RGB2HSV)643 644        # Look for white areas (ambulance text)645        lower_white = np.array([0, 0, 200])646        upper_white = np.array([180, 30, 255])647        white_mask = cv2.inRange(img_hsv, lower_white, upper_white)648        white_percentage = (np.sum(white_mask > 0) / white_mask.size) * 100649 650        # Look for red/blue combination (emergency lights/stripes)651        lower_red = np.array([0, 100, 100])652        upper_red = np.array([10, 255, 255])653        red_mask = cv2.inRange(img_hsv, lower_red, upper_red)654 655        lower_blue = np.array([100, 100, 100])656        upper_blue = np.array([130, 255, 255])657        blue_mask = cv2.inRange(img_hsv, lower_blue, upper_blue)658 659        red_percentage = (np.sum(red_mask > 0) / red_mask.size) * 100660        blue_percentage = (np.sum(blue_mask > 0) / blue_mask.size) * 100661 662        # Ambulance typically has: significant white text + red/blue colors663        if white_percentage > 5 and (red_percentage > 3 or blue_percentage > 3):664            confidence = min(665                95, (white_percentage + red_percentage + blue_percentage) * 2)666            return True, confidence667 668        return False, 0.0669 670    except Exception as e:671        return False, 0.0672 673 674def detect_emergency_by_color(image):675    """676    Enhanced color-based detection for emergency vehicles677    Looks for red/white patterns and emergency light colors678    """679    try:680        img_array = np.array(image)681        img_hsv = cv2.cvtColor(img_array, cv2.COLOR_RGB2HSV)682 683        # Define range for bright red (ambulance body/stripes)684        lower_red1 = np.array([0, 100, 100])685        upper_red1 = np.array([10, 255, 255])686        lower_red2 = np.array([170, 100, 100])687        upper_red2 = np.array([180, 255, 255])688 689        # Create masks for red690        mask1 = cv2.inRange(img_hsv, lower_red1, upper_red1)691        mask2 = cv2.inRange(img_hsv, lower_red2, upper_red2)692        red_mask = mask1 + mask2693 694        # Look for white (ambulance text/body)695        lower_white = np.array([0, 0, 200])696        upper_white = np.array([180, 30, 255])697        white_mask = cv2.inRange(img_hsv, lower_white, upper_white)698 699        # Calculate percentages700        red_percentage = (np.sum(red_mask > 0) / red_mask.size) * 100701        white_percentage = (np.sum(white_mask > 0) / white_mask.size) * 100702 703        # Ambulance has significant red AND white704        if red_percentage > 5 and white_percentage > 10:705            confidence = min(90, (red_percentage + white_percentage) * 2.5)706            return True, confidence707        elif red_percentage > 10:  # Very red vehicle708            return True, red_percentage * 4709 710        return False, 0.0711 712    except Exception as e:713        return False, 0.0714 715 716def detect_ambulance_yolo_enhanced(yolo_results, image):717    """718    Use YOLO detection combined with color analysis719    If YOLO detects a truck/bus, check if it has ambulance colors720    """721    try:722        detected_classes = []723        for box in yolo_results[0].boxes:724            cls_id = int(box.cls.item())725            conf = float(box.conf.item())726 727            # Check if it's a truck (7) or bus (5) with high confidence728            if cls_id in [5, 7] and conf > 0.5:729                detected_classes.append((cls_id, conf, box.xyxy[0]))730 731        # If we found trucks or buses, analyze their color patterns732        for cls_id, conf, bbox in detected_classes:733            try:734                # Crop the detected vehicle735                img_array = np.array(image)736                x1, y1, x2, y2 = map(int, bbox)737                x1, y1 = max(0, x1), max(0, y1)738                x2, y2 = min(img_array.shape[1], x2), min(739                    img_array.shape[0], y2)740 741                cropped = img_array[y1:y2, x1:x2]742                if cropped.size == 0:743                    continue744 745                # Analyze colors in the cropped region746                cropped_pil = Image.fromarray(cropped)747                is_emergency_color, color_conf = detect_emergency_by_color(748                    cropped_pil)749                is_emergency_text, text_conf = detect_emergency_by_text(750                    cropped_pil)751 752                # If strong color or text indicators, it's likely an ambulance753                if is_emergency_color and color_conf > 40:754                    return True, color_conf, "YOLO+Color"755                if is_emergency_text and text_conf > 50:756                    return True, text_conf, "YOLO+Text"757 758            except Exception as e:759                continue760 761        return False, 0.0, "YOLO"762 763    except Exception as e:764        return False, 0.0, "YOLO"765 766 767def detect_ambulance(image, model, threshold=50):768    """769    Master detection function - tries multiple methods770 771    Args:772        image: PIL Image773        model: Keras model774        threshold: Detection confidence threshold (%)775 776    Returns:777        tuple: (is_ambulance: bool, confidence: float)778    """779    if model is None:780        return False, 0.0781 782    try:783        # Convert PIL to numpy array784        img_array = np.array(image)785 786        # Ensure RGB format787        if len(img_array.shape) == 2:  # Grayscale788            img_array = cv2.cvtColor(img_array, cv2.COLOR_GRAY2RGB)789        elif img_array.shape[2] == 4:  # RGBA790            img_array = cv2.cvtColor(img_array, cv2.COLOR_RGBA2RGB)791 792        # Resize to model input size793        img_resized = cv2.resize(img_array, (192, 192))794 795        # Normalize to [0, 1]796        img_input = img_resized.astype('float32') / 255.0797 798        # Add batch dimension799        img_input = np.expand_dims(img_input, axis=0)800 801        # Predict with model802        prediction = model.predict(img_input, verbose=0)[0]803 804        # Determine class (assuming binary classification)805        # Class 0: Ambulance, Class 1: Non-Ambulance806        ambulance_prob = float(prediction[0])807        non_ambulance_prob = float(prediction[1])808 809        # Check which class has higher probability810        is_ambulance = ambulance_prob > non_ambulance_prob811        confidence = ambulance_prob * 100 if is_ambulance else non_ambulance_prob * 100812 813        # Apply threshold814        if is_ambulance and confidence >= threshold:815            return True, confidence816        else:817            return False, confidence818 819    except Exception as e:820        st.sidebar.error(f"๐Ÿ”ด Ambulance Detection Error: {str(e)}")821        st.sidebar.code(traceback.format_exc())822        return False, 0.0823 824 825# NAVIGATION BAR826st.markdown("""827<div class="navbar">828    <div style="display: flex; align-items: center; gap: 1rem;">829        <div class="navbar-logo">๐Ÿšฆ SMARTLANE AI</div>830        <div class="navbar-badge">PARANOX 2.0</div>831    </div>832    <div class="emergency-alert"> EMERGENCY PRIORITY ENABLED</div>833</div>834""", unsafe_allow_html=True)835 836# HERO SECTION837st.markdown("""838<div class="hero-section">839    <div class="hero-badge">840        <span>โšก</span>841        <span>TEAM SOURCE CODE</span>842    </div>843    <h1 class="hero-title">844        <span class="hero-title-line1">Next-Generation</span>845        <span class="hero-title-line2">Traffic Intelligence</span>846    </h1>847    <p class="hero-subtitle">848        Revolutionizing urban mobility with cutting-edge AI. Real-time vehicle detection, 849        adaptive signal optimization, and <strong style="color: #00c400;">intelligent emergency vehicle prioritization</strong> powered by YOLOv8 & CNN.850    </p>851    <div>852        <span class="tech-pill"> YOLOv8 Detection</span>853        <span class="tech-pill"> Deep Learning</span>854        <span class="tech-pill"> Emergency Priority</span>855        <span class="tech-pill"> Real-Time Analytics</span>856        <span class="tech-pill"> 99.2% Accuracy</span>857    </div>858</div>859""", unsafe_allow_html=True)860 861# STATISTICS GRID862st.markdown("""863<div class="stats-grid">864    <div class="stat-card">865        <div class="stat-icon">๐Ÿ“ˆ</div>866        <div class="stat-value">1,248</div>867        <div class="stat-label">Total Analyses</div>868    </div>869    <div class="stat-card">870        <div class="stat-icon">๐Ÿš—</div>871        <div class="stat-value">45,672</div>872        <div class="stat-label">Vehicles Detected</div>873    </div>874    <div class="stat-card">875        <div class="stat-icon">๐Ÿšจ</div>876        <div class="stat-value">342</div>877        <div class="stat-label">Emergency Responses</div>878    </div>879    <div class="stat-card">880        <div class="stat-icon">๐Ÿ•’</div>881        <div class="stat-value">~15s</div>882        <div class="stat-label">Processing Time</div>883    </div>884</div>885""", unsafe_allow_html=True)886 887# UPLOAD SECTION888st.markdown("""889<div class="section-container">890    <h2 class="section-title">๐Ÿšฆ 4-Way Intersection Analysis</h2>891    <p style="color: #94a3b8; margin-bottom: 2rem;">Upload traffic images from all four directions for comprehensive AI analysis with emergency vehicle detection</p>892</div>893""", unsafe_allow_html=True)894 895directions = ["North", "East", "South", "West"]896direction_icons = ["โฌ†๏ธ", "โžก๏ธ", "โฌ‡๏ธ", "โฌ…๏ธ"]897uploaded_images = {}898 899cols = st.columns(4)900for col, direction, icon in zip(cols, directions, direction_icons):901    with col:902        st.markdown(f"""903        <div class="upload-card">904            <div style="font-size: 3.5rem; margin-bottom: 1rem;">{icon}</div>905            <div style="font-size: 1.3rem; font-weight: 800; color: #f8fafc; margin-bottom: 0.5rem; text-transform: uppercase; letter-spacing: 2px;">{direction}</div>906            <div style="color: #64748b; font-size: 0.9rem;">Click below to upload image</div>907        </div>908        """, unsafe_allow_html=True)909        uploaded_images[direction] = st.file_uploader(910            f"{direction} Direction",911            type=["jpg", "png", "jpeg"],912            key=direction,913            label_visibility="collapsed"914        )915 916# PROCESSING LOGIC917if all(uploaded_images.values()):918    # Initialize session state variables919    if "images_processed" not in st.session_state:920        st.session_state.images_processed = False921 922    if "all_signals_complete" not in st.session_state:923        st.session_state.all_signals_complete = False924 925    # STEP 1: Process images only once926    if not st.session_state.images_processed:927        with st.spinner("๐Ÿง  Analyzing traffic patterns and detecting emergency vehicles..."):928            progress_bar = st.progress(0)929 930            # Initialize storage931            annotated_images = {}932            counts = {}933            class_counts = {}934            emergency_status = {}935            emergency_confidence = {}936            detection_method = {}937 938            for idx, (direction, img_file) in enumerate(uploaded_images.items()):939                progress_bar.progress((idx + 1) / 4)940 941                try:942                    img = Image.open(img_file).convert("RGB")943 944                    # YOLO vehicle detection945                    results = yolo_model(img)946 947                    # Count vehicles by class948                    class_count = {name: 0 for name in class_names.values()}949                    for cls in results[0].boxes.cls:950                        cls_id = int(cls.item())951                        if cls_id in class_names:952                            class_count[class_names[cls_id]] += 1953 954                    counts[direction] = sum(class_count.values())955                    class_counts[direction] = class_count956 957                    # Create annotated image958                    annotated_array = results[0].plot()959                    annotated_img = Image.fromarray(annotated_array[..., ::-1])960                    annotated_images[direction] = annotated_img961 962                    # EMERGENCY DETECTION - Multiple Methods with Priority963                    is_emergency = False964                    conf = 0.0965                    method = "None"966 967                    # Method 1: Force emergency override (testing) - HIGHEST PRIORITY968                    if force_emergency and direction == emergency_direction:969                        is_emergency = True970                        conf = float(emergency_conf_override)971                        method = "Manual Override"972                        st.sidebar.success(f"โœ… {direction}: Emergency FORCED")973 974                    # Method 2: YOLO + Color Analysis (truck/bus detected)975                    elif not is_emergency:976                        yolo_emergency, yolo_conf, yolo_method = detect_ambulance_yolo_enhanced(977                            results, img)978                        if yolo_emergency and yolo_conf > 40:979                            is_emergency = True980                            conf = yolo_conf981                            method = yolo_method982                            st.sidebar.success(983                                f"โœ… {direction}: Ambulance detected via {yolo_method} ({conf:.1f}%)")984 985                    # Method 3: CNN Model Detection986                    if not is_emergency and ambulance_model is not None:987                        cnn_emergency, cnn_conf = detect_ambulance(988                            img, ambulance_model, detection_threshold)989                        if cnn_emergency:990                            is_emergency = True991                            conf = cnn_conf992                            method = "CNN Model"993                            st.sidebar.success(994                                f"โœ… {direction}: Ambulance detected by CNN ({conf:.1f}%)")995 996                    # Method 4: Full image color analysis997                    if not is_emergency:998                        color_emergency, color_conf = detect_emergency_by_color(999                            img)1000                        if color_emergency and color_conf > 50:1001                            is_emergency = True1002                            conf = color_conf1003                            method = "Color Analysis"1004                            st.sidebar.info(1005                                f"โ„น๏ธ {direction}: Emergency detected by color ({conf:.1f}%)")1006 1007                    # Method 5: Text pattern detection1008                    if not is_emergency:1009                        text_emergency, text_conf = detect_emergency_by_text(1010                            img)1011                        if text_emergency and text_conf > 60:1012                            is_emergency = True1013                            conf = text_conf1014                            method = "Text Pattern"1015                            st.sidebar.info(1016                                f"โ„น๏ธ {direction}: Emergency detected by text pattern ({conf:.1f}%)")1017 1018                    emergency_status[direction] = is_emergency1019                    emergency_confidence[direction] = conf1020                    detection_method[direction] = method1021 1022                except Exception as e:1023                    st.error(f"โŒ Error processing {direction}: {e}")1024                    st.code(traceback.format_exc())1025                    st.stop()1026 1027            # Store in session state1028            st.session_state.annotated_images = annotated_images1029            st.session_state.counts = counts1030            st.session_state.class_counts = class_counts1031            st.session_state.emergency_status = emergency_status1032            st.session_state.emergency_confidence = emergency_confidence1033            st.session_state.detection_method = detection_method1034 1035            # Check for emergency vehicles1036            emergency_directions = [1037                d for d, status in emergency_status.items() if status]1038 1039            if emergency_directions:1040                # Emergency vehicles detected - prioritize them first1041                st.session_state.emergency_directions = emergency_directions1042                # Sort: Emergency directions first (by confidence), then regular by count1043                emergency_sorted = sorted(1044                    [(d, counts[d]) for d in emergency_directions],1045                    key=lambda x: emergency_confidence[x[0]],1046                    reverse=True1047                )1048                regular_sorted = sorted(1049                    [(d, count) for d, count in counts.items()1050                     if d not in emergency_directions],1051                    key=lambda x: x[1],1052                    reverse=True1053                )1054                st.session_state.sorted_directions = emergency_sorted + regular_sorted1055            else:1056                st.session_state.emergency_directions = []1057                # Normal sorting by vehicle count1058                st.session_state.sorted_directions = sorted(1059                    counts.items(),1060                    key=lambda x: x[1],1061                    reverse=True1062                )1063 1064            st.session_state.current_index = 01065            st.session_state.phase = "green"1066            st.session_state.finished = set()1067            st.session_state.images_processed = True1068 1069            progress_bar.empty()1070 1071            # Show detection summary1072            if emergency_directions:1073                st.sidebar.markdown("### ๐Ÿšจ EMERGENCY DETECTED!")1074                for d in emergency_directions:1075                    st.sidebar.error(1076                        f"**{d}**: {st.session_state.detection_method[d]} - {emergency_confidence[d]:.1f}%")1077            else:1078                st.sidebar.info("โ„น๏ธ No emergency vehicles detected")1079 1080            st.rerun()1081 1082    # STEP 2: Signal Control Loop1083    if not st.session_state.all_signals_complete:1084        if len(st.session_state.finished) < 4:1085            current_direction, current_count = st.session_state.sorted_directions[1086                st.session_state.current_index]1087 1088            # Check if current direction has emergency vehicle1089            is_emergency = current_direction in st.session_state.emergency_directions1090            emergency_conf = st.session_state.emergency_confidence.get(1091                current_direction, 0.0)1092            detection_method_used = st.session_state.detection_method.get(1093                current_direction, "None")1094 1095            # Calculate timing1096            if is_emergency:1097                # Emergency vehicle gets immediate green with extended time1098                green_time = 35  # Extended time for emergency vehicles1099                yellow_time = 2  # Shorter yellow for faster transition1100            else:1101                base_time = 51102                time_per_vehicle = 11103                max_time = 251104                green_time = min(base_time + int(current_count/2)1105                                 * time_per_vehicle, max_time)1106                yellow_time = 31107 1108            # Display emergency alert if applicable1109            if is_emergency:1110                st.markdown(f"""1111                <div class="emergency-banner">1112                    <div class="emergency-banner-title">๐Ÿšจ EMERGENCY VEHICLE DETECTED ๐Ÿšจ</div>1113                    <div style="font-size: 1.5rem; color: #fff; font-weight: 700; margin: 1rem 0;">1114                        {current_direction.upper()} Direction โ€ข Confidence: {emergency_conf:.1f}%1115                    </div>1116                    <div style="font-size: 1rem; color: #11ff11; font-weight: 600; margin: 0.5rem 0;">1117                        Detection Method: {detection_method_used}1118                    </div>1119                    <div style="font-size: 1.1rem; color: #11ff11; font-weight: 600;">1120                        โœ… {current_direction.upper()} direction GREEN โ€ข Emergency vehicle has priority clearance for {green_time} seconds1121                    </div>1122                </div>1123                """, unsafe_allow_html=True)1124 1125            # Display signal status1126            st.markdown("""1127            <div class="section-container">1128                <h2 class="section-title">๐Ÿšฅ Live Signal Control</h2>1129                <p style="color: #94a3b8; margin-bottom: 2rem;">Real-time adaptive traffic light management system with emergency vehicle priority</p>1130            </div>1131            """, unsafe_allow_html=True)1132 1133            signal_cols = st.columns(4)1134            for idx, direction in enumerate(directions):1135                with signal_cols[idx]:1136                    count = st.session_state.counts[direction]1137                    is_current = direction == current_direction1138                    has_emergency = direction in st.session_state.emergency_directions1139                    method = st.session_state.detection_method.get(1140                        direction, "None")1141 1142                    if is_current and is_emergency:1143                        # Emergency vehicle active - SHOW GREEN1144                        if st.session_state.phase == "green":1145                            card_class = "signal-card emergency-active"1146                            light_class = "light-emergency"1147                            status = "๐ŸŸข EMERGENCY GREEN"1148                            status_color = "#00c400"1149                        else:1150                            card_class = "signal-card yellow-active"1151                            light_class = "light-yellow"1152                            status = "๐ŸŸก YELLOW"1153                            status_color = "#fbbf24"1154                    elif is_current:1155                        # Regular green/yellow1156                        if st.session_state.phase == "green":1157                            card_class = "signal-card green-active"1158                            light_class = "light-green"1159                            status = "๐ŸŸข GREEN"1160                            status_color = "#10b981"1161                        else:1162                            card_class = "signal-card yellow-active"1163                            light_class = "light-yellow"1164                            status = "๐ŸŸก YELLOW"1165                            status_color = "#fbbf24"1166                    else:1167                        card_class = "signal-card"1168                        light_class = "light-red"1169                        status = "๐Ÿ”ด RED"1170                        status_color = "#ef4444"1171 1172                    # Add emergency badge if detected1173                    emergency_badge = ""1174                    if has_emergency:1175                        emergency_badge = f'''<div style="background: #00c400; color: white; padding: 0.375rem 0.75rem; 1176                                            border-radius: 12px; font-size: 0.7rem; font-weight: 900; 1177                                            margin-top: 0.5rem; letter-spacing: 1px;">1178                                            ๐Ÿšจ AMBULANCE<br><span style="font-size: 0.65rem;">{method}</span>1179                                            </div>'''1180 1181                    st.markdown(f"""1182                    <div class="{card_class}">1183                        <div class="traffic-light {light_class}">{direction_icons[idx]}</div>1184                        <div style="font-size: 1.2rem; font-weight: 800; color: #f8fafc; margin: 0.75rem 0; text-transform: uppercase; letter-spacing: 1.5px;">{direction}</div>1185                        <div style="color: {status_color}; font-weight: 800; font-size: 1rem; margin: 0.75rem 0; text-transform: uppercase; letter-spacing: 1.5px;">{status}</div>1186                        <div style="color: #94a3b8; font-size: 0.9rem; font-weight: 600;">{count} vehicles</div>1187                        {emergency_badge}1188                    </div>1189                    """, unsafe_allow_html=True)1190 1191            # Timer display1192            timer_placeholder = st.empty()1193 1194            # Display detected images WITH HIGHLIGHTING1195            st.markdown("""1196            <div class="section-container">1197                <h2 class="section-title">๐ŸŽฏ Vehicle Detection Results</h2>1198                <p style="color: #94a3b8; margin-bottom: 2rem;">AI-powered object recognition and emergency vehicle classification</p>1199            </div>1200            """, unsafe_allow_html=True)

Showing the first 1,200 of 1583 lines. Download the file for the rest.