Spaces:
Paused
Paused
| import streamlit as st | |
| import pandas as pd | |
| import cv2 | |
| import easyocr | |
| import tempfile | |
| import requests | |
| import os | |
| from datetime import datetime | |
| # ✅ Google Drive API Key and Folder ID | |
| API_KEY = "AIzaSyDojJrpauA0XZtCCDUuo9xeQHZQamYKsC4" | |
| FOLDER_ID = "1egelZ7ZyHBNcXmtObX0CWfr_Q_ilfX9p" | |
| LOG_FILE = "vehicle_log.csv" | |
| FRAME_SKIP = 15 # Reduced to improve detection | |
| reader = easyocr.Reader(['en'], gpu=False) | |
| st.title("🚓 Improved Vehicle Detection from Google Drive CCTV") | |
| # Ensure log file exists | |
| if not os.path.exists(LOG_FILE): | |
| pd.DataFrame(columns=["Vehicle Number", "Timestamp", "Video File"]).to_csv(LOG_FILE, index=False) | |
| def list_drive_files(folder_id): | |
| url = f"https://www.googleapis.com/drive/v3/files?q='{folder_id}'+in+parents+and+(mimeType='video/mp4'+or+mimeType='video/avi')&key={API_KEY}&fields=files(id,name)" | |
| resp = requests.get(url) | |
| if resp.status_code != 200: | |
| st.error(f"Drive API Error: {resp.text}") | |
| return [] | |
| return resp.json().get("files", []) | |
| def download_drive_video(file_id): | |
| download_url = f"https://www.googleapis.com/drive/v3/files/{file_id}?alt=media&key={API_KEY}" | |
| resp = requests.get(download_url, stream=True) | |
| if resp.status_code != 200: | |
| return None | |
| temp = tempfile.NamedTemporaryFile(delete=False, suffix=".mp4") | |
| for chunk in resp.iter_content(chunk_size=8192): | |
| if chunk: | |
| temp.write(chunk) | |
| temp.close() | |
| return temp.name | |
| def process_video(video_path, video_name, log_df): | |
| cap = cv2.VideoCapture(video_path) | |
| frame_num = 0 | |
| new_logs = [] | |
| detected_this_video = set() | |
| while cap.isOpened(): | |
| ret, frame = cap.read() | |
| if not ret: | |
| break | |
| if frame_num % FRAME_SKIP == 0: | |
| resized = cv2.resize(frame, (640, 360)) | |
| gray = cv2.cvtColor(resized, cv2.COLOR_BGR2GRAY) | |
| results = reader.readtext(gray) | |
| for (_, text, _) in results: | |
| text = text.replace(" ", "").upper() | |
| if len(text) >= 6 and any(char.isdigit() for char in text): | |
| if text not in detected_this_video: | |
| timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S") | |
| new_logs.append([text, timestamp, video_name]) | |
| detected_this_video.add(text) | |
| st.success(f"Detected: {text} at {timestamp}") | |
| frame_num += 1 | |
| cap.release() | |
| return new_logs | |
| # Step 1: Download and process videos | |
| files = list_drive_files(FOLDER_ID) | |
| if files: | |
| try: | |
| log_df = pd.read_csv(LOG_FILE) | |
| except pd.errors.EmptyDataError: | |
| log_df = pd.DataFrame(columns=["Vehicle Number", "Timestamp", "Video File"]) | |
| all_new_logs = [] | |
| for file in files: | |
| st.info(f"Processing: {file['name']}") | |
| local_path = download_drive_video(file['id']) | |
| if local_path: | |
| new_logs = process_video(local_path, file['name'], log_df) | |
| all_new_logs.extend(new_logs) | |
| os.remove(local_path) | |
| if all_new_logs: | |
| pd.DataFrame(all_new_logs, columns=["Vehicle Number", "Timestamp", "Video File"]).to_csv( | |
| LOG_FILE, mode='a', index=False, header=not os.path.exists(LOG_FILE)) | |
| st.success("✅ Logs updated.") | |
| else: | |
| st.warning("No video files found or API error.") | |
| # Step 2: Analyze logs | |
| if os.path.exists(LOG_FILE): | |
| try: | |
| df = pd.read_csv(LOG_FILE) | |
| df["Timestamp"] = pd.to_datetime(df["Timestamp"]) | |
| entries = df.sort_values("Timestamp").groupby("Vehicle Number").first() | |
| exits = df.sort_values("Timestamp").groupby("Vehicle Number").last() | |
| summary = pd.DataFrame() | |
| summary["Vehicle Number"] = entries.index | |
| summary["Entry Time"] = entries["Timestamp"] | |
| summary["Exit Time"] = exits["Timestamp"] | |
| summary["Duration (minutes)"] = (summary["Exit Time"] - summary["Entry Time"]).dt.total_seconds() / 60 | |
| summary["Overstay Alert"] = summary["Duration (minutes)"] > (24 * 60) | |
| summary["Checked Out"] = summary["Entry Time"] != summary["Exit Time"] | |
| st.subheader("📊 Vehicle Summary (Duration in Minutes)") | |
| st.dataframe(summary) | |
| except Exception as e: | |
| st.error(f"Failed to analyze logs: {e}") |