Spaces:
Configuration error
Configuration error
| import streamlit as st | |
| import pandas as pd | |
| import cv2 | |
| import os | |
| from datetime import datetime | |
| import plotly.express as px | |
| from PIL import Image | |
| # Set page config | |
| st.set_page_config( | |
| page_title="License Plate Detection Dashboard", | |
| page_icon="🚗", | |
| layout="wide" | |
| ) | |
| # Title | |
| st.title("License Plate Detection Dashboard") | |
| # Sidebar | |
| st.sidebar.header("Dashboard Controls") | |
| # Read the CSV file | |
| def load_data(): | |
| try: | |
| # Try to read from the original file first | |
| try: | |
| df = pd.read_csv("car_plate_data_stored.csv") | |
| except: | |
| # If that fails, try the new format file | |
| df = pd.read_csv("car_plate_data_new.csv") | |
| # Ensure we have the correct column names | |
| if 'NumberPlate' in df.columns: | |
| df = df.rename(columns={'NumberPlate': 'ID'}) | |
| elif 'ImageFile' in df.columns: | |
| df = df.rename(columns={'ImageFile': 'ID'}) | |
| # Ensure we have the right columns | |
| if 'NumberPlate' in df.columns: | |
| df = df.rename(columns={'NumberPlate': 'ID'}) | |
| # Add Confidence column if it doesn't exist | |
| if 'Confidence' not in df.columns: | |
| df['Confidence'] = 'N/A' | |
| # Clean up confidence values | |
| df['Confidence'] = df['Confidence'].fillna('N/A') | |
| # Parse dates properly | |
| df['DateTime'] = pd.to_datetime(df['Date'] + ' ' + df['Time'], | |
| format='%d-%m-%Y %H:%M:%S', | |
| dayfirst=True) | |
| # Convert confidence values to numeric where possible | |
| df['Confidence'] = pd.to_numeric(df['Confidence'].replace('N/A', float('nan')), errors='coerce') | |
| # Convert date and time to datetime | |
| df['DateTime'] = pd.to_datetime(df['Date'] + ' ' + df['Time']) | |
| # Fill missing confidence values with None | |
| if 'Confidence' in df.columns: | |
| df['Confidence'] = df['Confidence'].fillna('N/A') | |
| else: | |
| df['Confidence'] = 'N/A' | |
| return df | |
| except FileNotFoundError: | |
| return pd.DataFrame(columns=['ID', 'Date', 'Time', 'Confidence', 'DateTime']) | |
| df = load_data() | |
| # Main content | |
| col1, col2 = st.columns([2, 1]) | |
| with col1: | |
| st.header("Detection Statistics") | |
| # Statistics cards | |
| stat_col1, stat_col2, stat_col3 = st.columns(3) | |
| with stat_col1: | |
| st.metric("Total Detections", len(df)) | |
| with stat_col2: | |
| if not df.empty: | |
| numeric_conf = pd.to_numeric(df['Confidence'].replace('N/A', float('nan')), errors='coerce') | |
| avg_confidence = numeric_conf.mean() | |
| if pd.notnull(avg_confidence): | |
| st.metric("Average Confidence", f"{avg_confidence:.2f}%") | |
| else: | |
| st.metric("Average Confidence", "N/A") | |
| with stat_col3: | |
| if not df.empty: | |
| today = datetime.now().date() | |
| today_detections = df[pd.to_datetime(df['Date']).dt.date == today].shape[0] | |
| st.metric("Today's Detections", today_detections) | |
| # Timeline chart | |
| if not df.empty: | |
| st.subheader("Detection Timeline") | |
| timeline_fig = px.line( | |
| df.groupby('DateTime').size().reset_index(name='count'), | |
| x='DateTime', | |
| y='count', | |
| title="Detections Over Time" | |
| ) | |
| st.plotly_chart(timeline_fig, use_container_width=True) | |
| with col2: | |
| st.header("Recent Detections") | |
| if not df.empty: | |
| recent = df.tail(5) | |
| for _, row in recent.iterrows(): | |
| # Check if the ID is a filename (new format) or a plate number (old format) | |
| if row['ID'].endswith('.jpg'): | |
| img_path = os.path.join("detected_plates", row['ID']) | |
| conf_text = f" ({row['Confidence']}% confidence)" if row['Confidence'] != 'N/A' else "" | |
| else: | |
| # For old format, there might not be an image | |
| img_path = None | |
| conf_text = "" | |
| if img_path and os.path.exists(img_path): | |
| st.image(img_path, caption=f"Detected at {row['Time']}{conf_text}") | |
| else: | |
| st.write(f"License Plate: {row['ID']} detected at {row['Time']}{conf_text}") | |
| # Data table | |
| st.header("Detection Records") | |
| if not df.empty: | |
| # Add filters | |
| date_filter = st.date_input("Filter by date", pd.to_datetime(df['Date']).min()) | |
| confidence_filter = st.slider("Minimum confidence", 0.0, 100.0, 0.0) | |
| # Apply filters | |
| filtered_df = df[df['DateTime'].dt.date == date_filter] | |
| # Handle confidence filter | |
| if confidence_filter > 0: | |
| # Convert confidence to numeric, treating non-numeric values as -1 | |
| numeric_conf = pd.to_numeric(df['Confidence'], errors='coerce').fillna(-1) | |
| filtered_df = filtered_df[numeric_conf >= confidence_filter] | |
| st.dataframe( | |
| filtered_df[['ID', 'Date', 'Time', 'Confidence']], | |
| use_container_width=True | |
| ) | |
| else: | |
| st.info("No detections recorded yet. Start the detection system to collect data.") | |
| # Image gallery | |
| st.header("Image Gallery") | |
| if not df.empty: | |
| # Filter for rows that have image files | |
| image_df = df[df['ID'].str.endswith('.jpg', na=False)] | |
| if not image_df.empty: | |
| # Create a grid of images | |
| gallery = st.columns(4) | |
| for idx, row in image_df.iterrows(): | |
| img_path = os.path.join("detected_plates", row['ID']) | |
| if os.path.exists(img_path): | |
| with gallery[idx % 4]: | |
| conf_text = f" ({row['Confidence']}% conf.)" if row['Confidence'] != 'N/A' else "" | |
| st.image(img_path, caption=f"{row['Time']}{conf_text}", use_column_width=True) | |
| else: | |
| st.info("No images available in the gallery. Only text detections are present.") |