PlateVision / app.py
Himanshu2003's picture
Update app.py
07be9ea verified
import streamlit as st
import cv2
from ultralytics import YOLO
import os
import easyocr
from moviepy import ImageSequenceClip
st.title("πŸš— PlateVision πŸ”")
st.caption("AI-powered license plate detection & recognition from images and videos")
os.makedirs("input", exist_ok=True)
os.makedirs("output", exist_ok=True)
@st.cache_resource
def load_yolo_model():
return YOLO("best_model.pt")
@st.cache_resource
def load_ocr_reader():
return easyocr.Reader(['en'], model_storage_directory='model')
def process_and_find_plate(input_path, output_path):
extension = os.path.splitext(input_path)[1].lower()
if extension in ['.mp4', '.mkv']:
return find_plate_on_video(input_path, output_path)
elif extension in ['.jpg', '.jpeg', '.png']:
return find_plate_on_image(input_path, output_path)
else:
st.error("Unsupported file type")
return None
def find_plate_on_image(input_path, output_path):
model = load_yolo_model()
reader = load_ocr_reader()
image = cv2.imread(input_path)
image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
outputs = model.predict(image, verbose=False)
for output in outputs:
for box in output.boxes:
x1, y1, x2, y2 = map(int, box.xyxy[0])
confidence = box.conf[0]
roi = image[y1:y2, x1:x2]
results = reader.readtext(roi)
plate_num = results[0][1].strip() if results else "Not Visible!"
cv2.rectangle(image, (x1, y1), (x2, y2), (0, 0, 255), 2)
cv2.putText(image, f'{confidence*100:.2f}%', (x1, y1 - 20),
cv2.FONT_HERSHEY_SIMPLEX, 0.6, (0, 255, 0), 2)
cv2.putText(image, f'Number: {plate_num}', (x1, y2 + 20),
cv2.FONT_HERSHEY_SIMPLEX, 0.6, (0, 255, 0), 2)
cv2.imwrite(output_path, cv2.cvtColor(image, cv2.COLOR_RGB2BGR))
return output_path
def find_plate_on_video(input_path, output_path):
model = load_yolo_model()
reader = load_ocr_reader()
cap = cv2.VideoCapture(input_path)
if not cap.isOpened():
st.error("Error opening the video")
return None
fps = int(cap.get(cv2.CAP_PROP_FPS)) or 25
total_frames = int(cap.get(cv2.CAP_PROP_FRAME_COUNT)) or 1
frames = []
frame_idx = 0
skip_frame = 3 # βœ… define properly
progress_bar = st.progress(0, text="πŸ” Analyzing video frames...")
while cap.isOpened():
ret, frame = cap.read()
if not ret:
break
if frame_idx % skip_frame == 0:
rgb_frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
outputs = model.predict(rgb_frame, verbose=False)
for output in outputs:
for box in output.boxes:
x1, y1, x2, y2 = map(int, box.xyxy[0])
confidence = box.conf[0]
roi = frame[y1:y2, x1:x2]
results = reader.readtext(roi)
plate_num = results[0][1].strip() if results else "Not Visible!"
cv2.rectangle(frame, (x1, y1), (x2, y2), (0, 0, 255), 2)
cv2.putText(frame, f'{confidence*100:.2f}%', (x1, y1 - 20),
cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 255, 0), 2)
cv2.putText(frame, f'Number: {plate_num}', (x1, y2 + 20),
cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 255, 0), 2)
frames.append(cv2.cvtColor(frame, cv2.COLOR_BGR2RGB))
frame_idx += 1
progress = min(frame_idx / total_frames, 1.0)
progress_bar.progress(progress, text=f"πŸ“Έ Processed {frame_idx}/{total_frames} frames...")
cap.release()
progress_bar.empty()
# βœ… fix undefined variable (use skip_frame)
output_fps = max(fps // skip_frame, 1)
clip = ImageSequenceClip(frames, fps=output_fps)
clip.write_videofile(output_path, codec='libx264', audio=False, logger=None)
return output_path
uploaded_file = st.file_uploader("πŸ“€ Upload an image or video", type=['jpg', 'jpeg', 'png', 'mp4', 'mkv'])
if uploaded_file is not None:
input_path = f"input/{uploaded_file.name}"
output_path = f"output/{uploaded_file.name}"
with open(input_path, 'wb') as f:
f.write(uploaded_file.getbuffer())
with st.spinner("🚦 Detecting plates... please fasten your seatbelt!"):
path = process_and_find_plate(input_path, output_path)
if path and path.endswith(('.mp4', '.mkv')):
with open(path, 'rb') as video_file:
st.video(video_file.read())
elif path and path.endswith(('.jpg', '.jpeg', '.png')):
st.image(path)
else:
st.error("Error occurred while processing the file.")