Оптимизация OpenCV для одноплатника

Рейтинг: 1Ответов: 1Опубликовано: 17.03.2023

Как можно повысить количество кадров в секунду для обнаружения объектов на плате OrangePi 3? Используется скрипт для обнаружения объектов на основе алгоритма YOLO v8 (вообще, основной целью является обнаружение людей/пешеходов), но проблема заключается в огромной задержке. Со скриптом ниже fps на плате составляет около 0.5 - 1, но с этим ещё можно мириться, если бы не огромная задержка - то, что выводит и обрабатывает плата на 5 - 10 секунд отстаёт от реальной обстановки, а это критично. Есть ли какие-нибудь способы хотя бы убрать задержку?

Код прилагаю:

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

my_file = open("utils/coco.txt", "r") # Файл с названиями объектов
data = my_file.read()
class_list = data.split("\n")
my_file.close()

detection_colors = []
for i in range(len(class_list)):
    r = random.randint(0, 255)
    g = random.randint(0, 255)
    b = random.randint(0, 255)
    detection_colors.append((b, g, r))

model = YOLO("weights/yolov8n.pt", "v8")

frame_wid = 640
frame_hyt = 480

# cap = cv2.VideoCapture(1)
cap = cv2.VideoCapture(0)

if not cap.isOpened():
    print("Cannot open camera")
    exit()

while True:
    ret, frame = cap.read()
    if not ret:
        print("Can't receive frame (stream end?). Exiting ...")
        break

    frame = cv2.resize(frame, (frame_wid, frame_hyt), cv2.INTER_NEAREST)

    detect_params = model.predict(source=[frame], conf=0.45, save=False)
    DP = detect_params[0].numpy()

    if len(detect_params[0]) != 0:
        for i in range(len(detect_params[0])):
            # print(i)

            boxes = detect_params[0].boxes
            box = boxes[i]
            clsID = box.cls.numpy()[0]
            conf = box.conf.numpy()[0]
            bb = box.xyxy.numpy()[0]

            cv2.rectangle(
                frame,
                (int(bb[0]), int(bb[1])),
                (int(bb[2]), int(bb[3])),
                detection_colors[int(clsID)],
                3,
            )

            font = cv2.FONT_HERSHEY_COMPLEX
            cv2.putText(
                frame,
                class_list[int(clsID)]
                + " "
                + str(round(conf, 3))
                + "%",
                (int(bb[0]), int(bb[1]) - 10),
                font,
                1,
                (255, 255, 255),
                2,
            )

    cv2.imshow('ObjectDetection', frame)

    if cv2.waitKey(1) == ord('q'):
        break

cap.release()
cv2.destroyAllWindows()

Ответы

▲ 2Принят
  1. у вас идет нарастающее отставание, цикл while не успевает (сравните 25 кадров/сек и 1 кадр/сек)
  2. вы можете только уменьшить размер окна изображения. но будет потеря в качестве детекции
  3. можно поставить радиатор и разогнать микроконтроллер
  4. попробуйте поискать возможность обработки grayscale в настройках, все ищут решение этого вопроса, но никто не тренирует сети на градациях серого (это один канал вместо 3-х)

по первому пункту попробуйте так, будет брать кадры пореже

from imutils.video import VideoStream

# Initialize multithreading the video stream.
videostream = "rtsp://192.168.x.y/user=admin=xxxxxxx_channel=vvvv=1.sdp?params"
vs = VideoStream(src=videostream, resolution=frameSize,
                 framerate=32).start()

frame = vs.read()

update: по п.4. это непросто! общая картина следующая, вместо 3 слоев RGB подается на вход только градации серого. это втрое уменьшает вычисления на сетке. НО, сеть надо заново обучать, вроде всё есть, но такой сетки нет, хотя в настройках сети есть параметр ch=

    Add ch argument in your MODEL.yaml, if it's not exist:

# Parameters
......
nc: 80  
ch: 1 # input channels
depth_multiple: 0.33  
width_multiple: 0.50  

и... это не работает, либо надо проверить, может сделали.

еще там вариант превращают картинку в серое и с помощью numpy делают трёхслойку с нулевыми значениями остальных двух слоев. я не пробовал.

прим., можете сами поискать по словам: yolo grayscale ultralitics, напр.. тут https://github.com/ultralytics/yolov5/issues/6288