Project 3: Real-time object detection with YOLOv8
Frontend
The frontend is built with tkinter. It is responsible to show the user the live video feed and take screenshots which are sent to the backend for processing. It also offers a simple user interface that allows to:
- Start Video Feed: Begins capturing and displaying live video feed from the camera.
- Stop Video Feed: Stops the video feed and replaces the display with a black frame.
- Start Object Detection: Enables YOLOv8-based object detection, which processes frames to identify and annotate detected objects.
- Stop Object Detection: Disables object detection while keeping the live feed running.
import tkinter as tk
from tkinter import Label, Button, Frame
from PIL import Image, ImageTk
import backend
class LiveFeedApp:
#initialize and build the window and buttons
def __init__(self, root):
self.root = root
self.root.title("Live Camera Feed")
self.root.geometry("640x480")
self.video_handler = backend.VideoStreamHandler()
#create a frame for the buttons
button_frame = Frame(root)
button_frame.pack(pady=10)
#buttons
self.start_button = Button(button_frame, text="Start Live Feed", command=self.start_feed, font=("Arial", 12))
self.start_button.pack(side="left", padx=5)
self.stop_button = Button(button_frame, text="Stop Live Feed", command=self.stop_feed, font=("Arial", 12))
self.stop_button.pack(side="left", padx=5)
self.detect_button = Button(button_frame, text="Start Object Detection", command=self.start_detection, font=("Arial", 12))
self.detect_button.pack(side="left", padx=5)
self.stop_detect_button = Button(button_frame, text="Stop Object Detection", command=self.stop_detection, font=("Arial", 12))
self.stop_detect_button.pack(side="left", padx=5)
#label for video frame
self.video_label = Label(root)
self.video_label.pack()
self.running = False
#start the video feed
def start_feed(self):
if not self.running:
self.running = True
self.video_handler.start_stream()
self.update_feed()
#update the video feed
def update_feed(self):
if self.running:
frame = self.video_handler.get_frame()
if frame is not None:
img = Image.fromarray(frame)
else:
img = Image.fromarray(self.video_handler.get_black_frame())
imgtk = ImageTk.PhotoImage(image=img)
self.video_label.imgtk = imgtk
self.video_label.configure(image=imgtk)
self.root.after(10, self.update_feed)
#start object detection (backend call)
def start_detection(self):
self.video_handler.enable_detection()
#end object detection (backend call)
def stop_detection(self):
self.video_handler.disable_detection()
#stop the video feed
def stop_feed(self):
if self.running:
self.running = False
self.video_handler.disable_detection()
self.video_handler.stop_stream()
# Set a black frame
black_frame = self.video_handler.get_black_frame()
black_img = Image.fromarray(black_frame)
black_imgtk = ImageTk.PhotoImage(image=black_img)
self.video_label.imgtk = black_imgtk
self.video_label.configure(image=black_imgtk)
#properly close the tool
def close(self):
self.running = False
self.video_handler.stop_stream()
self.root.destroy()
#main
if __name__ == "__main__":
root = tk.Tk()
app = LiveFeedApp(root)
root.protocol("WM_DELETE_WINDOW", app.close)
root.mainloop()