npd / frontend.py
hostel's picture
commit1
cf18722 verified
Raw
History Blame Contribute Delete
6.08 kB
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
@st.cache_data
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.")