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

Python多进程结合OpenCV运行YOLO时cv2.dnn_Net无法pickle报错如何解决

问题根因

该报错是Windows平台Python多进程默认的spawn启动模式导致的:Windows系统没有fork系统调用,启动子进程时会自动序列化父进程中所有关联对象传递给子进程,而cv2.dnn_Net是OpenCV底层C++实现的对象,不支持Python的pickle序列化机制,就会触发该错误。如果在父进程作用域中提前加载了YOLO模型,哪怕没有主动把模型对象传给子进程,序列化环节也会扫描到该对象并报错。

报错附带的PermissionError和KeyboardInterrupt都是序列化失败导致子进程启动异常的连锁报错,解决序列化问题后会自动消失。

最简解决方案(适配概念验证需求)
  • 不要在父进程中提前加载YOLO模型,将YOLO配置文件路径、权重文件路径作为参数传给子进程,在每个工作进程内部单独加载模型,刚好符合你原本打算每个进程独立加载模型的设计
  • 写进程和工作进程之间用multiprocessing.Queue传递处理后的帧数据即可,队列内置了跨进程同步机制,不需要额外处理复杂的共享内存逻辑

示例代码参考:

import cv2
import multiprocessing

# 工作进程逻辑:所有模型加载操作都放在进程内部完成
def worker_process(video_path, yolo_cfg_path, yolo_weights_path, frame_queue):
    # 子进程内部加载YOLO,不会触发父进程序列化问题
    net = cv2.dnn.readNetFromDarknet(yolo_cfg_path, yolo_weights_path)
    cap = cv2.VideoCapture(video_path)
    while cap.isOpened():
        ret, frame = cap.read()
        if not ret:
            break
        # 此处补充YOLO推理逻辑
        # 处理完的帧推入队列给写进程
        frame_queue.put(frame)
    cap.release()
    frame_queue.put(None) # 发送当前路视频处理结束标记

def writer_process(frame_queue_list, output_path):
    # 此处补充四路帧合并、写入输出视频的逻辑
    pass

if __name__ == "__main__":
    # 父进程只传递路径参数,不要提前加载YOLO
    yolo_cfg = "yolov3.cfg"
    yolo_weights = "yolov3.weights"
    video_paths = ["road1.mp4", "road2.mp4", "road3.mp4", "road4.mp4"]

    frame_queues = [multiprocessing.Queue(maxsize=10) for _ in range(4)]
    # 启动写进程
    writer = multiprocessing.Process(target=writer_process, args=(frame_queues, "output.mp4"))
    writer.start()
    # 启动4个工作进程
    workers = []
    for i in range(4):
        p = multiprocessing.Process(target=worker_process, args=(video_paths[i], yolo_cfg, yolo_weights, frame_queues[i]))
        workers.append(p)
        p.start()
    # 等待所有进程执行结束
    for p in workers:
        p.join()
    writer.join()
可选优化方案
  • 如果嫌4个进程重复加载YOLO占用内存过高,可以直接改用多线程方案:OpenCV的DNN推理逻辑是C++实现,运行时会释放GIL,多线程也能充分利用多核CPU性能,完全没有序列化报错的问题,代码改动量最小。
  • 如果需要多进程+模型共享,可以使用multiprocessing.shared_memory将模型权重放在共享内存区,但实现复杂度较高,概念验证阶段不需要考虑。

内容的提问来源于stack exchange,提问作者Pythoneer96

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.07 12:06:02