YOLO目标检测多进程实现的视频卡顿延迟问题求助
YOLO目标检测多进程实现的视频卡顿延迟问题求助
我现在想用Ultralytics的YOLO模型实现一个支持摄像头/视频源的多进程版本目标检测。我做了一个队列来存放帧,还弄了个有4个工作进程的池:1个负责显示画面,另外3个处理帧。
但现在遇到个问题:程序启动后检测是能正常工作,但视频播放不流畅,感觉延迟很高——和原视频源比,每帧之间的间隔太长,整体比原视频慢很多。我本来期望播放效果能和输入源一样流畅的。
有没有大佬能给点建议?我已经试过调整工作进程数量和队列的maxsize,但情况并没有改善。
from multiprocessing import Pool, Queue, Process, Lock import cv2 from ultralytics import YOLO stop_flag = False def init_pool(d_b, selected_classes): global detection_buffer, yolo, selected_classes_set detection_buffer = d_b yolo = YOLO('yolov8n.pt') selected_classes_set = set(selected_classes) def detect_object(frame, frame_id): global yolo, selected_classes_set results = yolo.track(frame, stream=False) for result in results: classes_names = result.names for box in result.boxes: if box.conf[0] > 0.4: x1, y1, x2, y2 = map(int, box.xyxy[0]) cls = int(box.cls[0]) class_name = classes_names[cls] if class_name in selected_classes_set: colour = (0, 255, 0) cv2.rectangle(frame, (x1, y1), (x2, y2), colour, 2) cv2.putText(frame, f'{class_name} {box.conf[0]:.2f}', (x1, y1), cv2.FONT_HERSHEY_SIMPLEX, 1, colour, 2) detection_buffer.put((frame_id, frame)) def show(detection_buffer): global stop_flag next_frame_id = 0 frames_buffer = {} while not stop_flag: data = detection_buffer.get() if data is None: break frame_id, frame = data frames_buffer[frame_id] = frame while next_frame_id in frames_buffer: cv2.imshow("Video", frames_buffer.pop(next_frame_id)) next_frame_id += 1 if cv2.waitKey(1) & 0xFF == ord('q'): stop_flag = True break cv2.destroyAllWindows() return # Required for Windows: if __name__ == "__main__": video_path = "path_to_video" detection_buffer = Queue(maxsize=3) selected_classes = ['car'] detect_pool = Pool(3, initializer=init_pool, initargs=(detection_buffer, selected_classes)) num_show_processes = 1 show_processes = Process(target=show, args=(detection_buffer,)) show_processes.start() if not video_path: cap = cv2.VideoCapture(0) else: cap = cv2.VideoCapture(video_path) frame_id = 0 futures = [] while not stop_flag: ret, frame = cap.read() if ret: f = detect_pool.apply_async(detect_object, args=(frame, frame_id)) futures.append(f) frame_id += 1 else: break for f in futures: f.get() for _ in range(num_show_processes): detection_buffer.put(None) for p in show_processes: p.join() detect_pool.close() detect_pool.join() cv2.destroyAllWindows()
备注:内容来源于stack exchange,提问作者Simone Carlesi
相关产品推荐
相关产品推荐

