在Python多处理进程中运行较慢的OpenCV代码段

在Python多处理进程中运行较慢的OpenCV代码段,python,opencv,concurrency,parallel-processing,multiprocessing,Python,Opencv,Concurrency,Parallel Processing,Multiprocessing,我在做一些多处理测试,以并行化人脸检测和识别,我遇到了一个奇怪的行为,其中detectMultiScale()(执行人脸检测)在子进程中运行得比在父进程中慢(只调用函数) 因此,我编写了下面的代码,其中10幅图像排队,然后使用两种方法之一依次执行人脸检测:只调用检测函数或在单个新进程中运行检测函数。对于每个detectMultiScale()调用,都会打印执行时间。执行这段代码,第一种方法中每次调用的平均时间为0.22秒,第二种方法为0.54秒。另外,第二种方法处理这10幅图像的总时间也更长 我

我在做一些多处理测试,以并行化人脸检测和识别,我遇到了一个奇怪的行为,其中detectMultiScale()(执行人脸检测)在子进程中运行得比在父进程中慢(只调用函数)

因此,我编写了下面的代码,其中10幅图像排队,然后使用两种方法之一依次执行人脸检测:只调用检测函数或在单个新进程中运行检测函数。对于每个detectMultiScale()调用,都会打印执行时间。执行这段代码,第一种方法中每次调用的平均时间为0.22秒,第二种方法为0.54秒。另外,第二种方法处理这10幅图像的总时间也更长

我不知道为什么相同的代码片段在新进程中运行得较慢。如果总时间更长,我会理解(考虑到设置新流程的开销),但我不明白。记录在案,我用树莓皮3B+运行它

import cv2
import multiprocessing
from time import time, sleep

def detect(face_cascade, img_queue, bnd_queue):
    while True:
        image = img_queue.get()
        if image is not None:
            gray_image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
            ti = time()
            ########################################
            faces = face_cascade.detectMultiScale(
                                gray_image,
                                scaleFactor=1.1,
                                minNeighbors=3,
                                minSize=(130, 130))
            ########################################
            tf = time()
            print('det time: ' + str(tf-ti))
                            
            if len(faces) > 0:
                max_bounds = (0,0,0,0)
                max_size = 0
                for (x,y,w,h) in faces:
                     if w*h > max_size:
                         max_size = w*h
                         max_bounds = (x,y,w,h)
            img_queue.task_done()
            bnd_queue.put('bound')
        else:
            img_queue.task_done()
            break


face_cascade = cv2.CascadeClassifier('../lbpcascade_frontalface_improved.xml')
cam = cv2.VideoCapture(0)
cam.set(cv2.CAP_PROP_FRAME_WIDTH, 2592)
cam.set(cv2.CAP_PROP_FRAME_HEIGHT, 1944)
cam.set(cv2.CAP_PROP_BUFFERSIZE, 1)

img_queue = multiprocessing.JoinableQueue()

i = 0
while i < 10:
    is_there_frame, image = cam.read()
    if is_there_frame:
        image = image[0:1944, 864:1728]
        image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
        img_queue.put(image)
        i += 1

bnd_queue = multiprocessing.JoinableQueue()
num_process = 1

ti = time()
# MULTIPROCESSING PROCESS APPROACH
for _ in range(num_process):
    p = multiprocessing.Process(target=detect, args=(face_cascade, img_queue, bnd_queue))
    p.start()

for _ in range(num_process):
    img_queue.put(None)
#     
# FUNCTION CALL APPROACH
#img_queue.put(None)
#while not img_queue.empty():
#    detect(face_cascade, img_queue, bnd_queue)

img_queue.join()
tf = time()

print('TOTAL TIME: ' + str(tf-ti))

while not bnd_queue.empty():
    bound = bnd_queue.get()
    if bound != 'bound':
        print('ERROR')
    bnd_queue.task_done()
导入cv2
导入多处理
从时间导入时间,睡眠
def检测(面部级联、img队列、bnd队列):
尽管如此:
image=img_queue.get()
如果图像不是无:
灰色\u图像=cv2.CVT颜色(图像,cv2.COLOR\u BGR2GRAY)
ti=时间()
########################################
面=面\级联。检测多尺度(
灰度图像,
scaleFactor=1.1,
minNeighbors=3,
minSize=(130130))
########################################
tf=时间()
打印('det time:'+str(tf ti))
如果透镜(面)>0:
最大界=(0,0,0,0)
最大尺寸=0
对于面中的(x,y,w,h):
如果w*h>最大尺寸:
最大尺寸=w*h
最大界=(x,y,w,h)
img_queue.task_done()
bnd_queue.put('bound')
其他:
img_queue.task_done()
打破
face_cascade=cv2.CascadeClassifier(“../lbpcascade_frontalface_improved.xml”)
cam=cv2.视频捕获(0)
凸轮组(cv2.CAP\U PROP\U FRAME\U WIDTH,2592)
凸轮组件(cv2.CAP\U PROP\U FRAME\U HEIGHT,1944)
凸轮组件(cv2.CAP\U PROP\U BUFFERSIZE,1)
img_queue=多处理。JoinableQueue()
i=0
当我<10时:
是否有框架,image=cam.read()
如果存在\u帧:
image=image[0:1944864:1728]
image=cv2.cvt颜色(image,cv2.COLOR\u BGR2RGB)
img_queue.put(图像)
i+=1
bnd_queue=多处理。JoinableQueue()
num_进程=1
ti=时间()
#多处理方法
对于范围内的(num_进程):
p=多处理。进程(目标=检测,参数=(面_级联,img_队列,bnd_队列))
p、 开始()
对于范围内的(num_进程):
img_queue.put(无)
#     
#函数调用方法
#img_queue.put(无)
#而不是img_queue.empty():
#检测(面部级联、img队列、bnd队列)
img_queue.join()
tf=时间()
打印('总时间:'+str(tf-ti))
而不是bnd_queue.empty():
bound=bnd_queue.get()
如果绑定!='绑定':
打印('错误')
bnd_queue.task_done()