Spaces:
No application file
No application file
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 --- | |
# 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. | |
""" | |
) | |