I’m using OpenCV in Python to record footage from my webcam and process it with the YOLOv8 model to recognize vehicles. The video feed is separated into four quadrants, which are analyzed separately to count automobiles. Based on the number of vehicles, I design traffic signals using the turtle graphics library.
However, I am having severe lag in video capture and display, resulting in choppy and slow footage. Here’s the relevant portion of my code:
The Code which I’m working is provided below:
import cv2
import argparse
import numpy as np
from ultralytics import YOLO
import supervision as sv
import turtle
def parse_arguments() -> argparse.Namespace:
parser = argparse.ArgumentParser(description="YOLOv8 live")
parser.add_argument("--webcam-resolution", default=[1280, 720], nargs=2, type=int)
return parser.parse_args()
def draw_signal(x, y, color):
turtle.penup()
turtle.goto(x, y)
turtle.pendown()
turtle.begin_fill()
turtle.color(color)
turtle.circle(30)
turtle.end_fill()
def main():
args = parse_arguments()
frame_width, frame_height = args.webcam_resolution
cap = cv2.VideoCapture(0)
cap.set(cv2.CAP_PROP_FRAME_WIDTH, frame_width)
cap.set(cv2.CAP_PROP_FRAME_HEIGHT, frame_height)
model = YOLO("yolov8l.pt")
box_annotator = sv.BoxAnnotator(thickness=2, text_thickness=2, text_scale=1)
turtle.speed(0)
turtle.hideturtle()
turtle.title("Traffic Signal")
while True:
ret, frame = cap.read()
height, width, _ = frame.shape
half_height, half_width = height // 2, width // 2
quadrants = [frame[:half_height, :half_width], frame[:half_height, half_width:], frame[half_height:, :half_width], frame[half_height:, half_width:]]
max_vehicle_count = 0
max_vehicle_quadrant = -1
for i, quadrant in enumerate(quadrants):
result = model(quadrant, agnostic_nms=True)[0]
detections = sv.Detections.from_yolov8(result)
detections = detections[(detections.class_id == 2) | (detections.class_id == 3)]
vehicle_count = len(detections)
if vehicle_count > max_vehicle_count:
max_vehicle_count = vehicle_count
max_vehicle_quadrant = i
labels = [f"Vehicle {j+1}: {model.model.names[class_id]} {confidence:0.2f}" for j, (bbox, confidence, class_id, _) in enumerate(detections)]
quadrant = box_annotator.annotate(scene=quadrant, detections=detections, labels=labels)
cv2.rectangle(quadrant, (0, 0), (quadrant.shape[1], quadrant.shape[0]), (255, 255, 255), 2)
cv2.putText(quadrant, f"Vehicles: {len(detections)}", (10, 30), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 0), 2)
if i == 0:
frame[:half_height, :half_width] = quadrant
elif i == 1:
frame[:half_height, half_width:] = quadrant
elif i == 2:
frame[half_height:, :half_width] = quadrant
elif i == 3:
frame[half_height:, half_width:] = quadrant
turtle.clear()
signal_colors = ["red"] * 4
if max_vehicle_quadrant != -1:
signal_colors[max_vehicle_quadrant] = "green"
for i, color in enumerate(signal_colors):
draw_signal(-frame_width//2 + 100 + i * 150, frame_height//2 - 100, color)
cv2.imshow("yolov8", frame)
if cv2.waitKey(30) == 27:
break
cap.release()
cv2.destroyAllWindows()
if __name__ == "__main__":
main()
What I tried:
-
Frame Resolution Adjustment: I tried various resolutions to see if they affected performance, but the lag persisted.
-
Reducing Processing Load: I simplified the model processing to simply evaluate two classes, yet the latency persists.
-
Threading: We attempted to use threading to handle video capture and processing separately, but it did not greatly reduce lag.
Expected results:
I want a smoother video stream with less lag, similar to the raw webcam feed. The objective is to have real-time processing and presentation with no apparent delays.
R Aalsan Jaas is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.