Yolov8 замедляет поток с камерыPython

Программы на Python
Anonymous
Yolov8 замедляет поток с камеры

Сообщение Anonymous »

Во-первых, извините, если я плохо говорю по-английски, я француз, надеюсь, вы меня понимаете.
Я хочу сделать сетевой видеорегистратор своими руками для камеры Reolink и хочу добавить распознавание объектов.
Но когда я использую yolov8, частота кадров падает до 20 кадров в секунду (даже с включенным CUDA).
Так что для 20-секундного видео это не так уж и плохо но для камеры это будет делать все большую задержку.
Как сделать, чтобы программа могла пропускать определенные кадры, ведь меня не волнует, не следует ли он за объектом кадр за кадром...
Вот код:
  • main.py

Код: Выделить всё

import cv2
import threading
from threading import Thread
import time
import random
from ultralytics import YOLO
import math
import numpy as np
from collections import deque
from torchvision.models.mobilenetv2 import Conv2dNormActivation
from object_recognition import thread_safe_object_recognition

font = cv2.FONT_HERSHEY_SIMPLEX
fontScale = 1
color = (255, 0, 0)
thickness = 2

classNames = ["person", "bicycle", "car", "motorbike", "aeroplane", "bus", "train", "truck", "boat",
"traffic light", "fire hydrant", "stop sign", "parking meter", "bench", "bird", "cat",
"dog", "horse", "sheep", "cow", "elephant", "bear", "zebra", "giraffe", "backpack", "umbrella",
"handbag", "tie", "suitcase", "frisbee", "skis", "snowboard", "sports ball", "kite", "baseball bat",
"baseball glove", "skateboard", "surfboard", "tennis racket", "bottle", "wine glass", "cup",
"fork", "knife", "spoon", "bowl", "banana", "apple", "sandwich", "orange", "broccoli",
"carrot", "hot dog", "pizza", "donut", "cake", "chair", "sofa", "pottedplant", "bed",
"diningtable", "toilet", "tvmonitor", "laptop", "mouse", "remote", "keyboard", "cell phone",
"microwave", "oven", "toaster", "sink", "refrigerator", "book", "clock", "vase", "scissors",
"teddy bear", "hair drier", "toothbrush"
]

class ThreadWithReturnValue(Thread):
def __init__(self, group=None, target=None, name=None,
args=(), kwargs={}, Verbose=None):
Thread.__init__(self, group, target, name, args, kwargs)
self._return = None

def run(self):
if self._target is not None:
self._return = self._target(*self._args,
**self._kwargs)
def join(self, *args):
Thread.join(self, *args)
return self._return

def capture_loop(previewName, camID, gpuID: int): # Function where the RTSP stream is get.

cv2.namedWindow(previewName + " | Capture")
cv2.namedWindow(previewName + " | Object Recognition")

capture = cv2.VideoCapture(camID)

first_ret, first_frame= capture.read()

prev_frame_time = 0
new_frame_time = 0

fps_queue = deque(maxlen = 60)

while True:
grabbed, frame = capture.read()
if not grabbed:
break

cpu_temp = random.randrange(30,95)
new_frame_time = time.time()

fps = int(1/(new_frame_time-prev_frame_time))
fps_queue.append(fps)
avg_fps = int(np.mean(fps_queue))
prev_frame_time = new_frame_time

object_recognition_transparent_frame = object_recognition(frame, gpuID)
object_recognition_frame = cv2.addWeighted(frame, 1, object_recognition_transparent_frame, 0.5, 0)

cv2.putText(frame, str(fps) + " FPS (" + str(avg_fps) + ")", (7, 30), font, 1, (100, 255, 0), 3, cv2.LINE_AA)
cv2.putText(object_recognition_frame, str(fps) + " FPS ("  + str(avg_fps) + ")", (7, 30), font, 1, (100, 255, 0), 3, cv2.LINE_AA)

cv2.putText(frame, str(cpu_temp) + "C", (7, 70), font, 1, (100, 255, 0), 3, cv2.LINE_AA)
cv2.putText(object_recognition_frame, str(cpu_temp) + "C", (7, 70), font, 1, (100, 255, 0), 3, cv2.LINE_AA)

cv2.imshow(previewName + " | Capture", frame)
cv2.imshow(previewName + " | Object Recognition", object_recognition_frame)
key = cv2.waitKey(20)
if key == 27:  # exit on ESC
break

cv2.destroyWindow(previewName + " | Capture")
cv2.destroyWindow(previewName + " | Object Recognition")
capture.release()

def object_recognition(frame, gpuID: int):
yolov8_thread = ThreadWithReturnValue(target=thread_safe_object_recognition, args=(frame, gpuID))
yolov8_thread.start()
results = yolov8_thread.join()

height, width = frame.shape[:2]
b, g, r = 0xFF, 0xFF, 0xFF
transparent_frame = np.zeros((height, width, 3), np.uint8)
transparent_frame[:, :, 0] = b
transparent_frame[:, :, 1] = g
transparent_frame[:, :, 2] = r

for r in results:
boxes = r.boxes

for box in boxes:
# bounding box
x1, y1, x2, y2 = box.xyxy[0]
x1, y1, x2, y2 = int(x1), int(y1), int(x2), int(y2) # convert to int values

# put box in cam
cv2.rectangle(transparent_frame, (x1, y1), (x2, y2), (255, 0, 255), 3)

# confidence
confidence = math.ceil((box.conf[0]*100))/100

# class name
cls = int(box.cls[0])

# object details
org = [x1, y1]

cv2.putText(transparent_frame, classNames[cls] + " " + str(confidence), org, font, fontScale, color, thickness)

return transparent_frame

def main():
thread = threading.Thread(target=capture_loop, args=["Camera 1", "#RTSP URL#", 0])
thread.start()

if __name__ == "__main__":
main()
  • object_recognition.py

Код: Выделить всё

from ultralytics import YOLO
model = YOLO("yolov8n.pt")
model.to('cuda')

def thread_safe_object_recognition(frame, gpuID: int):
results = model(frame, verbose=False, batch=6, stream=True, device='cuda:'+str(gpuID))
return results
Я пытаюсь использовать функцию потока (с ThreadWithReturnValue), но это не сработало.

Подробнее здесь: https://stackoverflow.com/questions/786 ... eam-slower

Вернуться в «Python»