You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.14 15:24:35