jake2004's picture
Upload 2 files
4acc1de verified
import streamlit as st
import cv2
from PIL import Image
import numpy as np
from ultralytics import YOLO
import tempfile # For handling video uploads
import os
# --- Page Configuration ---
st.set_page_config(
page_title="Traffic Lane and Object Detection",
page_icon=":camera_video:",
layout="wide",
initial_sidebar_state="expanded",
)
# --- Sidebar ---
st.sidebar.header("Traffic Lane Detection Options")
source_type = st.sidebar.radio(
"Select Input Source:", ("Image", "Video")
) # Choose between image and video
confidence_threshold = st.sidebar.slider(
"Confidence Threshold", min_value=0.0, max_value=1.0, value=0.25, step=0.05
)
# --- Load YOLO Model ---
@st.cache_resource # Cache the model for faster loading
def load_model():
model = YOLO("yolov8n.pt") # Load a pretrained YOLOv8n model
return model
model = load_model()
# --- Functions ---
def detect_lanes_and_objects_image(image, model, confidence_threshold):
"""Runs YOLO on a single image."""
img_np = np.array(image)
results = model(img_np, conf=confidence_threshold)
for result in results:
boxes = result.boxes
for box in boxes:
x1, y1, x2, y2 = map(int, box.xyxy[0].cpu().numpy())
confidence = box.conf[0].cpu().numpy()
class_id = int(box.cls[0].cpu().numpy())
if confidence > confidence_threshold:
label = f"{model.names[class_id]} {confidence:.2f}"
cv2.rectangle(img_np, (x1, y1), (x2, y2), (0, 255, 0), 2)
cv2.putText(
img_np,
label,
(x1, y1 - 10),
cv2.FONT_HERSHEY_SIMPLEX,
0.5,
(0, 255, 0),
2,
)
return img_np
def detect_lanes_and_objects_video(video_path, model, confidence_threshold):
"""Runs YOLO on a video file."""
video = cv2.VideoCapture(video_path)
frame_width = int(video.get(3))
frame_height = int(video.get(4))
fps = int(video.get(cv2.CAP_PROP_FPS))
codec = cv2.VideoWriter_fourcc(*"mp4v") # Use appropriate codec for MP4
output_path = "output.mp4" # Temporary output file
out = cv2.VideoWriter(output_path, codec, fps, (frame_width, frame_height))
stframe = st.empty() # Create an empty placeholder in Streamlit
while video.isOpened():
ret, frame = video.read()
if not ret:
break
results = model(frame, conf=confidence_threshold)
for result in results:
boxes = result.boxes
for box in boxes:
x1, y1, x2, y2 = map(int, box.xyxy[0].cpu().numpy())
confidence = box.conf[0].cpu().numpy()
class_id = int(box.cls[0].cpu().numpy())
if confidence > confidence_threshold:
label = f"{model.names[class_id]} {confidence:.2f}"
cv2.rectangle(frame, (x1, y1), (x2, y2), (0, 255, 0), 2)
cv2.putText(
frame,
label,
(x1, y1 - 10),
cv2.FONT_HERSHEY_SIMPLEX,
0.5,
(0, 255, 0),
2,
)
out.write(frame) # Write the processed frame to the output video
stframe.image(
frame, channels="BGR", use_column_width=True
) # Display the processed frame in Streamlit
video.release()
out.release()
cv2.destroyAllWindows()
return output_path
# --- Main Application ---
st.title("Traffic Lane and Object Detection")
if source_type == "Image":
uploaded_file = st.file_uploader("Upload an image", type=["jpg", "jpeg", "png"])
if uploaded_file is not None:
image = Image.open(uploaded_file)
st.image(image, caption="Uploaded Image", use_column_width=True)
if st.button("Run Detection"):
with st.spinner("Running YOLOv8..."):
detected_image = detect_lanes_and_objects_image(
image, model, confidence_threshold
)
st.image(detected_image, caption="Detected Image", use_column_width=True)
elif source_type == "Video":
uploaded_video = st.file_uploader("Upload a video", type=["mp4", "avi", "mov"])
if uploaded_video is not None:
# Save the uploaded video to a temporary file
tfile = tempfile.NamedTemporaryFile(delete=False)
tfile.write(uploaded_video.read())
video_path = tfile.name
if st.button("Run Detection"):
with st.spinner("Running YOLOv8 on video..."):
output_video_path = detect_lanes_and_objects_video(
video_path, model, confidence_threshold
)
st.video(output_video_path)
# Clean up the temporary file
tfile.close()
os.unlink(video_path)
os.remove(output_video_path) #remove the output video after displaying
st.markdown("---")
st.markdown(
"""
**Note:** This example uses YOLOv8 for object detection. Lane detection is a more complex task and requires additional image processing techniques. This is a simplified demo and will likely not perform well on complex or noisy video.
"""
)