使用python和Opencv进行多处理或多线程以检测人脸

时间:2018-08-10 05:59:03

标签: python opencv raspberry-pi3 raspbian

最近,我使用OPENCV + PYTHON在raspberry pi 3(OS raspbian)上进行工作,以检测实时摄像机上的人脸。而且我发现在树莓派pi3上检测到的人脸使用opencv的速度非常慢,大约为4-5 FPS / s。所以我想知道我可以使用MultiThread或MultiProcessing来加快FPS的速度吗,如果可以,我该怎么做?

请帮助我,任何想法将不胜感激。谢谢

2 个答案:

答案 0 :(得分:1)

更新。我使用单独的线程从相机捕获图像,与串行比较,我看不到FPS的任何加速。请参阅我的代码。

import threading
import time
import cv2
import numpy as np
class myThread (threading.Thread):
    def __init__(self, src):
        print("thread -------------init-------------")
        threading.Thread.__init__(self)
        self.cap = cv2.VideoCapture(src)
        self.stop = False
    def run(self):
        while(self.stop == False):
            self.ret, self.frame = self.cap.read()

    def Stop(self):
        self.cap.release()
        self.stop = True

    def read(self):
        return self.ret, self.frame

recognizer = cv2.face.LBPHFaceRecognizer_create()
recognizer.read('trainer/trainer.yml')
cascadePath = "haarcascade_frontalface_default.xml"
faceCascade = cv2.CascadeClassifier(cascadePath);

thread = myThread(0)
thread.start()
time.sleep(1)

start = time.time()
frames = 0
font = cv2.FONT_HERSHEY_SIMPLEX
cap = cv2.VideoCapture(0)
while(True):
    ret, frame = thread.read()
    frame = cv2.resize(frame, (640, 480))
    frames += 1
    gray = cv2.cvtColor(frame,cv2.COLOR_BGR2GRAY)
    faces = faceCascade.detectMultiScale(gray, 1.2, 5)
    for(x,y,w,h) in faces:
        # Create rectangle around the face
        cv2.rectangle(frame, (x-20,y-20), (x+w+20,y+h+20), (0,255,0), 4)
        Id, con = recognizer.predict(gray[y:y+h,x:x+w])
        print(Id, con)

        # Check the ID if exist
        if(con < 60):
            if(Id == 1):
                Id = "HUY"
            if(Id == 2):
                Id = "HOA"
        #If not exist, then it is Unknown
        else:
            #print(Id)
            Id = "Unknow"

        # Put text describe who is in the picture
        cv2.rectangle(frame, (x-22,y-90), (x+w+22, y-22), (0,255,0), -1)
        cv2.putText(frame, str(Id), (x,y-40), font, 2, (255,255,255), 3)  

    if cv2.waitKey(10) & 0xFF == ord('q'):
        thread.Stop()
        break
    cv2.imshow("frame", frame) 
end = time.time()
second = end - start
print("second:", + second)
print(frames/second)
cv2.destroyAllWindows()

答案 1 :(得分:0)

是的,您可以对该进程进行多线程处理。 在python 2中使用threading库,在python 3中使用thread

这是一个简单的例子。

在主线程之外,

只有一个线程操作相机并不断更新最新的帧,在这种情况下,这是全局的。

def camera_thread():       
    cam = cv2.VideoCapture(1)
    _ret, self.image = cam.read()
    cv2.imshow('camera', self.image)

第二个线程可以使用最新框架从模型中进行推断。

可选的三分之一可能会在脸上绘制一个边界框,或执行其他操作等。

在这种情况下,您可能需要在第二个线程和第三个线程之间使用互斥锁,因为只有从模型获得输出后才能开始绘制框。这使您的第二个线程可以开始下一帧的推断,而无需等待其他线程。

上面的示例将导致视频输出平滑,且推理略微滞后。如果您不确定多线程的工作方式,建议您先阅读基础知识。