opencv-python 时,子进程不能正常启动

一个生产者函数负责从摄像头中读取 frame,一个消费者函数负责使用 opencv 识别里面是否有人。
假如是单进程,可以正常运行,但是假如通过一个 Manager.Queue 通讯,试图使用生产者消费者模式的时候,只要调用 cv2 就报错。

代码如下:

import cv2
import time
import os
import sys
from multiprocessing import Process, Queue, Pool, Manager
from functools import wraps
from collections import defaultdict


basedir = os.path.abspath(os.path.dirname(__file__))
xml = os.path.join(basedir, 'opencv-master/data/haarcascades/haarcascade_frontalface_default.xml')
face_cascade = cv2.CascadeClassifier(xml)
cap = cv2.VideoCapture(0)
start = time.time()
total_fps = 0
manager = Manager()
queue = manager.Queue()


def producer(queue):
    print("producer start")
    fcount = 0
    max_fcount = 20
    sample_rate = 10
    while cap.isOpened() and cv2.waitKey(1) != 27 and fcount < max_fcount:
        ret, frame = cap.read()
        if not ret:
            break
        queue.put(frame)
        cv2.imshow('My Camera',frame)
        fcount += 1
    print("producer stop")
    queue.put('stop')


@timing
def consumer(queue):
    print("consumer start")
    i = -1
    while True:
        info = queue.get()
        i += 1
        print(f'{i}:{type(info)}')
        if isinstance(info, str):
            break
        
        gray = cv2.cvtColor(info, cv2.COLOR_BGR2GRAY)
        faces = face_cascade.detectMultiScale(
            gray,
            scaleFactor=1.15,
            minNeighbors=5,
            minSize=(15, 15),
        )
        
        for x, y, w, h in faces:
            top_left = (x, y)
            bottom = (x + w, y + h)
            cv2.rectangle(info, top_left, bottom, (125, 255, 255), 1)
        global total_fps
        global start
        total_fps += 1
        fps = 'fps:' + str(round(total_fps / (time.time() - start), 0))
        cv2.putText(info, fps, (10, 10), 1, 1, (175, 255, 175), thickness=1)

        cv2.imshow('My Camera',info)

        if not isinstance(faces, tuple):
            # 如果检测到人脸
            print(f'@{time.ctime()}, {len(faces)} detected!')
            file_name = str(int(time.time())) + '.jpg'
            cv2.imwrite(os.path.join(basedir, 'Persons', file_name), info)
        else:
            print('没有检测到人脸')
    print("consumer stop")


if __name__ == '__main__':
    c = Process(target=consumer, args=(queue,))
    # p.daemon = True
    c.daemon = True
    # p.start()
    c.start()
    # p.join()
    producer(queue)
    c.join()

症状就是,假如在constumer 中的下面这行代码之前输入 continue,就各种正常
但是只要用到了cv2,就会报错。
gray = cv2.cvtColor(info, cv2.COLOR_BGR2GRAY)

报错如下图,还看不出什么有效信息:
图片描述

请问是哪里用错了呢?

阅读 2.6k
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题