pythonqtpyqtpyautoguiyolov8

YOLOv8, display bounding boxes on the screen


How to display bounding boxes directly on the screen? Its not a video, so I can't use tracking. My program captures the whole screen and checks for Objects. I researched that CV can help me with that but I can't get it to work

from ultralytics import YOLO
import pyautogui
import cv2
import numpy as np

# Load the model
model_path = 'C:/Users/toto/Desktop/DETECT/best.pt'
model = YOLO(model_path)

# Set the confidence threshold
conf_threshold = 0.4

# Capture the entire screen
screen_image = pyautogui.screenshot()
screen_image = cv2.cvtColor(np.array(screen_image), cv2.COLOR_RGB2BGR)

# Perform object detection on the captured screen image
results = model(screen_image)

my code output

0: 384x640 3 Objects, 70.1ms
Speed: 4.5ms preprocess, 70.1ms inference, 1.0ms postprocess per image at shape (1, 3, 384, 640)

Solution

  • ok I did it using PyQt5, if you have a different solution please let me know. but this is how I did it.

    import sys
    from PyQt5.QtWidgets import QApplication, QWidget
    from PyQt5.QtGui import QPainter, QPen
    from PyQt5.QtCore import Qt
    import pyautogui
    import cv2
    import numpy as np
    from ultralytics import YOLO  # Adjust import based on your YOLO version/installation
    
    class Overlay(QWidget):
        def __init__(self, detection_results):
            super().__init__()
            self.detection_results = detection_results
            self.initUI()
    
        def initUI(self):
            self.setGeometry(0, 0, pyautogui.size().width, pyautogui.size().height)
            self.setWindowTitle('Transparent Overlay with Bounding Box')
            self.setWindowFlags(Qt.FramelessWindowHint | Qt.WindowStaysOnTopHint)
            self.setAttribute(Qt.WA_TranslucentBackground)
    
        def paintEvent(self, event):
            painter = QPainter(self)
            pen = QPen(Qt.green, 2, Qt.SolidLine)  # Set the color and width of the pen
            painter.setPen(pen)
    
            # Iterate through all detection results
            for det in self.detection_results:
                x1, y1, x2, y2 = det['bbox']  # Extract bounding box coordinates
                painter.drawRect(x1, y1, x2 - x1, y2 - y1)  # Draw the rectangle
    
    
    
    def run_yolo_and_overlay():
        model_path = 'C:/Users/toto/Desktop/DETECT/best.pt'
        model = YOLO(model_path)
        
        app = QApplication(sys.argv)
        ex = Overlay([])
        ex.show()
    
        while True:
            screen_image = pyautogui.screenshot()
            screen_image = cv2.cvtColor(np.array(screen_image), cv2.COLOR_RGB2BGR)
            results = model(screen_image)
    
            detection_results = []
            if results:
                # Assuming the 'boxes' attribute contains the bounding boxes information
                for result in results:  # If results is a list, adjust accordingly
                    # Directly access the xyxy property for bounding box coordinates
                    boxes = result.boxes.xyxy  # This should be adjusted based on your results structure
                    for box in boxes:
                        x1, y1, x2, y2 = box[:4]  # Extract bounding box coordinates
                        detection_results.append({'bbox': [int(x1), int(y1), int(x2), int(y2)]})
    
            ex.detection_results = detection_results
            ex.repaint()
            QApplication.processEvents()
    
    
    if __name__ == '__main__':
        run_yolo_and_overlay()
    

    I hope someone will find it useful, it scans full screen (2k for me) for the object and draws bounding boxes around it,