File size: 4,418 Bytes
056ff88 aa45af5 056ff88 860c4dc |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 |
import streamlit as st
from ultralytics import YOLO
import cv2
import easyocr
import numpy as np
import pandas as pd
from PIL import Image
import tempfile
@st.cache_resource
def load_model():
model = YOLO('yolo11n-custom.pt')
model.fuse()
return model
model = load_model()
reader = easyocr.Reader(['en'])
def detect_license_plate(image):
results = model.predict(image, conf=0.15, iou=0.3, classes=[0])
plate_texts = []
img_array = np.array(image)
# img = cv2.imread(image_path)
img = cv2.cvtColor(img_array, cv2.COLOR_RGB2BGR)
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
img_height, img_width, _ = img.shape
for result in results:
for bbox in result.boxes.xyxy:
x1, y1, x2, y2 = map(int, bbox.tolist())
plate = img[int(y1):int(y2), int(x1):int(x2)]
scale=2
height, width = plate.shape[:2]
plate = cv2.resize(plate, (width * scale, height * scale), interpolation=cv2.INTER_CUBIC)
lab = cv2.cvtColor(plate, cv2.COLOR_RGB2LAB)
l, a, b = cv2.split(lab)
clahe = cv2.createCLAHE(clipLimit=3.0, tileGridSize=(8, 8))
l = clahe.apply(l)
plate = cv2.merge((l, a, b))
plate = cv2.cvtColor(plate, cv2.COLOR_LAB2RGB)
text = reader.readtext(plate, detail=0, allowlist="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-")
text = " ".join(text).upper()
text_scale = max(1, width / 250)
thickness = max(2, width // 200)
cv2.rectangle(img, (x1, y1), (x2, y2), (0, 255, 0), thickness)
(text_width, text_height), _ = cv2.getTextSize(text, cv2.FONT_HERSHEY_SIMPLEX, text_scale, thickness)
text_x = x1 + (width - text_width) // 2 # Centered horizontally
text_y = y1 - 10 if y1 > 50 else y2 + text_height + 20 # Above unless too high
text_box_y1 = text_y - text_height - 5
text_box_y2 = text_y + 5
cv2.rectangle(img, (text_x - 8, text_box_y1 - 3), (text_x + text_width + 8, text_box_y2 + 3), (0, 0, 0), -1)
cv2.rectangle(img, (text_x - 5, text_box_y1), (text_x + text_width + 5, text_box_y2), (255, 255, 255), -1)
cv2.putText(img, text, (text_x, text_y), cv2.FONT_HERSHEY_SIMPLEX, text_scale, (0, 0, 0), thickness)
plate_texts.append(text)
image = img
return image, plate_texts
st.title("π Real-Time License Plate Detection", anchor=False)
st.write("For better license plate detection, ensure you use high-quality images. If detection is unclear, try enhancing the image first. Use the Refine Image for Detection tool.")
st.write("Upload an image, upload a video, or use your webcam for real-time license plate detection.")
option = st.radio("Choose Input Source:", ("Upload Image", "Upload Video", "Webcam"), horizontal=True )
if option == "Upload Image":
uploaded_file = st.file_uploader("Upload an image", type=["jpg", "png", "jpeg"])
if uploaded_file:
img = Image.open(uploaded_file)
st.write("Processing...")
processed_img, plate_texts = detect_license_plate(img)
st.image(processed_img, caption="Detected Plates Image", use_container_width=True)
st.write("**Detected License Plates:**")
if plate_texts:
plates = pd.DataFrame({"License Plate": plate_texts})
plates.index = plates.index + 1
st.table(plates)
else:
st.write("No license plates detected.")
elif option == "Upload Video":
uploaded_video = st.file_uploader("Choose a video...", type=["mp4", "avi", "mov"])
if uploaded_video is not None:
st.write("Processing video...")
tfile = tempfile.NamedTemporaryFile(delete=False)
tfile.write(uploaded_video.read())
cap = cv2.VideoCapture(tfile.name)
frame_placeholder = st.empty()
while cap.isOpened():
ret, frame = cap.read()
if not ret:
break
processed_frame, plate_texts = detect_license_plate(frame)
frame_placeholder.image(processed_frame, caption="Detected Plates Video", use_container_width=True)
cap.release()
elif option == "Webcam":
if "running" not in st.session_state:
st.session_state.running = True
if st.button("Stop"):
st.session_state.running = False
st.write("Starting Webcam... Press **Stop** to end.")
cap = cv2.VideoCapture(0)
frame_placeholder = st.empty()
while cap.isOpened():
ret, frame = cap.read()
if not ret:
st.warning("Failed to capture webcam feed.")
break
processed_frame, plate_texts = detect_license_plate(frame)
frame_placeholder.image(processed_frame, channels="BGR", caption="Webcam Feed", use_container_width=True)
if not st.session_state.running:
break
cap.release() |