import streamlit as st import pandas as pd from datetime import datetime import plotly.express as px import plotly.graph_objects as go # Set page config st.set_page_config( page_title="License Plate Detection Results", page_icon="🚗", layout="wide" ) # Custom CSS st.markdown(""" """, unsafe_allow_html=True) # Title and description st.title("📊 License Plate Detection Dashboard") st.markdown(""" This dashboard shows the results of license plate detections from video surveillance. """) # Load and process data @st.cache_data def load_data(): try: df = pd.read_csv("car_plate_data_stored.csv") # Handle different 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 all required columns if 'Confidence' not in df.columns: df['Confidence'] = 'N/A' # Convert dates df['DateTime'] = pd.to_datetime(df['Date'] + ' ' + df['Time'], format='%d-%m-%Y %H:%M:%S', dayfirst=True) return df except Exception as e: st.error(f"Error loading data: {str(e)}") return pd.DataFrame(columns=['ID', 'Date', 'Time', 'Confidence', 'DateTime']) # Load data df = load_data() # Dashboard layout col1, col2 = st.columns([2, 1]) with col1: # Statistics cards in a grid st.markdown('
', unsafe_allow_html=True) 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) st.markdown('
', unsafe_allow_html=True) # Timeline chart if not df.empty: st.subheader("Detection Timeline") detections_by_time = df.groupby(df['DateTime'].dt.floor('H')).size().reset_index(name='count') fig = go.Figure() fig.add_trace(go.Scatter( x=detections_by_time['DateTime'], y=detections_by_time['count'], mode='lines+markers', line=dict(color='#1f77b4', width=2), marker=dict(size=6), name='Detections' )) fig.update_layout( title="Detections Over Time", xaxis_title="Time", yaxis_title="Number of Detections", height=400, hovermode='x unified', plot_bgcolor='white', paper_bgcolor='white', xaxis=dict( showgrid=True, gridcolor='#f0f0f0', ), yaxis=dict( showgrid=True, gridcolor='#f0f0f0', ) ) st.plotly_chart(fig, use_container_width=True) with col2: st.subheader("Recent Detections") if not df.empty: recent = df.tail(5) for _, row in recent.iterrows(): with st.container(): st.markdown(f"""

ID: {row['ID']}

Time: {row['Time']}

Confidence: {row['Confidence'] if row['Confidence'] != 'N/A' else 'N/A'}

""", unsafe_allow_html=True) # Data table with filters st.subheader("Detection Records") if not df.empty: col1, col2 = st.columns([1, 2]) with col1: date_filter = st.date_input( "Filter by date", pd.to_datetime(df['Date']).min() ) with col2: confidence_filter = st.slider( "Minimum confidence", 0.0, 100.0, 0.0, help="Filter detections by minimum confidence score" ) # Apply filters filtered_df = df[df['DateTime'].dt.date == date_filter] if confidence_filter > 0: numeric_conf = pd.to_numeric(filtered_df['Confidence'].replace('N/A', -1), errors='coerce') filtered_df = filtered_df[numeric_conf >= confidence_filter] # Display the filtered dataframe st.dataframe( filtered_df[['ID', 'Date', 'Time', 'Confidence']].style.format({ 'Confidence': lambda x: f"{x:.2f}%" if isinstance(x, (int, float)) else x }), use_container_width=True ) # Add summary statistics if not df.empty: st.subheader("Detection Statistics") col1, col2 = st.columns(2) with col1: # Detections by hour hourly_stats = df.groupby(df['DateTime'].dt.hour).size() fig = px.bar( x=hourly_stats.index, y=hourly_stats.values, labels={'x': 'Hour of Day', 'y': 'Number of Detections'}, title='Detections by Hour of Day' ) fig.update_layout(bargap=0.2) st.plotly_chart(fig, use_container_width=True) with col2: # Confidence distribution confidence_values = pd.to_numeric(df['Confidence'].replace('N/A', float('nan')), errors='coerce') confidence_values = confidence_values.dropna() if not confidence_values.empty: fig = px.histogram( confidence_values, nbins=20, labels={'value': 'Confidence Score', 'count': 'Number of Detections'}, title='Distribution of Confidence Scores' ) fig.update_layout(bargap=0.2) st.plotly_chart(fig, use_container_width=True)